1. /*
  2. * @(#)SyntheticImage.java 1.14 01/11/29
  3. *
  4. * Copyright 2002 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.14 11/29/01
  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. }
  80. class SyntheticImageGenerator extends Thread {
  81. ImageConsumer ic;
  82. boolean useful;
  83. SyntheticImageGenerator next;
  84. SyntheticImage parent;
  85. SyntheticImageGenerator(ImageConsumer ic, SyntheticImageGenerator next,
  86. SyntheticImage parent) {
  87. this.ic = ic;
  88. this.next = next;
  89. this.parent = parent;
  90. useful = true;
  91. setDaemon(true);
  92. // System.out.println (Thread.getCurrent() + " is making a generator");
  93. }
  94. public void run() {
  95. ImageConsumer ic = this.ic;
  96. int w = parent.width;
  97. int h = parent.height;
  98. int hints = ic.SINGLEPASS|ic.COMPLETESCANLINES|ic.TOPDOWNLEFTRIGHT;
  99. if (parent.isStatic())
  100. hints |= ic.SINGLEFRAME;
  101. ic.setHints(hints);
  102. ic.setDimensions(w, h);
  103. ic.setProperties(null);
  104. ic.setColorModel(parent.cm);
  105. if (useful) {
  106. int[] row=new int[w];
  107. doPrivileged( new Runnable() {
  108. public void run() {
  109. Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  110. }
  111. });
  112. do {
  113. // System.out.println("doing");
  114. for (int y = 0; y<h && useful; y++) {
  115. parent.computeRow(y,row);
  116. ic.setPixels(0, y, w, 1, parent.cm, row, 0, w);
  117. }
  118. ic.imageComplete(parent.isStatic() ? ic.STATICIMAGEDONE
  119. : ic.SINGLEFRAMEDONE );
  120. } while(!parent.isStatic() && useful);
  121. }
  122. }
  123. private final static void doPrivileged(final Runnable doRun) {
  124. java.security.AccessController.doPrivileged(
  125. new java.security.PrivilegedAction() {
  126. public Object run() {
  127. doRun.run();
  128. return null;
  129. }
  130. }
  131. );
  132. }
  133. }