1. /*
  2. * @(#)SyntheticImage.java 1.16 00/07/26
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.colorchooser;
  11. import java.awt.*;
  12. import java.awt.image.*;
  13. /** A helper class to make computing synthetic images a little easier.
  14. * All you need to do is define a subclass that overrides computeRow
  15. * to compute a row of the image. It is passed the y coordinate of the
  16. * row and an array into which to put the pixels in
  17. * <a href="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.image.ColorModel.html#getRGBdefault()">
  18. * standard ARGB format</a>.
  19. * <p>Normal usage looks something like this:
  20. * <pre> Image i = createImage(new SyntheticImage(200, 100) {
  21. *   protected void computeRow(int y, int[] row) {
  22. *   for(int i = width; --i>=0; ) {
  23. *   int grey = i*255/(width-1);
  24. *   row[i] = (255<<24)|(grey<<16)|(grey<<8)|grey;
  25. *   }
  26. *   }
  27. *  }
  28. * </pre>This creates a image 200 pixels wide and 100 pixels high
  29. * that is a horizontal grey ramp, going from black on the left to
  30. * white on the right.
  31. * <p>
  32. * If the image is to be a movie, override isStatic to return false,
  33. * <i>y</i> cycling back to 0 is computeRow's signal that the next
  34. * frame has started. It is acceptable (expected?) for computeRow(0,r)
  35. * to pause until the appropriate time to start the next frame.
  36. *
  37. * @version 1.16 07/26/00
  38. * @author James Gosling
  39. */
  40. abstract class SyntheticImage implements ImageProducer {
  41. private SyntheticImageGenerator root;
  42. protected int width=10, height=100;
  43. static final ColorModel cm = ColorModel.getRGBdefault();
  44. public static final int pixMask = 0xFF;
  45. private Thread runner;
  46. protected SyntheticImage() { }
  47. protected SyntheticImage(int w, int h) { width = w; height = h; }
  48. protected void computeRow(int y, int[] row) {
  49. int p = 255-255*y(height-1);
  50. p = (pixMask<<24)|(p<<16)|(p<<8)|p;
  51. for (int i = row.length; --i>=0; ) row[i] = p;
  52. }
  53. public synchronized void addConsumer(ImageConsumer ic){
  54. for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next)
  55. if (ics.ic == ic) return;
  56. root = new SyntheticImageGenerator(ic, root, this);
  57. }
  58. public synchronized boolean isConsumer(ImageConsumer ic){
  59. for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next)
  60. if (ics.ic == ic) return true;
  61. return false;
  62. }
  63. public synchronized void removeConsumer(ImageConsumer ic) {
  64. SyntheticImageGenerator prev = null;
  65. for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next)
  66. if (ics.ic == ic) {
  67. ics.useful = false;
  68. if (prev!=null) prev.next = ics.next;
  69. else root = ics.next;
  70. return;
  71. }
  72. }
  73. public synchronized void startProduction(ImageConsumer ic) {
  74. addConsumer(ic);
  75. for (SyntheticImageGenerator ics = root; ics != null; ics = ics.next)
  76. if (ics.useful && !ics.isAlive())
  77. ics.start();
  78. }
  79. protected boolean isStatic() { return true; }
  80. public void nextFrame(int param) {}//Override if !isStatic
  81. public void requestTopDownLeftRightResend(ImageConsumer ic){}
  82. }
  83. class SyntheticImageGenerator extends Thread {
  84. ImageConsumer ic;
  85. boolean useful;
  86. SyntheticImageGenerator next;
  87. SyntheticImage parent;
  88. SyntheticImageGenerator(ImageConsumer ic, SyntheticImageGenerator next,
  89. SyntheticImage parent) {
  90. this.ic = ic;
  91. this.next = next;
  92. this.parent = parent;
  93. useful = true;
  94. setDaemon(true);
  95. // System.out.println (Thread.getCurrent() + " is making a generator");
  96. }
  97. public void run() {
  98. ImageConsumer ic = this.ic;
  99. int w = parent.width;
  100. int h = parent.height;
  101. int hints = ic.SINGLEPASS|ic.COMPLETESCANLINES|ic.TOPDOWNLEFTRIGHT;
  102. if (parent.isStatic())
  103. hints |= ic.SINGLEFRAME;
  104. ic.setHints(hints);
  105. ic.setDimensions(w, h);
  106. ic.setProperties(null);
  107. ic.setColorModel(parent.cm);
  108. if (useful) {
  109. int[] row=new int[w];
  110. doPrivileged( new Runnable() {
  111. public void run() {
  112. Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  113. }
  114. });
  115. do {
  116. // System.out.println("doing");
  117. for (int y = 0; y<h && useful; y++) {
  118. parent.computeRow(y,row);
  119. ic.setPixels(0, y, w, 1, parent.cm, row, 0, w);
  120. }
  121. ic.imageComplete(parent.isStatic() ? ic.STATICIMAGEDONE
  122. : ic.SINGLEFRAMEDONE );
  123. } while(!parent.isStatic() && useful);
  124. }
  125. }
  126. private final static void doPrivileged(final Runnable doRun) {
  127. java.security.AccessController.doPrivileged(
  128. new java.security.PrivilegedAction() {
  129. public Object run() {
  130. doRun.run();
  131. return null;
  132. }
  133. }
  134. );
  135. }
  136. }