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