Replacing RepaintManager with RepaintController which does not reference Applet in its signatures
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 20 Jun 2009 22:10:34 +0200
changeset 1247b4727fd16c4b
parent 1246 293b390ba471
child 1248 63da26e35f11
Replacing RepaintManager with RepaintController which does not reference Applet in its signatures
build.xml
src/share/classes/com/sun/java/swing/SwingUtilities3.java
src/share/classes/javax/swing/BufferStrategyPaintManager.java
src/share/classes/javax/swing/DebugGraphics.java
src/share/classes/javax/swing/DefaultDesktopManager.java
src/share/classes/javax/swing/JApplet.java
src/share/classes/javax/swing/JComponent.java
src/share/classes/javax/swing/JDialog.java
src/share/classes/javax/swing/JFrame.java
src/share/classes/javax/swing/JRootPane.java
src/share/classes/javax/swing/JViewport.java
src/share/classes/javax/swing/JWindow.java
src/share/classes/javax/swing/RepaintController.java
src/share/classes/javax/swing/RepaintManager.java
src/share/classes/javax/swing/SwingPaintEventDispatcher.java
src/share/classes/javax/swing/UIManager.java
     1.1 --- a/build.xml	Fri Jun 19 21:46:14 2009 +0200
     1.2 +++ b/build.xml	Sat Jun 20 22:10:34 2009 +0200
     1.3 @@ -4,7 +4,9 @@
     1.4  
     1.5      <target name="all">
     1.6          <antcall target="base"/>
     1.7 +        <antcall target="applet"/>
     1.8          <antcall target="corba"/>
     1.9 +        <antcall target="deprecated7"/>
    1.10      </target>
    1.11  
    1.12      <!-- basic parameters -->
    1.13 @@ -125,7 +127,14 @@
    1.14  
    1.15      <selector id="deprecated7">
    1.16          <or>
    1.17 +            <!-- deprecated as it contains one method
    1.18 +            that references Applet
    1.19 +            -->
    1.20              <filename name="java/beans/Beans*"/>
    1.21 +            <!-- deprecated as it contains one method
    1.22 +            that references Applet
    1.23 +            -->
    1.24 +            <filename name="javax/swing/RepaintManager*"/>
    1.25  
    1.26              <!-- tools -->
    1.27              <filename name="sun/tools/serialver/**"/>
    1.28 @@ -184,7 +193,7 @@
    1.29      <target name="corba">
    1.30          <antcall target="-compile-one-module">
    1.31              <param name="module" value="corba"/>
    1.32 -            <param name="depends" value="base"/>
    1.33 +            <param name="depends" value="base:applet"/>
    1.34          </antcall>
    1.35      </target>
    1.36  
     2.1 --- a/src/share/classes/com/sun/java/swing/SwingUtilities3.java	Fri Jun 19 21:46:14 2009 +0200
     2.2 +++ b/src/share/classes/com/sun/java/swing/SwingUtilities3.java	Sat Jun 20 22:10:34 2009 +0200
     2.3 @@ -33,7 +33,7 @@
     2.4  import java.awt.EventQueue;
     2.5  import java.awt.Component;
     2.6  import javax.swing.JComponent;
     2.7 -import javax.swing.RepaintManager;
     2.8 +import javax.swing.RepaintController;
     2.9  
    2.10  /**
    2.11   * A collection of utility methods for Swing.
    2.12 @@ -49,32 +49,32 @@
    2.13   */
    2.14  public class SwingUtilities3 {
    2.15      /**
    2.16 -     * The {@code clientProperty} key for delegate {@code RepaintManager}
    2.17 +     * The {@code clientProperty} key for delegate {@code RepaintController}
    2.18       */
    2.19      private static final Object DELEGATE_REPAINT_MANAGER_KEY =
    2.20 -        new StringBuilder("DelegateRepaintManagerKey");
    2.21 +        new StringBuilder("DelegateRepaintControllerKey");
    2.22  
    2.23      /**
    2.24 -      * Registers delegate RepaintManager for {@code JComponent}.
    2.25 +      * Registers delegate RepaintController for {@code JComponent}.
    2.26        */
    2.27 -    public static void setDelegateRepaintManager(JComponent component,
    2.28 -                                                RepaintManager repaintManager) {
    2.29 +    public static void setDelegateRepaintController(JComponent component,
    2.30 +                                                RepaintController RepaintController) {
    2.31          /* setting up flag in AppContext to speed up lookups in case
    2.32 -         * there are no delegate RepaintManagers used.
    2.33 +         * there are no delegate RepaintControllers used.
    2.34           */
    2.35          AppContext.getAppContext().put(DELEGATE_REPAINT_MANAGER_KEY,
    2.36                                         Boolean.TRUE);
    2.37  
    2.38          component.putClientProperty(DELEGATE_REPAINT_MANAGER_KEY,
    2.39 -                                    repaintManager);
    2.40 +                                    RepaintController);
    2.41      }
    2.42  
    2.43      /**
    2.44 -     * Returns delegate {@code RepaintManager} for {@code component} hierarchy.
    2.45 +     * Returns delegate {@code RepaintController} for {@code component} hierarchy.
    2.46       */
    2.47 -    public static RepaintManager getDelegateRepaintManager(Component
    2.48 +    public static RepaintController getDelegateRepaintController(Component
    2.49                                                              component) {
    2.50 -        RepaintManager delegate = null;
    2.51 +        RepaintController delegate = null;
    2.52          if (Boolean.TRUE == AppContext.getAppContext().get(
    2.53                                                 DELEGATE_REPAINT_MANAGER_KEY)) {
    2.54              while (delegate == null && component != null) {
    2.55 @@ -83,7 +83,7 @@
    2.56                      component = component.getParent();
    2.57                  }
    2.58                  if (component != null) {
    2.59 -                    delegate = (RepaintManager)
    2.60 +                    delegate = (RepaintController)
    2.61                          ((JComponent) component)
    2.62                            .getClientProperty(DELEGATE_REPAINT_MANAGER_KEY);
    2.63                      component = component.getParent();
     3.1 --- a/src/share/classes/javax/swing/BufferStrategyPaintManager.java	Fri Jun 19 21:46:14 2009 +0200
     3.2 +++ b/src/share/classes/javax/swing/BufferStrategyPaintManager.java	Sat Jun 20 22:10:34 2009 +0200
     3.3 @@ -43,7 +43,7 @@
     3.4   *
     3.5   * @author Scott Violet
     3.6   */
     3.7 -class BufferStrategyPaintManager extends RepaintManager.PaintManager {
     3.8 +class BufferStrategyPaintManager extends RepaintController.PaintManager {
     3.9      //
    3.10      // All drawing is done to a BufferStrategy.  At the end of painting
    3.11      // (endPaint) the region that was painted is flushed to the screen
    3.12 @@ -633,7 +633,7 @@
    3.13          if (bufferInfos != null) {
    3.14              dispose(bufferInfos);
    3.15              bufferInfos = null;
    3.16 -            repaintManager.setPaintManager(null);
    3.17 +            RepaintController.setPaintManager(null);
    3.18          }
    3.19      }
    3.20  
     4.1 --- a/src/share/classes/javax/swing/DebugGraphics.java	Fri Jun 19 21:46:14 2009 +0200
     4.2 +++ b/src/share/classes/javax/swing/DebugGraphics.java	Sat Jun 20 22:10:34 2009 +0200
     4.3 @@ -37,12 +37,12 @@
     4.4   * method.
     4.5   * <p>
     4.6   * NOTE: You must turn off double buffering to use DebugGraphics:
     4.7 - *       RepaintManager repaintManager = RepaintManager.currentManager(component);
     4.8 - *       repaintManager.setDoubleBufferingEnabled(false);
     4.9 + *       RepaintController RepaintController = RepaintController.currentManager(component);
    4.10 + *       RepaintController.setDoubleBufferingEnabled(false);
    4.11   *
    4.12   * @see JComponent#setDebugGraphicsOptions
    4.13 - * @see RepaintManager#currentManager
    4.14 - * @see RepaintManager#setDoubleBufferingEnabled
    4.15 + * @see RepaintController#currentManager
    4.16 + * @see RepaintController#setDoubleBufferingEnabled
    4.17   *
    4.18   * @author Dave Karlton
    4.19   */
     5.1 --- a/src/share/classes/javax/swing/DefaultDesktopManager.java	Fri Jun 19 21:46:14 2009 +0200
     5.2 +++ b/src/share/classes/javax/swing/DefaultDesktopManager.java	Sat Jun 20 22:10:34 2009 +0200
     5.3 @@ -640,7 +640,7 @@
     5.4        JComponent parent = (JComponent)f.getParent();
     5.5        Rectangle visBounds = previousBounds.intersection(desktopBounds);
     5.6  
     5.7 -      RepaintManager currentManager = RepaintManager.currentManager(f);
     5.8 +      RepaintController currentManager = RepaintController.currentManager(f);
     5.9  
    5.10        currentManager.beginPaint();
    5.11        try {
     6.1 --- a/src/share/classes/javax/swing/JApplet.java	Fri Jun 19 21:46:14 2009 +0200
     6.2 +++ b/src/share/classes/javax/swing/JApplet.java	Sat Jun 20 22:10:34 2009 +0200
     6.3 @@ -492,7 +492,7 @@
     6.4  
     6.5      /**
     6.6       * Repaints the specified rectangle of this component within
     6.7 -     * <code>time</code> milliseconds.  Refer to <code>RepaintManager</code>
     6.8 +     * <code>time</code> milliseconds.  Refer to <code>RepaintController</code>
     6.9       * for details on how the repaint is handled.
    6.10       *
    6.11       * @param     time   maximum time in milliseconds before update
    6.12 @@ -500,12 +500,12 @@
    6.13       * @param     y    the <i>y</i> coordinate
    6.14       * @param     width    the width
    6.15       * @param     height   the height
    6.16 -     * @see       RepaintManager
    6.17 +     * @see       RepaintController
    6.18       * @since     1.6
    6.19       */
    6.20      public void repaint(long time, int x, int y, int width, int height) {
    6.21 -        if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
    6.22 -            RepaintManager.currentManager(this).addDirtyRegion(
    6.23 +        if (RepaintController.HANDLE_TOP_LEVEL_PAINT) {
    6.24 +            RepaintController.currentManager(this).addDirtyRegion0(
    6.25                                this, x, y, width, height);
    6.26          }
    6.27          else {
     7.1 --- a/src/share/classes/javax/swing/JComponent.java	Fri Jun 19 21:46:14 2009 +0200
     7.2 +++ b/src/share/classes/javax/swing/JComponent.java	Sat Jun 20 22:10:34 2009 +0200
     7.3 @@ -987,7 +987,7 @@
     7.4          Graphics componentGraphics = getComponentGraphics(g);
     7.5          Graphics co = componentGraphics.create();
     7.6          try {
     7.7 -            RepaintManager repaintManager = RepaintManager.currentManager(this);
     7.8 +            RepaintController repaintManager = RepaintController.currentManager(this);
     7.9              Rectangle clipRect = co.getClipBounds();
    7.10              int clipX;
    7.11              int clipY;
    7.12 @@ -1067,10 +1067,10 @@
    7.13  
    7.14      // paint forcing use of the double buffer.  This is used for historical
    7.15      // reasons: JViewport, when scrolling, previously directly invoked paint
    7.16 -    // while turning off double buffering at the RepaintManager level, this
    7.17 +    // while turning off double buffering at the RepaintController level, this
    7.18      // codes simulates that.
    7.19      void paintForceDoubleBuffered(Graphics g) {
    7.20 -        RepaintManager rm = RepaintManager.currentManager(this);
    7.21 +        RepaintController rm = RepaintController.currentManager(this);
    7.22          Rectangle clip = g.getClipBounds();
    7.23          rm.beginPaint();
    7.24          setFlag(IS_REPAINTING, true);
    7.25 @@ -3334,7 +3334,7 @@
    7.26      }
    7.27  
    7.28      /**
    7.29 -     * This is invoked by the <code>RepaintManager</code> if
    7.30 +     * This is invoked by the <code>RepaintController</code> if
    7.31       * <code>createImage</code> is called on the component.
    7.32       *
    7.33       * @param newValue true if the double buffer image was created from this component
    7.34 @@ -3344,7 +3344,7 @@
    7.35      }
    7.36  
    7.37      /**
    7.38 -     * Returns true if the <code>RepaintManager</code>
    7.39 +     * Returns true if the <code>RepaintController</code>
    7.40       * created the double buffer image from the component.
    7.41       *
    7.42       * @return true if this component had a double buffer image, false otherwise
    7.43 @@ -4752,7 +4752,7 @@
    7.44          deregisterNextFocusableComponent();
    7.45  
    7.46          if (getCreatedDoubleBuffer()) {
    7.47 -            RepaintManager.currentManager(this).resetDoubleBuffer();
    7.48 +            RepaintController.currentManager(this).resetDoubleBuffer();
    7.49              setCreatedDoubleBuffer(false);
    7.50          }
    7.51          if (autoscrolls) {
    7.52 @@ -4772,10 +4772,10 @@
    7.53       * @param width  the width of the dirty region
    7.54       * @param height  the height of the dirty region
    7.55       * @see java.awt.Component#isShowing
    7.56 -     * @see RepaintManager#addDirtyRegion
    7.57 +     * @see RepaintController#addDirtyRegion
    7.58       */
    7.59      public void repaint(long tm, int x, int y, int width, int height) {
    7.60 -        RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
    7.61 +        RepaintController.currentManager(this).addDirtyRegion(this, x, y, width, height);
    7.62      }
    7.63  
    7.64  
    7.65 @@ -4786,7 +4786,7 @@
    7.66       *
    7.67       * @param  r a <code>Rectangle</code> containing the dirty region
    7.68       * @see java.awt.Component#isShowing
    7.69 -     * @see RepaintManager#addDirtyRegion
    7.70 +     * @see RepaintController#addDirtyRegion
    7.71       */
    7.72      public void repaint(Rectangle r) {
    7.73          repaint(0,r.x,r.y,r.width,r.height);
    7.74 @@ -4817,7 +4817,7 @@
    7.75       * @see java.awt.Component#invalidate
    7.76       * @see java.awt.Container#validate
    7.77       * @see #isValidateRoot
    7.78 -     * @see RepaintManager#addInvalidComponent
    7.79 +     * @see RepaintController#addInvalidComponent
    7.80       */
    7.81      public void revalidate() {
    7.82          if (getParent() == null) {
    7.83 @@ -4831,7 +4831,7 @@
    7.84          }
    7.85          if (SwingUtilities.isEventDispatchThread()) {
    7.86              invalidate();
    7.87 -            RepaintManager.currentManager(this).addInvalidComponent(this);
    7.88 +            RepaintController.currentManager(this).addInvalidComponent(this);
    7.89          }
    7.90          else {
    7.91              // To avoid a flood of Runnables when constructing GUIs off
    7.92 @@ -4980,7 +4980,7 @@
    7.93          JComponent bufferedComponent = null;
    7.94          JComponent paintingComponent = this;
    7.95  
    7.96 -        RepaintManager repaintManager = RepaintManager.currentManager(this);
    7.97 +        RepaintController repaintManager = RepaintController.currentManager(this);
    7.98          // parent Container's up to Window or Applet. First container is
    7.99          // the direct parent. Note that in testing it was faster to
   7.100          // alloc a new Vector vs keeping a stack of them around, and gc
   7.101 @@ -5121,7 +5121,7 @@
   7.102              g = safelyGetGraphics(paintingComponent, c);
   7.103              try {
   7.104                  if (hasBuffer) {
   7.105 -                    RepaintManager rm = RepaintManager.currentManager(
   7.106 +                    RepaintController rm = RepaintController.currentManager(
   7.107                                                 bufferedComponent);
   7.108                      rm.beginPaint();
   7.109                      try {
   7.110 @@ -5163,7 +5163,7 @@
   7.111      /**
   7.112       * Paints to the specified graphics.  This does not set the clip and it
   7.113       * does not adjust the Graphics in anyway, callers must do that first.
   7.114 -     * This method is package-private for RepaintManager.PaintManager and
   7.115 +     * This method is package-private for RepaintController.PaintManager and
   7.116       * its subclasses to call, it is NOT intended for general use outside
   7.117       * of that.
   7.118       */
   7.119 @@ -5175,7 +5175,7 @@
   7.120                  setFlag(IS_PAINTING_TILE, true);
   7.121              }
   7.122              if (getFlag(IS_REPAINTING)) {
   7.123 -                // Called from paintImmediately (RepaintManager) to fill
   7.124 +                // Called from paintImmediately (RepaintController) to fill
   7.125                  // repaint request
   7.126                  paint(g);
   7.127              } else {
     8.1 --- a/src/share/classes/javax/swing/JDialog.java	Fri Jun 19 21:46:14 2009 +0200
     8.2 +++ b/src/share/classes/javax/swing/JDialog.java	Sat Jun 20 22:10:34 2009 +0200
     8.3 @@ -1084,7 +1084,7 @@
     8.4  
     8.5      /**
     8.6       * Repaints the specified rectangle of this component within
     8.7 -     * <code>time</code> milliseconds.  Refer to <code>RepaintManager</code>
     8.8 +     * <code>time</code> milliseconds.  Refer to <code>RepaintController</code>
     8.9       * for details on how the repaint is handled.
    8.10       *
    8.11       * @param     time   maximum time in milliseconds before update
    8.12 @@ -1092,12 +1092,12 @@
    8.13       * @param     y    the <i>y</i> coordinate
    8.14       * @param     width    the width
    8.15       * @param     height   the height
    8.16 -     * @see       RepaintManager
    8.17 +     * @see       RepaintController
    8.18       * @since     1.6
    8.19       */
    8.20      public void repaint(long time, int x, int y, int width, int height) {
    8.21 -        if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
    8.22 -            RepaintManager.currentManager(this).addDirtyRegion(
    8.23 +        if (RepaintController.HANDLE_TOP_LEVEL_PAINT) {
    8.24 +            RepaintController.currentManager(this).addDirtyRegion(
    8.25                                this, x, y, width, height);
    8.26          }
    8.27          else {
     9.1 --- a/src/share/classes/javax/swing/JFrame.java	Fri Jun 19 21:46:14 2009 +0200
     9.2 +++ b/src/share/classes/javax/swing/JFrame.java	Sat Jun 20 22:10:34 2009 +0200
     9.3 @@ -761,7 +761,7 @@
     9.4  
     9.5      /**
     9.6       * Repaints the specified rectangle of this component within
     9.7 -     * <code>time</code> milliseconds.  Refer to <code>RepaintManager</code>
     9.8 +     * <code>time</code> milliseconds.  Refer to <code>RepaintController</code>
     9.9       * for details on how the repaint is handled.
    9.10       *
    9.11       * @param     time   maximum time in milliseconds before update
    9.12 @@ -769,12 +769,12 @@
    9.13       * @param     y    the <i>y</i> coordinate
    9.14       * @param     width    the width
    9.15       * @param     height   the height
    9.16 -     * @see       RepaintManager
    9.17 +     * @see       RepaintController
    9.18       * @since     1.6
    9.19       */
    9.20      public void repaint(long time, int x, int y, int width, int height) {
    9.21 -        if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
    9.22 -            RepaintManager.currentManager(this).addDirtyRegion(
    9.23 +        if (RepaintController.HANDLE_TOP_LEVEL_PAINT) {
    9.24 +            RepaintController.currentManager(this).addDirtyRegion(
    9.25                                this, x, y, width, height);
    9.26          }
    9.27          else {
    10.1 --- a/src/share/classes/javax/swing/JRootPane.java	Fri Jun 19 21:46:14 2009 +0200
    10.2 +++ b/src/share/classes/javax/swing/JRootPane.java	Sat Jun 20 22:10:34 2009 +0200
    10.3 @@ -376,7 +376,7 @@
    10.4      public void setDoubleBuffered(boolean aFlag) {
    10.5          if (isDoubleBuffered() != aFlag) {
    10.6              super.setDoubleBuffered(aFlag);
    10.7 -            RepaintManager.currentManager(this).doubleBufferingChanged(this);
    10.8 +            RepaintController.currentManager(this).doubleBufferingChanged(this);
    10.9          }
   10.10      }
   10.11  
   10.12 @@ -825,7 +825,7 @@
   10.13                      Thread.dumpStack();
   10.14                  }
   10.15                  useTrueDoubleBuffering = false;
   10.16 -                RepaintManager.currentManager(this).
   10.17 +                RepaintController.currentManager(this).
   10.18                          doubleBufferingChanged(this);
   10.19              }
   10.20          }
    11.1 --- a/src/share/classes/javax/swing/JViewport.java	Fri Jun 19 21:46:14 2009 +0200
    11.2 +++ b/src/share/classes/javax/swing/JViewport.java	Sat Jun 20 22:10:34 2009 +0200
    11.3 @@ -464,7 +464,7 @@
    11.4       * <code>true</code> to <code>isValidateRoot</code>.
    11.5       * If all the <code>Component</code>'s  parents are visible,
    11.6       * <code>validate</code> will then be invoked on it. The
    11.7 -     * <code>RepaintManager</code> is then invoked with
    11.8 +     * <code>RepaintController</code> is then invoked with
    11.9       * <code>removeInvalidComponent</code>. This
   11.10       * is the synchronous version of a <code>revalidate</code>.
   11.11       */
   11.12 @@ -515,9 +515,9 @@
   11.13          // Validate the root.
   11.14          validateRoot.validate();
   11.15  
   11.16 -        // And let the RepaintManager it does not have to validate from
   11.17 +        // And let the RepaintController it does not have to validate from
   11.18          // validateRoot anymore.
   11.19 -        RepaintManager rm = RepaintManager.currentManager(this);
   11.20 +        RepaintController rm = RepaintController.currentManager(this);
   11.21  
   11.22          if (rm != null) {
   11.23              rm.removeInvalidComponent((JComponent)validateRoot);
   11.24 @@ -1111,7 +1111,7 @@
   11.25  
   11.26          if ((oldX != newX) || (oldY != newY)) {
   11.27              if (!waitingForRepaint && isBlitting() && canUseWindowBlitter()) {
   11.28 -                RepaintManager rm = RepaintManager.currentManager(this);
   11.29 +                RepaintController rm = RepaintController.currentManager(this);
   11.30                  // The cast to JComponent will work, if view is not
   11.31                  // a JComponent, isBlitting will return false.
   11.32                  JComponent jview = (JComponent)view;
   11.33 @@ -1399,7 +1399,7 @@
   11.34  
   11.35      /**
   11.36       * Always repaint in the parents coordinate system to make sure
   11.37 -     * only one paint is performed by the <code>RepaintManager</code>.
   11.38 +     * only one paint is performed by the <code>RepaintController</code>.
   11.39       *
   11.40       * @param     tm   maximum time in milliseconds before update
   11.41       * @param     x    the <code>x</code> coordinate (pixels over from left)
   11.42 @@ -1551,7 +1551,7 @@
   11.43          }
   11.44  
   11.45          boolean retValue;
   11.46 -        RepaintManager rm = RepaintManager.currentManager(this);
   11.47 +        RepaintController rm = RepaintController.currentManager(this);
   11.48          JComponent view = (JComponent) getView();
   11.49  
   11.50          if (lastPaintPosition == null ||
   11.51 @@ -1607,7 +1607,7 @@
   11.52          //   blitFrom/blitTo are in JViewport coordinates system
   11.53          //     not the views coordinate space.
   11.54          //   clip* are in the views coordinate space.
   11.55 -        RepaintManager rm = RepaintManager.currentManager(this);
   11.56 +        RepaintController rm = RepaintController.currentManager(this);
   11.57          int bdx = blitToX - blitFromX;
   11.58          int bdy = blitToY - blitFromY;
   11.59  
   11.60 @@ -1676,7 +1676,7 @@
   11.61              return false;
   11.62          }
   11.63  
   11.64 -        Rectangle dirtyRegion = RepaintManager.currentManager(this).
   11.65 +        Rectangle dirtyRegion = RepaintController.currentManager(this).
   11.66                                  getDirtyRegion((JComponent)getParent());
   11.67  
   11.68          if (dirtyRegion != null && dirtyRegion.width > 0 &&
    12.1 --- a/src/share/classes/javax/swing/JWindow.java	Fri Jun 19 21:46:14 2009 +0200
    12.2 +++ b/src/share/classes/javax/swing/JWindow.java	Sat Jun 20 22:10:34 2009 +0200
    12.3 @@ -593,7 +593,7 @@
    12.4  
    12.5      /**
    12.6       * Repaints the specified rectangle of this component within
    12.7 -     * <code>time</code> milliseconds.  Refer to <code>RepaintManager</code>
    12.8 +     * <code>time</code> milliseconds.  Refer to <code>RepaintController</code>
    12.9       * for details on how the repaint is handled.
   12.10       *
   12.11       * @param     time   maximum time in milliseconds before update
   12.12 @@ -601,12 +601,12 @@
   12.13       * @param     y    the <i>y</i> coordinate
   12.14       * @param     width    the width
   12.15       * @param     height   the height
   12.16 -     * @see       RepaintManager
   12.17 +     * @see       RepaintController
   12.18       * @since     1.6
   12.19       */
   12.20      public void repaint(long time, int x, int y, int width, int height) {
   12.21 -        if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
   12.22 -            RepaintManager.currentManager(this).addDirtyRegion(
   12.23 +        if (RepaintController.HANDLE_TOP_LEVEL_PAINT) {
   12.24 +            RepaintController.currentManager(this).addDirtyRegion(
   12.25                                this, x, y, width, height);
   12.26          }
   12.27          else {
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/share/classes/javax/swing/RepaintController.java	Sat Jun 20 22:10:34 2009 +0200
    13.3 @@ -0,0 +1,1647 @@
    13.4 +/*
    13.5 + * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.  Sun designates this
   13.11 + * particular file as subject to the "Classpath" exception as provided
   13.12 + * by Sun in the LICENSE file that accompanied this code.
   13.13 + *
   13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 + * version 2 for more details (a copy is included in the LICENSE file that
   13.18 + * accompanied this code).
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License version
   13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 + *
   13.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   13.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
   13.26 + * have any questions.
   13.27 + */
   13.28 +package javax.swing;
   13.29 +
   13.30 +
   13.31 +import java.awt.*;
   13.32 +import java.awt.event.*;
   13.33 +import java.awt.image.VolatileImage;
   13.34 +import java.security.AccessController;
   13.35 +import java.util.*;
   13.36 +
   13.37 +import sun.awt.AWTAccessor;
   13.38 +import sun.awt.AppContext;
   13.39 +import sun.awt.DisplayChangedListener;
   13.40 +import sun.awt.SunToolkit;
   13.41 +import sun.java2d.SunGraphicsEnvironment;
   13.42 +import sun.security.action.GetPropertyAction;
   13.43 +
   13.44 +import com.sun.java.swing.SwingUtilities3;
   13.45 +import sun.swing.SwingUtilities2;
   13.46 +
   13.47 +/**
   13.48 + * This class manages repaint requests, allowing the number
   13.49 + * of repaints to be minimized, for example by collapsing multiple
   13.50 + * requests into a single repaint for members of a component tree.
   13.51 + * <p>
   13.52 + * As of 1.6 <code>RepaintController</code> handles repaint requests
   13.53 + * for Swing's top level components (<code>JApplet</code>,
   13.54 + * <code>JWindow</code>, <code>JFrame</code> and <code>JDialog</code>).
   13.55 + * Any calls to <code>repaint</code> on one of these will call into the
   13.56 + * appropriate <code>addDirtyRegion</code> method.
   13.57 + *
   13.58 + * @author Arnaud Weber
   13.59 + */
   13.60 +public class RepaintController
   13.61 +{
   13.62 +    /**
   13.63 +     * Whether or not the RepaintController should handle paint requests
   13.64 +     * for top levels.
   13.65 +     */
   13.66 +    static final boolean HANDLE_TOP_LEVEL_PAINT;
   13.67 +
   13.68 +    private static final short BUFFER_STRATEGY_NOT_SPECIFIED = 0;
   13.69 +    private static final short BUFFER_STRATEGY_SPECIFIED_ON = 1;
   13.70 +    private static final short BUFFER_STRATEGY_SPECIFIED_OFF = 2;
   13.71 +
   13.72 +    private static final short BUFFER_STRATEGY_TYPE;
   13.73 +
   13.74 +    /**
   13.75 +     * Maps from GraphicsConfiguration to VolatileImage.
   13.76 +     */
   13.77 +    private Map<GraphicsConfiguration,VolatileImage> volatileMap = new
   13.78 +                        HashMap<GraphicsConfiguration,VolatileImage>(1);
   13.79 +
   13.80 +    //
   13.81 +    // As of 1.6 Swing handles scheduling of paint events from native code.
   13.82 +    // That is, SwingPaintEventDispatcher is invoked on the toolkit thread,
   13.83 +    // which in turn invokes nativeAddDirtyRegion.  Because this is invoked
   13.84 +    // from the native thread we can not invoke any public methods and so
   13.85 +    // we introduce these added maps.  So, any time nativeAddDirtyRegion is
   13.86 +    // invoked the region is added to hwDirtyComponents and a work request
   13.87 +    // is scheduled.  When the work request is processed all entries in
   13.88 +    // this map are pushed to the real map (dirtyComponents) and then
   13.89 +    // painted with the rest of the components.
   13.90 +    //
   13.91 +    private Map<Container,Rectangle> hwDirtyComponents;
   13.92 +
   13.93 +    private Map<Component,Rectangle> dirtyComponents;
   13.94 +    private Map<Component,Rectangle> tmpDirtyComponents;
   13.95 +    private java.util.List<Component> invalidComponents;
   13.96 +
   13.97 +    // List of Runnables that need to be processed before painting from AWT.
   13.98 +    private java.util.List<Runnable> runnableList;
   13.99 +
  13.100 +    boolean   doubleBufferingEnabled = true;
  13.101 +
  13.102 +    private Dimension doubleBufferMaxSize;
  13.103 +
  13.104 +    // Support for both the standard and volatile offscreen buffers exists to
  13.105 +    // provide backwards compatibility for the [rare] programs which may be
  13.106 +    // calling getOffScreenBuffer() and not expecting to get a VolatileImage.
  13.107 +    // Swing internally is migrating to use *only* the volatile image buffer.
  13.108 +
  13.109 +    // Support for standard offscreen buffer
  13.110 +    //
  13.111 +    DoubleBufferInfo standardDoubleBuffer;
  13.112 +
  13.113 +    /**
  13.114 +     * Object responsible for hanlding core paint functionality.
  13.115 +     */
  13.116 +    private PaintManager paintManager;
  13.117 +
  13.118 +    private static final Object RepaintControllerKey = RepaintController.class;
  13.119 +
  13.120 +    // Whether or not a VolatileImage should be used for double-buffered painting
  13.121 +    static boolean volatileImageBufferEnabled = true;
  13.122 +    /**
  13.123 +     * Value of the system property awt.nativeDoubleBuffering.
  13.124 +     */
  13.125 +    private static boolean nativeDoubleBuffering;
  13.126 +
  13.127 +    // The maximum number of times Swing will attempt to use the VolatileImage
  13.128 +    // buffer during a paint operation.
  13.129 +    private static final int VOLATILE_LOOP_MAX = 2;
  13.130 +
  13.131 +    /**
  13.132 +     * Number of <code>beginPaint</code> that have been invoked.
  13.133 +     */
  13.134 +    private int paintDepth = 0;
  13.135 +
  13.136 +    /**
  13.137 +     * Type of buffer strategy to use.  Will be one of the BUFFER_STRATEGY_
  13.138 +     * constants.
  13.139 +     */
  13.140 +    private short bufferStrategyType;
  13.141 +
  13.142 +    //
  13.143 +    // BufferStrategyPaintManager has the unique characteristic that it
  13.144 +    // must deal with the buffer being lost while painting to it.  For
  13.145 +    // example, if we paint a component and show it and the buffer has
  13.146 +    // become lost we must repaint the whole window.  To deal with that
  13.147 +    // the PaintManager calls into repaintRoot, and if we're still in
  13.148 +    // the process of painting the repaintRoot field is set to the JRootPane
  13.149 +    // and after the current JComponent.paintImmediately call finishes
  13.150 +    // paintImmediately will be invoked on the repaintRoot.  In this
  13.151 +    // way we don't try to show garbage to the screen.
  13.152 +    //
  13.153 +    /**
  13.154 +     * True if we're in the process of painting the dirty regions.  This is
  13.155 +     * set to true in <code>paintDirtyRegions</code>.
  13.156 +     */
  13.157 +    private boolean painting;
  13.158 +    /**
  13.159 +     * If the PaintManager calls into repaintRoot during painting this field
  13.160 +     * will be set to the root.
  13.161 +     */
  13.162 +    private JComponent repaintRoot;
  13.163 +
  13.164 +    /**
  13.165 +     * The Thread that has initiated painting.  If null it
  13.166 +     * indicates painting is not currently in progress.
  13.167 +     */
  13.168 +    private Thread paintThread;
  13.169 +
  13.170 +    /**
  13.171 +     * Runnable used to process all repaint/revalidate requests.
  13.172 +     */
  13.173 +    private final ProcessingRunnable processingRunnable;
  13.174 +
  13.175 +
  13.176 +    static {
  13.177 +        volatileImageBufferEnabled = "true".equals(AccessController.
  13.178 +                doPrivileged(new GetPropertyAction(
  13.179 +                "swing.volatileImageBufferEnabled", "true")));
  13.180 +        boolean headless = GraphicsEnvironment.isHeadless();
  13.181 +        if (volatileImageBufferEnabled && headless) {
  13.182 +            volatileImageBufferEnabled = false;
  13.183 +        }
  13.184 +        nativeDoubleBuffering = "true".equals(AccessController.doPrivileged(
  13.185 +                    new GetPropertyAction("awt.nativeDoubleBuffering")));
  13.186 +        String bs = AccessController.doPrivileged(
  13.187 +                          new GetPropertyAction("swing.bufferPerWindow"));
  13.188 +        if (headless) {
  13.189 +            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
  13.190 +        }
  13.191 +        else if (bs == null) {
  13.192 +            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_NOT_SPECIFIED;
  13.193 +        }
  13.194 +        else if ("true".equals(bs)) {
  13.195 +            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_ON;
  13.196 +        }
  13.197 +        else {
  13.198 +            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
  13.199 +        }
  13.200 +        HANDLE_TOP_LEVEL_PAINT = "true".equals(AccessController.doPrivileged(
  13.201 +               new GetPropertyAction("swing.handleTopLevelPaint", "true")));
  13.202 +        GraphicsEnvironment ge = GraphicsEnvironment.
  13.203 +                getLocalGraphicsEnvironment();
  13.204 +        if (ge instanceof SunGraphicsEnvironment) {
  13.205 +            ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
  13.206 +                    new DisplayChangedHandler());
  13.207 +        }
  13.208 +    }
  13.209 +
  13.210 +    /**
  13.211 +     * Return the RepaintController for the calling thread given a Component.
  13.212 +     *
  13.213 +     * @param c a Component -- unused in the default implementation, but could
  13.214 +     *          be used by an overridden version to return a different RepaintController
  13.215 +     *          depending on the Component
  13.216 +     * @return the RepaintController object
  13.217 +     */
  13.218 +    public static RepaintController currentManager(Component c) {
  13.219 +        // Note: DisplayChangedRunnable passes in null as the component, so if
  13.220 +        // component is ever used to determine the current
  13.221 +        // RepaintController, DisplayChangedRunnable will need to be modified
  13.222 +        // accordingly.
  13.223 +        return currentManager(AppContext.getAppContext());
  13.224 +    }
  13.225 +
  13.226 +    /**
  13.227 +     * Returns the RepaintController for the specified AppContext.  If
  13.228 +     * a RepaintController has not been created for the specified
  13.229 +     * AppContext this will return null.
  13.230 +     */
  13.231 +    static RepaintController currentManager(AppContext appContext) {
  13.232 +        RepaintController rm = (RepaintController)appContext.get(RepaintControllerKey);
  13.233 +        if (rm == null) {
  13.234 +            rm = new RepaintController(BUFFER_STRATEGY_TYPE);
  13.235 +            appContext.put(RepaintControllerKey, rm);
  13.236 +        }
  13.237 +        return rm;
  13.238 +    }
  13.239 +
  13.240 +    /**
  13.241 +     * Return the RepaintController for the calling thread given a JComponent.
  13.242 +     * <p>
  13.243 +    * Note: This method exists for backward binary compatibility with earlier
  13.244 +     * versions of the Swing library. It simply returns the result returned by
  13.245 +     * {@link #currentManager(Component)}.
  13.246 +     *
  13.247 +     * @param c a JComponent -- unused
  13.248 +     * @return the RepaintController object
  13.249 +     */
  13.250 +    public static RepaintController currentManager(JComponent c) {
  13.251 +        return currentManager((Component)c);
  13.252 +    }
  13.253 +
  13.254 +
  13.255 +    /**
  13.256 +     * Set the RepaintController that should be used for the calling
  13.257 +     * thread. <b>aRepaintController</b> will become the current RepaintController
  13.258 +     * for the calling thread's thread group.
  13.259 +     * @param aRepaintController  the RepaintController object to use
  13.260 +     */
  13.261 +    public static void setCurrentManager(RepaintController aRepaintController) {
  13.262 +        if (aRepaintController != null) {
  13.263 +            SwingUtilities.appContextPut(RepaintControllerKey, aRepaintController);
  13.264 +        } else {
  13.265 +            SwingUtilities.appContextRemove(RepaintControllerKey);
  13.266 +        }
  13.267 +    }
  13.268 +
  13.269 +    /**
  13.270 +     * Create a new RepaintController instance. You rarely call this constructor.
  13.271 +     * directly. To get the default RepaintController, use
  13.272 +     * RepaintController.currentManager(JComponent) (normally "this").
  13.273 +     */
  13.274 +    public RepaintController() {
  13.275 +        // Because we can't know what a subclass is doing with the
  13.276 +        // volatile image we immediately punt in subclasses.  If this
  13.277 +        // poses a problem we'll need a more sophisticated detection algorithm,
  13.278 +        // or API.
  13.279 +        this(BUFFER_STRATEGY_SPECIFIED_OFF);
  13.280 +    }
  13.281 +
  13.282 +    private RepaintController(short bufferStrategyType) {
  13.283 +        // If native doublebuffering is being used, do NOT use
  13.284 +        // Swing doublebuffering.
  13.285 +        doubleBufferingEnabled = !nativeDoubleBuffering;
  13.286 +        synchronized(this) {
  13.287 +            dirtyComponents = new IdentityHashMap<Component,Rectangle>();
  13.288 +            tmpDirtyComponents = new IdentityHashMap<Component,Rectangle>();
  13.289 +            this.bufferStrategyType = bufferStrategyType;
  13.290 +            hwDirtyComponents = new IdentityHashMap<Container,Rectangle>();
  13.291 +        }
  13.292 +        processingRunnable = new ProcessingRunnable();
  13.293 +    }
  13.294 +
  13.295 +    private void displayChanged() {
  13.296 +        clearImages();
  13.297 +    }
  13.298 +
  13.299 +    /**
  13.300 +     * Mark the component as in need of layout and queue a runnable
  13.301 +     * for the event dispatching thread that will validate the components
  13.302 +     * first isValidateRoot() ancestor.
  13.303 +     *
  13.304 +     * @see JComponent#isValidateRoot
  13.305 +     * @see #removeInvalidComponent
  13.306 +     */
  13.307 +    public synchronized void addInvalidComponent(JComponent invalidComponent)
  13.308 +    {
  13.309 +        RepaintController delegate = getDelegate(invalidComponent);
  13.310 +        if (delegate != null) {
  13.311 +            delegate.addInvalidComponent(invalidComponent);
  13.312 +            return;
  13.313 +        }
  13.314 +        Component validateRoot = null;
  13.315 +
  13.316 +        /* Find the first JComponent ancestor of this component whose
  13.317 +         * isValidateRoot() method returns true.
  13.318 +         */
  13.319 +        for(Component c = invalidComponent; c != null; c = c.getParent()) {
  13.320 +            if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
  13.321 +                return;
  13.322 +            }
  13.323 +            if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
  13.324 +                validateRoot = c;
  13.325 +                break;
  13.326 +            }
  13.327 +        }
  13.328 +
  13.329 +        /* There's no validateRoot to apply validate to, so we're done.
  13.330 +         */
  13.331 +        if (validateRoot == null) {
  13.332 +            return;
  13.333 +        }
  13.334 +
  13.335 +        /* If the validateRoot and all of its ancestors aren't visible
  13.336 +         * then we don't do anything.  While we're walking up the tree
  13.337 +         * we find the root Window or Applet.
  13.338 +         */
  13.339 +        Component root = null;
  13.340 +
  13.341 +        for(Component c = validateRoot; c != null; c = c.getParent()) {
  13.342 +            if (!c.isVisible() || (c.getPeer() == null)) {
  13.343 +                return;
  13.344 +            }
  13.345 +            if ((c instanceof Window) || SwingUtilities2.isApplet(c)) {
  13.346 +                root = c;
  13.347 +                break;
  13.348 +            }
  13.349 +        }
  13.350 +
  13.351 +        if (root == null) {
  13.352 +            return;
  13.353 +        }
  13.354 +
  13.355 +        /* Lazily create the invalidateComponents vector and add the
  13.356 +         * validateRoot if it's not there already.  If this validateRoot
  13.357 +         * is already in the vector, we're done.
  13.358 +         */
  13.359 +        if (invalidComponents == null) {
  13.360 +            invalidComponents = new ArrayList<Component>();
  13.361 +        }
  13.362 +        else {
  13.363 +            int n = invalidComponents.size();
  13.364 +            for(int i = 0; i < n; i++) {
  13.365 +                if(validateRoot == invalidComponents.get(i)) {
  13.366 +                    return;
  13.367 +                }
  13.368 +            }
  13.369 +        }
  13.370 +        invalidComponents.add(validateRoot);
  13.371 +
  13.372 +        // Queue a Runnable to invoke paintDirtyRegions and
  13.373 +        // validateInvalidComponents.
  13.374 +        scheduleProcessingRunnable();
  13.375 +    }
  13.376 +
  13.377 +
  13.378 +    /**
  13.379 +     * Remove a component from the list of invalid components.
  13.380 +     *
  13.381 +     * @see #addInvalidComponent
  13.382 +     */
  13.383 +    public synchronized void removeInvalidComponent(JComponent component) {
  13.384 +        RepaintController delegate = getDelegate(component);
  13.385 +        if (delegate != null) {
  13.386 +            delegate.removeInvalidComponent(component);
  13.387 +            return;
  13.388 +        }
  13.389 +        if(invalidComponents != null) {
  13.390 +            int index = invalidComponents.indexOf(component);
  13.391 +            if(index != -1) {
  13.392 +                invalidComponents.remove(index);
  13.393 +            }
  13.394 +        }
  13.395 +    }
  13.396 +
  13.397 +
  13.398 +    /**
  13.399 +     * Add a component in the list of components that should be refreshed.
  13.400 +     * If <i>c</i> already has a dirty region, the rectangle <i>(x,y,w,h)</i>
  13.401 +     * will be unioned with the region that should be redrawn.
  13.402 +     *
  13.403 +     * @see JComponent#repaint
  13.404 +     */
  13.405 +    final void addDirtyRegion0(Container c, int x, int y, int w, int h) {
  13.406 +        /* Special cases we don't have to bother with.
  13.407 +         */
  13.408 +        if ((w <= 0) || (h <= 0) || (c == null)) {
  13.409 +            return;
  13.410 +        }
  13.411 +
  13.412 +        if ((c.getWidth() <= 0) || (c.getHeight() <= 0)) {
  13.413 +            return;
  13.414 +        }
  13.415 +
  13.416 +        if (extendDirtyRegion(c, x, y, w, h)) {
  13.417 +            // Component was already marked as dirty, region has been
  13.418 +            // extended, no need to continue.
  13.419 +            return;
  13.420 +        }
  13.421 +
  13.422 +        /* Make sure that c and all it ancestors (up to an Applet or
  13.423 +         * Window) are visible.  This loop has the same effect as
  13.424 +         * checking c.isShowing() (and note that it's still possible
  13.425 +         * that c is completely obscured by an opaque ancestor in
  13.426 +         * the specified rectangle).
  13.427 +         */
  13.428 +        Component root = null;
  13.429 +
  13.430 +        // Note: We can't synchronize around this, Frame.getExtendedState
  13.431 +        // is synchronized so that if we were to synchronize around this
  13.432 +        // it could lead to the possibility of getting locks out
  13.433 +        // of order and deadlocking.
  13.434 +        for (Container p = c; p != null; p = p.getParent()) {
  13.435 +            if (!p.isVisible() || (p.getPeer() == null)) {
  13.436 +                return;
  13.437 +            }
  13.438 +            if ((p instanceof Window) || SwingUtilities2.isApplet(p)) {
  13.439 +                // Iconified frames are still visible!
  13.440 +                if (p instanceof Frame &&
  13.441 +                        (((Frame)p).getExtendedState() & Frame.ICONIFIED) ==
  13.442 +                                    Frame.ICONIFIED) {
  13.443 +                    return;
  13.444 +                }
  13.445 +                root = p;
  13.446 +                break;
  13.447 +            }
  13.448 +        }
  13.449 +
  13.450 +        if (root == null) return;
  13.451 +
  13.452 +        synchronized(this) {
  13.453 +            if (extendDirtyRegion(c, x, y, w, h)) {
  13.454 +                // In between last check and this check another thread
  13.455 +                // queued up runnable, can bail here.
  13.456 +                return;
  13.457 +            }
  13.458 +            dirtyComponents.put(c, new Rectangle(x, y, w, h));
  13.459 +        }
  13.460 +
  13.461 +        // Queue a Runnable to invoke paintDirtyRegions and
  13.462 +        // validateInvalidComponents.
  13.463 +        scheduleProcessingRunnable();
  13.464 +    }
  13.465 +
  13.466 +    /**
  13.467 +     * Add a component in the list of components that should be refreshed.
  13.468 +     * If <i>c</i> already has a dirty region, the rectangle <i>(x,y,w,h)</i>
  13.469 +     * will be unioned with the region that should be redrawn.
  13.470 +     *
  13.471 +     * @param c Component to repaint, null results in nothing happening.
  13.472 +     * @param x X coordinate of the region to repaint
  13.473 +     * @param y Y coordinate of the region to repaint
  13.474 +     * @param w Width of the region to repaint
  13.475 +     * @param h Height of the region to repaint
  13.476 +     * @see JComponent#repaint
  13.477 +     */
  13.478 +    public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
  13.479 +    {
  13.480 +        RepaintController delegate = getDelegate(c);
  13.481 +        if (delegate != null) {
  13.482 +            delegate.addDirtyRegion(c, x, y, w, h);
  13.483 +            return;
  13.484 +        }
  13.485 +        addDirtyRegion0(c, x, y, w, h);
  13.486 +    }
  13.487 +
  13.488 +    /**
  13.489 +     * Adds <code>window</code> to the list of <code>Component</code>s that
  13.490 +     * need to be repainted.
  13.491 +     *
  13.492 +     * @param window Window to repaint, null results in nothing happening.
  13.493 +     * @param x X coordinate of the region to repaint
  13.494 +     * @param y Y coordinate of the region to repaint
  13.495 +     * @param w Width of the region to repaint
  13.496 +     * @param h Height of the region to repaint
  13.497 +     * @see JFrame#repaint
  13.498 +     * @see JWindow#repaint
  13.499 +     * @see JDialog#repaint
  13.500 +     * @since 1.6
  13.501 +     */
  13.502 +    public void addDirtyRegion(Window window, int x, int y, int w, int h) {
  13.503 +        addDirtyRegion0(window, x, y, w, h);
  13.504 +    }
  13.505 +
  13.506 +    void scheduleHeavyWeightPaints() {
  13.507 +        Map<Container,Rectangle> hws;
  13.508 +
  13.509 +        synchronized(this) {
  13.510 +            if (hwDirtyComponents.size() == 0) {
  13.511 +                return;
  13.512 +            }
  13.513 +            hws = hwDirtyComponents;
  13.514 +            hwDirtyComponents =  new IdentityHashMap<Container,Rectangle>();
  13.515 +        }
  13.516 +        for (Container hw : hws.keySet()) {
  13.517 +            Rectangle dirty = hws.get(hw);
  13.518 +            if (hw instanceof Window) {
  13.519 +                addDirtyRegion((Window)hw, dirty.x, dirty.y,
  13.520 +                               dirty.width, dirty.height);
  13.521 +            }
  13.522 +            else if (SwingUtilities2.isApplet(hw)) {
  13.523 +                addDirtyRegion0(hw, dirty.x, dirty.y,
  13.524 +                               dirty.width, dirty.height);
  13.525 +            }
  13.526 +            else { // SwingHeavyWeight
  13.527 +                addDirtyRegion0(hw, dirty.x, dirty.y,
  13.528 +                                dirty.width, dirty.height);
  13.529 +            }
  13.530 +        }
  13.531 +    }
  13.532 +
  13.533 +    //
  13.534 +    // This is called from the toolkit thread when a native expose is
  13.535 +    // received.
  13.536 +    //
  13.537 +    void nativeAddDirtyRegion(AppContext appContext, Container c,
  13.538 +                              int x, int y, int w, int h) {
  13.539 +        if (w > 0 && h > 0) {
  13.540 +            synchronized(this) {
  13.541 +                Rectangle dirty = hwDirtyComponents.get(c);
  13.542 +                if (dirty == null) {
  13.543 +                    hwDirtyComponents.put(c, new Rectangle(x, y, w, h));
  13.544 +                }
  13.545 +                else {
  13.546 +                    hwDirtyComponents.put(c, SwingUtilities.computeUnion(
  13.547 +                                              x, y, w, h, dirty));
  13.548 +                }
  13.549 +            }
  13.550 +            scheduleProcessingRunnable(appContext);
  13.551 +        }
  13.552 +    }
  13.553 +
  13.554 +    //
  13.555 +    // This is called from the toolkit thread when awt needs to run a
  13.556 +    // Runnable before we paint.
  13.557 +    //
  13.558 +    void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
  13.559 +                                        Runnable r) {
  13.560 +        synchronized(this) {
  13.561 +            if (runnableList == null) {
  13.562 +                runnableList = new LinkedList<Runnable>();
  13.563 +            }
  13.564 +            runnableList.add(r);
  13.565 +        }
  13.566 +        scheduleProcessingRunnable(appContext);
  13.567 +    }
  13.568 +
  13.569 +    /**
  13.570 +     * Extends the dirty region for the specified component to include
  13.571 +     * the new region.
  13.572 +     *
  13.573 +     * @return false if <code>c</code> is not yet marked dirty.
  13.574 +     */
  13.575 +    private synchronized boolean extendDirtyRegion(
  13.576 +        Component c, int x, int y, int w, int h) {
  13.577 +        Rectangle r = dirtyComponents.get(c);
  13.578 +        if (r != null) {
  13.579 +            // A non-null r implies c is already marked as dirty,
  13.580 +            // and that the parent is valid. Therefore we can
  13.581 +            // just union the rect and bail.
  13.582 +            SwingUtilities.computeUnion(x, y, w, h, r);
  13.583 +            return true;
  13.584 +        }
  13.585 +        return false;
  13.586 +    }
  13.587 +
  13.588 +    /** Return the current dirty region for a component.
  13.589 +     *  Return an empty rectangle if the component is not
  13.590 +     *  dirty.
  13.591 +     */
  13.592 +    public Rectangle getDirtyRegion(JComponent aComponent) {
  13.593 +        RepaintController delegate = getDelegate(aComponent);
  13.594 +        if (delegate != null) {
  13.595 +            return delegate.getDirtyRegion(aComponent);
  13.596 +        }
  13.597 +        Rectangle r;
  13.598 +        synchronized(this) {
  13.599 +            r = dirtyComponents.get(aComponent);
  13.600 +        }
  13.601 +        if(r == null)
  13.602 +            return new Rectangle(0,0,0,0);
  13.603 +        else
  13.604 +            return new Rectangle(r);
  13.605 +    }
  13.606 +
  13.607 +    /**
  13.608 +     * Mark a component completely dirty. <b>aComponent</b> will be
  13.609 +     * completely painted during the next paintDirtyRegions() call.
  13.610 +     */
  13.611 +    public void markCompletelyDirty(JComponent aComponent) {
  13.612 +        RepaintController delegate = getDelegate(aComponent);
  13.613 +        if (delegate != null) {
  13.614 +            delegate.markCompletelyDirty(aComponent);
  13.615 +            return;
  13.616 +        }
  13.617 +        addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE);
  13.618 +    }
  13.619 +
  13.620 +    /**
  13.621 +     * Mark a component completely clean. <b>aComponent</b> will not
  13.622 +     * get painted during the next paintDirtyRegions() call.
  13.623 +     */
  13.624 +    public void markCompletelyClean(JComponent aComponent) {
  13.625 +        RepaintController delegate = getDelegate(aComponent);
  13.626 +        if (delegate != null) {
  13.627 +            delegate.markCompletelyClean(aComponent);
  13.628 +            return;
  13.629 +        }
  13.630 +        synchronized(this) {
  13.631 +                dirtyComponents.remove(aComponent);
  13.632 +        }
  13.633 +    }
  13.634 +
  13.635 +    /**
  13.636 +     * Convenience method that returns true if <b>aComponent</b> will be completely
  13.637 +     * painted during the next paintDirtyRegions(). If computing dirty regions is
  13.638 +     * expensive for your component, use this method and avoid computing dirty region
  13.639 +     * if it return true.
  13.640 +     */
  13.641 +    public boolean isCompletelyDirty(JComponent aComponent) {
  13.642 +        RepaintController delegate = getDelegate(aComponent);
  13.643 +        if (delegate != null) {
  13.644 +            return delegate.isCompletelyDirty(aComponent);
  13.645 +        }
  13.646 +        Rectangle r;
  13.647 +
  13.648 +        r = getDirtyRegion(aComponent);
  13.649 +        if(r.width == Integer.MAX_VALUE &&
  13.650 +           r.height == Integer.MAX_VALUE)
  13.651 +            return true;
  13.652 +        else
  13.653 +            return false;
  13.654 +    }
  13.655 +
  13.656 +
  13.657 +    /**
  13.658 +     * Validate all of the components that have been marked invalid.
  13.659 +     * @see #addInvalidComponent
  13.660 +     */
  13.661 +    public void validateInvalidComponents() {
  13.662 +        java.util.List<Component> ic;
  13.663 +        synchronized(this) {
  13.664 +            if(invalidComponents == null) {
  13.665 +                return;
  13.666 +            }
  13.667 +            ic = invalidComponents;
  13.668 +            invalidComponents = null;
  13.669 +        }
  13.670 +        int n = ic.size();
  13.671 +        for(int i = 0; i < n; i++) {
  13.672 +            ic.get(i).validate();
  13.673 +        }
  13.674 +    }
  13.675 +
  13.676 +
  13.677 +    /**
  13.678 +     * This is invoked to process paint requests.  It's needed
  13.679 +     * for backward compatability in so far as RepaintController would previously
  13.680 +     * not see paint requests for top levels, so, we have to make sure
  13.681 +     * a subclass correctly paints any dirty top levels.
  13.682 +     */
  13.683 +    private void prePaintDirtyRegions() {
  13.684 +        Map<Component,Rectangle> dirtyComponents;
  13.685 +        java.util.List<Runnable> runnableList;
  13.686 +        synchronized(this) {
  13.687 +            dirtyComponents = this.dirtyComponents;
  13.688 +            runnableList = this.runnableList;
  13.689 +            this.runnableList = null;
  13.690 +        }
  13.691 +        if (runnableList != null) {
  13.692 +            for (Runnable runnable : runnableList) {
  13.693 +                runnable.run();
  13.694 +            }
  13.695 +        }
  13.696 +        paintDirtyRegions();
  13.697 +        if (dirtyComponents.size() > 0) {
  13.698 +            // This'll only happen if a subclass isn't correctly dealing
  13.699 +            // with toplevels.
  13.700 +            paintDirtyRegions(dirtyComponents);
  13.701 +        }
  13.702 +    }
  13.703 +
  13.704 +    private void updateWindows(Map<Component,Rectangle> dirtyComponents) {
  13.705 +        Toolkit toolkit = Toolkit.getDefaultToolkit();
  13.706 +        if (!(toolkit instanceof SunToolkit &&
  13.707 +              ((SunToolkit)toolkit).needUpdateWindow()))
  13.708 +        {
  13.709 +            return;
  13.710 +        }
  13.711 +
  13.712 +        Set<Window> windows = new HashSet<Window>();
  13.713 +        Set<Component> dirtyComps = dirtyComponents.keySet();
  13.714 +        for (Iterator<Component> it = dirtyComps.iterator(); it.hasNext();) {
  13.715 +            Component dirty = it.next();
  13.716 +            Window window = dirty instanceof Window ?
  13.717 +                (Window)dirty :
  13.718 +                SwingUtilities.getWindowAncestor(dirty);
  13.719 +            if (window != null &&
  13.720 +                !AWTAccessor.getWindowAccessor().isOpaque(window))
  13.721 +            {
  13.722 +                windows.add(window);
  13.723 +            }
  13.724 +        }
  13.725 +
  13.726 +        for (Window window : windows) {
  13.727 +            AWTAccessor.getWindowAccessor().updateWindow(window);
  13.728 +        }
  13.729 +    }
  13.730 +
  13.731 +    boolean isPainting() {
  13.732 +        return painting;
  13.733 +    }
  13.734 +
  13.735 +    /**
  13.736 +     * Paint all of the components that have been marked dirty.
  13.737 +     *
  13.738 +     * @see #addDirtyRegion
  13.739 +     */
  13.740 +    public void paintDirtyRegions() {
  13.741 +        synchronized(this) {  // swap for thread safety
  13.742 +            Map<Component,Rectangle> tmp = tmpDirtyComponents;
  13.743 +            tmpDirtyComponents = dirtyComponents;
  13.744 +            dirtyComponents = tmp;
  13.745 +            dirtyComponents.clear();
  13.746 +        }
  13.747 +        paintDirtyRegions(tmpDirtyComponents);
  13.748 +    }
  13.749 +
  13.750 +    private void paintDirtyRegions(Map<Component,Rectangle>
  13.751 +                                   tmpDirtyComponents){
  13.752 +        int i, count;
  13.753 +        java.util.List<Component> roots;
  13.754 +        Component dirtyComponent;
  13.755 +
  13.756 +        count = tmpDirtyComponents.size();
  13.757 +        if (count == 0) {
  13.758 +            return;
  13.759 +        }
  13.760 +
  13.761 +        Rectangle rect;
  13.762 +        int localBoundsX = 0;
  13.763 +        int localBoundsY = 0;
  13.764 +        int localBoundsH;
  13.765 +        int localBoundsW;
  13.766 +        Enumeration keys;
  13.767 +
  13.768 +        roots = new ArrayList<Component>(count);
  13.769 +
  13.770 +        for (Component dirty : tmpDirtyComponents.keySet()) {
  13.771 +            collectDirtyComponents(tmpDirtyComponents, dirty, roots);
  13.772 +        }
  13.773 +
  13.774 +        count = roots.size();
  13.775 +        painting = true;
  13.776 +        try {
  13.777 +            for(i=0 ; i < count ; i++) {
  13.778 +                dirtyComponent = roots.get(i);
  13.779 +                rect = tmpDirtyComponents.get(dirtyComponent);
  13.780 +                localBoundsH = dirtyComponent.getHeight();
  13.781 +                localBoundsW = dirtyComponent.getWidth();
  13.782 +
  13.783 +                SwingUtilities.computeIntersection(localBoundsX,
  13.784 +                                                   localBoundsY,
  13.785 +                                                   localBoundsW,
  13.786 +                                                   localBoundsH,
  13.787 +                                                   rect);
  13.788 +                if (dirtyComponent instanceof JComponent) {
  13.789 +                    ((JComponent)dirtyComponent).paintImmediately(
  13.790 +                        rect.x,rect.y,rect.width, rect.height);
  13.791 +                }
  13.792 +                else if (dirtyComponent.isShowing()) {
  13.793 +                    Graphics g = JComponent.safelyGetGraphics(
  13.794 +                            dirtyComponent, dirtyComponent);
  13.795 +                    // If the Graphics goes away, it means someone disposed of
  13.796 +                    // the window, don't do anything.
  13.797 +                    if (g != null) {
  13.798 +                        g.setClip(rect.x, rect.y, rect.width, rect.height);
  13.799 +                        try {
  13.800 +                            dirtyComponent.paint(g);
  13.801 +                        } finally {
  13.802 +                            g.dispose();
  13.803 +                        }
  13.804 +                    }
  13.805 +                }
  13.806 +                // If the repaintRoot has been set, service it now and
  13.807 +                // remove any components that are children of repaintRoot.
  13.808 +                if (repaintRoot != null) {
  13.809 +                    adjustRoots(repaintRoot, roots, i + 1);
  13.810 +                    count = roots.size();
  13.811 +                    paintManager.isRepaintingRoot = true;
  13.812 +                    repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
  13.813 +                                                 repaintRoot.getHeight());
  13.814 +                    paintManager.isRepaintingRoot = false;
  13.815 +                    // Only service repaintRoot once.
  13.816 +                    repaintRoot = null;
  13.817 +                }
  13.818 +            }
  13.819 +        } finally {
  13.820 +            painting = false;
  13.821 +        }
  13.822 +
  13.823 +        updateWindows(tmpDirtyComponents);
  13.824 +
  13.825 +        tmpDirtyComponents.clear();
  13.826 +    }
  13.827 +
  13.828 +
  13.829 +    /**
  13.830 +     * Removes any components from roots that are children of
  13.831 +     * root.
  13.832 +     */
  13.833 +    private void adjustRoots(JComponent root,
  13.834 +                             java.util.List<Component> roots, int index) {
  13.835 +        for (int i = roots.size() - 1; i >= index; i--) {
  13.836 +            Component c = roots.get(i);
  13.837 +            for(;;) {
  13.838 +                if (c == root || c == null || !(c instanceof JComponent)) {
  13.839 +                    break;
  13.840 +                }
  13.841 +                c = c.getParent();
  13.842 +            }
  13.843 +            if (c == root) {
  13.844 +                roots.remove(i);
  13.845 +            }
  13.846 +        }
  13.847 +    }
  13.848 +
  13.849 +    Rectangle tmp = new Rectangle();
  13.850 +
  13.851 +    void collectDirtyComponents(Map<Component,Rectangle> dirtyComponents,
  13.852 +                                Component dirtyComponent,
  13.853 +                                java.util.List<Component> roots) {
  13.854 +        int dx, dy, rootDx, rootDy;
  13.855 +        Component component, rootDirtyComponent,parent;
  13.856 +        Rectangle cBounds;
  13.857 +
  13.858 +        // Find the highest parent which is dirty.  When we get out of this
  13.859 +        // rootDx and rootDy will contain the translation from the
  13.860 +        // rootDirtyComponent's coordinate system to the coordinates of the
  13.861 +        // original dirty component.  The tmp Rect is also used to compute the
  13.862 +        // visible portion of the dirtyRect.
  13.863 +
  13.864 +        component = rootDirtyComponent = dirtyComponent;
  13.865 +
  13.866 +        int x = dirtyComponent.getX();
  13.867 +        int y = dirtyComponent.getY();
  13.868 +        int w = dirtyComponent.getWidth();
  13.869 +        int h = dirtyComponent.getHeight();
  13.870 +
  13.871 +        dx = rootDx = 0;
  13.872 +        dy = rootDy = 0;
  13.873 +        tmp.setBounds(dirtyComponents.get(dirtyComponent));
  13.874 +
  13.875 +        // System.out.println("Collect dirty component for bound " + tmp +
  13.876 +        //                                   "component bounds is " + cBounds);;
  13.877 +        SwingUtilities.computeIntersection(0,0,w,h,tmp);
  13.878 +
  13.879 +        if (tmp.isEmpty()) {
  13.880 +            // System.out.println("Empty 1");
  13.881 +            return;
  13.882 +        }
  13.883 +
  13.884 +        for(;;) {
  13.885 +            if(!(component instanceof JComponent))
  13.886 +                break;
  13.887 +
  13.888 +            parent = component.getParent();
  13.889 +            if(parent == null)
  13.890 +                break;
  13.891 +
  13.892 +            component = parent;
  13.893 +
  13.894 +            dx += x;
  13.895 +            dy += y;
  13.896 +            tmp.setLocation(tmp.x + x, tmp.y + y);
  13.897 +
  13.898 +            x = component.getX();
  13.899 +            y = component.getY();
  13.900 +            w = component.getWidth();
  13.901 +            h = component.getHeight();
  13.902 +            tmp = SwingUtilities.computeIntersection(0,0,w,h,tmp);
  13.903 +
  13.904 +            if (tmp.isEmpty()) {
  13.905 +                // System.out.println("Empty 2");
  13.906 +                return;
  13.907 +            }
  13.908 +
  13.909 +            if (dirtyComponents.get(component) != null) {
  13.910 +                rootDirtyComponent = component;
  13.911 +                rootDx = dx;
  13.912 +                rootDy = dy;
  13.913 +            }
  13.914 +        }
  13.915 +
  13.916 +        if (dirtyComponent != rootDirtyComponent) {
  13.917 +            Rectangle r;
  13.918 +            tmp.setLocation(tmp.x + rootDx - dx,
  13.919 +                            tmp.y + rootDy - dy);
  13.920 +            r = dirtyComponents.get(rootDirtyComponent);
  13.921 +            SwingUtilities.computeUnion(tmp.x,tmp.y,tmp.width,tmp.height,r);
  13.922 +        }
  13.923 +
  13.924 +        // If we haven't seen this root before, then we need to add it to the
  13.925 +        // list of root dirty Views.
  13.926 +
  13.927 +        if (!roots.contains(rootDirtyComponent))
  13.928 +            roots.add(rootDirtyComponent);
  13.929 +    }
  13.930 +
  13.931 +
  13.932 +    /**
  13.933 +     * Returns a string that displays and identifies this
  13.934 +     * object's properties.
  13.935 +     *
  13.936 +     * @return a String representation of this object
  13.937 +     */
  13.938 +    public synchronized String toString() {
  13.939 +        StringBuffer sb = new StringBuffer();
  13.940 +        if(dirtyComponents != null)
  13.941 +            sb.append("" + dirtyComponents);
  13.942 +        return sb.toString();
  13.943 +    }
  13.944 +
  13.945 +
  13.946 +   /**
  13.947 +     * Return the offscreen buffer that should be used as a double buffer with
  13.948 +     * the component <code>c</code>.
  13.949 +     * By default there is a double buffer per RepaintController.
  13.950 +     * The buffer might be smaller than <code>(proposedWidth,proposedHeight)</code>
  13.951 +     * This happens when the maximum double buffer size as been set for the receiving
  13.952 +     * repaint manager.
  13.953 +     */
  13.954 +    public Image getOffscreenBuffer(Component c,int proposedWidth,int proposedHeight) {
  13.955 +        RepaintController delegate = getDelegate(c);
  13.956 +        if (delegate != null) {
  13.957 +            return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight);
  13.958 +        }
  13.959 +        return _getOffscreenBuffer(c, proposedWidth, proposedHeight);
  13.960 +    }
  13.961 +
  13.962 +  /**
  13.963 +   * Return a volatile offscreen buffer that should be used as a
  13.964 +   * double buffer with the specified component <code>c</code>.
  13.965 +   * The image returned will be an instance of VolatileImage, or null
  13.966 +   * if a VolatileImage object could not be instantiated.
  13.967 +   * This buffer might be smaller than <code>(proposedWidth,proposedHeight)</code>.
  13.968 +   * This happens when the maximum double buffer size has been set for this
  13.969 +   * repaint manager.
  13.970 +   *
  13.971 +   * @see java.awt.image.VolatileImage
  13.972 +   * @since 1.4
  13.973 +   */
  13.974 +    public Image getVolatileOffscreenBuffer(Component c,
  13.975 +                                            int proposedWidth,int proposedHeight) {
  13.976 +        RepaintController delegate = getDelegate(c);
  13.977 +        if (delegate != null) {
  13.978 +            return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
  13.979 +                                                        proposedHeight);
  13.980 +        }
  13.981 +
  13.982 +        // If the window is non-opaque, it's double-buffered at peer's level
  13.983 +        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
  13.984 +        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
  13.985 +            Toolkit tk = Toolkit.getDefaultToolkit();
  13.986 +            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
  13.987 +                return null;
  13.988 +            }
  13.989 +        }
  13.990 +
  13.991 +        GraphicsConfiguration config = c.getGraphicsConfiguration();
  13.992 +        if (config == null) {
  13.993 +            config = GraphicsEnvironment.getLocalGraphicsEnvironment().
  13.994 +                            getDefaultScreenDevice().getDefaultConfiguration();
  13.995 +        }
  13.996 +        Dimension maxSize = getDoubleBufferMaximumSize();
  13.997 +        int width = proposedWidth < 1 ? 1 :
  13.998 +            (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
  13.999 +        int height = proposedHeight < 1 ? 1 :
 13.1000 +            (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
 13.1001 +        VolatileImage image = volatileMap.get(config);
 13.1002 +        if (image == null || image.getWidth() < width ||
 13.1003 +                             image.getHeight() < height) {
 13.1004 +            if (image != null) {
 13.1005 +                image.flush();
 13.1006 +            }
 13.1007 +            image = config.createCompatibleVolatileImage(width, height);
 13.1008 +            volatileMap.put(config, image);
 13.1009 +        }
 13.1010 +        return image;
 13.1011 +    }
 13.1012 +
 13.1013 +    private Image _getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
 13.1014 +        Dimension maxSize = getDoubleBufferMaximumSize();
 13.1015 +        DoubleBufferInfo doubleBuffer;
 13.1016 +        int width, height;
 13.1017 +
 13.1018 +        // If the window is non-opaque, it's double-buffered at peer's level
 13.1019 +        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
 13.1020 +        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
 13.1021 +            Toolkit tk = Toolkit.getDefaultToolkit();
 13.1022 +            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
 13.1023 +                return null;
 13.1024 +            }
 13.1025 +        }
 13.1026 +
 13.1027 +        if (standardDoubleBuffer == null) {
 13.1028 +            standardDoubleBuffer = new DoubleBufferInfo();
 13.1029 +        }
 13.1030 +        doubleBuffer = standardDoubleBuffer;
 13.1031 +
 13.1032 +        width = proposedWidth < 1? 1 :
 13.1033 +                  (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
 13.1034 +        height = proposedHeight < 1? 1 :
 13.1035 +                  (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
 13.1036 +
 13.1037 +        if (doubleBuffer.needsReset || (doubleBuffer.image != null &&
 13.1038 +                                        (doubleBuffer.size.width < width ||
 13.1039 +                                         doubleBuffer.size.height < height))) {
 13.1040 +            doubleBuffer.needsReset = false;
 13.1041 +            if (doubleBuffer.image != null) {
 13.1042 +                doubleBuffer.image.flush();
 13.1043 +                doubleBuffer.image = null;
 13.1044 +            }
 13.1045 +            width = Math.max(doubleBuffer.size.width, width);
 13.1046 +            height = Math.max(doubleBuffer.size.height, height);
 13.1047 +        }
 13.1048 +
 13.1049 +        Image result = doubleBuffer.image;
 13.1050 +
 13.1051 +        if (doubleBuffer.image == null) {
 13.1052 +            result = c.createImage(width , height);
 13.1053 +            doubleBuffer.size = new Dimension(width, height);
 13.1054 +            if (c instanceof JComponent) {
 13.1055 +                ((JComponent)c).setCreatedDoubleBuffer(true);
 13.1056 +                doubleBuffer.image = result;
 13.1057 +            }
 13.1058 +            // JComponent will inform us when it is no longer valid
 13.1059 +            // (via removeNotify) we have no such hook to other components,
 13.1060 +            // therefore we don't keep a ref to the Component
 13.1061 +            // (indirectly through the Image) by stashing the image.
 13.1062 +        }
 13.1063 +        return result;
 13.1064 +    }
 13.1065 +
 13.1066 +
 13.1067 +    /** Set the maximum double buffer size. **/
 13.1068 +    public void setDoubleBufferMaximumSize(Dimension d) {
 13.1069 +        doubleBufferMaxSize = d;
 13.1070 +        if (doubleBufferMaxSize == null) {
 13.1071 +            clearImages();
 13.1072 +        } else {
 13.1073 +            clearImages(d.width, d.height);
 13.1074 +        }
 13.1075 +    }
 13.1076 +
 13.1077 +    private void clearImages() {
 13.1078 +        clearImages(0, 0);
 13.1079 +    }
 13.1080 +
 13.1081 +    private void clearImages(int width, int height) {
 13.1082 +        if (standardDoubleBuffer != null && standardDoubleBuffer.image != null) {
 13.1083 +            if (standardDoubleBuffer.image.getWidth(null) > width ||
 13.1084 +                standardDoubleBuffer.image.getHeight(null) > height) {
 13.1085 +                standardDoubleBuffer.image.flush();
 13.1086 +                standardDoubleBuffer.image = null;
 13.1087 +            }
 13.1088 +        }
 13.1089 +        // Clear out the VolatileImages
 13.1090 +        Iterator gcs = volatileMap.keySet().iterator();
 13.1091 +        while (gcs.hasNext()) {
 13.1092 +            GraphicsConfiguration gc = (GraphicsConfiguration)gcs.next();
 13.1093 +            VolatileImage image = volatileMap.get(gc);
 13.1094 +            if (image.getWidth() > width || image.getHeight() > height) {
 13.1095 +                image.flush();
 13.1096 +                gcs.remove();
 13.1097 +            }
 13.1098 +        }
 13.1099 +    }
 13.1100 +
 13.1101 +    /**
 13.1102 +     * Returns the maximum double buffer size.
 13.1103 +     *
 13.1104 +     * @return a Dimension object representing the maximum size
 13.1105 +     */
 13.1106 +    public Dimension getDoubleBufferMaximumSize() {
 13.1107 +        if (doubleBufferMaxSize == null) {
 13.1108 +            try {
 13.1109 +                Rectangle virtualBounds = new Rectangle();
 13.1110 +                GraphicsEnvironment ge = GraphicsEnvironment.
 13.1111 +                                                 getLocalGraphicsEnvironment();
 13.1112 +                for (GraphicsDevice gd : ge.getScreenDevices()) {
 13.1113 +                    GraphicsConfiguration gc = gd.getDefaultConfiguration();
 13.1114 +                    virtualBounds = virtualBounds.union(gc.getBounds());
 13.1115 +                }
 13.1116 +                doubleBufferMaxSize = new Dimension(virtualBounds.width,
 13.1117 +                                                    virtualBounds.height);
 13.1118 +            } catch (HeadlessException e) {
 13.1119 +                doubleBufferMaxSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 13.1120 +            }
 13.1121 +        }
 13.1122 +        return doubleBufferMaxSize;
 13.1123 +    }
 13.1124 +
 13.1125 +    /**
 13.1126 +     * Enables or disables double buffering in this RepaintController.
 13.1127 +     * CAUTION: The default value for this property is set for optimal
 13.1128 +     * paint performance on the given platform and it is not recommended
 13.1129 +     * that programs modify this property directly.
 13.1130 +     *
 13.1131 +     * @param aFlag  true to activate double buffering
 13.1132 +     * @see #isDoubleBufferingEnabled
 13.1133 +     */
 13.1134 +    public void setDoubleBufferingEnabled(boolean aFlag) {
 13.1135 +        doubleBufferingEnabled = aFlag;
 13.1136 +        PaintManager paintManager = getPaintManager();
 13.1137 +        if (!aFlag && paintManager.getClass() != PaintManager.class) {
 13.1138 +            setPaintManager(new PaintManager());
 13.1139 +        }
 13.1140 +    }
 13.1141 +
 13.1142 +    /**
 13.1143 +     * Returns true if this RepaintController is double buffered.
 13.1144 +     * The default value for this property may vary from platform
 13.1145 +     * to platform.  On platforms where native double buffering
 13.1146 +     * is supported in the AWT, the default value will be <code>false</code>
 13.1147 +     * to avoid unnecessary buffering in Swing.
 13.1148 +     * On platforms where native double buffering is not supported,
 13.1149 +     * the default value will be <code>true</code>.
 13.1150 +     *
 13.1151 +     * @return true if this object is double buffered
 13.1152 +     */
 13.1153 +    public boolean isDoubleBufferingEnabled() {
 13.1154 +        return doubleBufferingEnabled;
 13.1155 +    }
 13.1156 +
 13.1157 +    /**
 13.1158 +     * This resets the double buffer. Actually, it marks the double buffer
 13.1159 +     * as invalid, the double buffer will then be recreated on the next
 13.1160 +     * invocation of getOffscreenBuffer.
 13.1161 +     */
 13.1162 +    void resetDoubleBuffer() {
 13.1163 +        if (standardDoubleBuffer != null) {
 13.1164 +            standardDoubleBuffer.needsReset = true;
 13.1165 +        }
 13.1166 +    }
 13.1167 +
 13.1168 +    /**
 13.1169 +     * This resets the volatile double buffer.
 13.1170 +     */
 13.1171 +    void resetVolatileDoubleBuffer(GraphicsConfiguration gc) {
 13.1172 +        Image image = volatileMap.remove(gc);
 13.1173 +        if (image != null) {
 13.1174 +            image.flush();
 13.1175 +        }
 13.1176 +    }
 13.1177 +
 13.1178 +    /**
 13.1179 +     * Returns true if we should use the <code>Image</code> returned
 13.1180 +     * from <code>getVolatileOffscreenBuffer</code> to do double buffering.
 13.1181 +     */
 13.1182 +    boolean useVolatileDoubleBuffer() {
 13.1183 +        return volatileImageBufferEnabled;
 13.1184 +    }
 13.1185 +
 13.1186 +    /**
 13.1187 +     * Returns true if the current thread is the thread painting.  This
 13.1188 +     * will return false if no threads are painting.
 13.1189 +     */
 13.1190 +    private synchronized boolean isPaintingThread() {
 13.1191 +        return (Thread.currentThread() == paintThread);
 13.1192 +    }
 13.1193 +    //
 13.1194 +    // Paint methods.  You very, VERY rarely need to invoke these.
 13.1195 +    // They are invoked directly from JComponent's painting code and
 13.1196 +    // when painting happens outside the normal flow: DefaultDesktopManager
 13.1197 +    // and JViewport.  If you end up needing these methods in other places be
 13.1198 +    // careful that you don't get stuck in a paint loop.
 13.1199 +    //
 13.1200 +
 13.1201 +    /**
 13.1202 +     * Paints a region of a component
 13.1203 +     *
 13.1204 +     * @param paintingComponent Component to paint
 13.1205 +     * @param bufferComponent Component to obtain buffer for
 13.1206 +     * @param g Graphics to paint to
 13.1207 +     * @param x X-coordinate
 13.1208 +     * @param y Y-coordinate
 13.1209 +     * @param w Width
 13.1210 +     * @param h Height
 13.1211 +     */
 13.1212 +    void paint(JComponent paintingComponent,
 13.1213 +               JComponent bufferComponent, Graphics g,
 13.1214 +               int x, int y, int w, int h) {
 13.1215 +        PaintManager paintManager = getPaintManager();
 13.1216 +        if (!isPaintingThread()) {
 13.1217 +            // We're painting to two threads at once.  PaintManager deals
 13.1218 +            // with this a bit better than BufferStrategyPaintManager, use
 13.1219 +            // it to avoid possible exceptions/corruption.
 13.1220 +            if (paintManager.getClass() != PaintManager.class) {
 13.1221 +                paintManager = new PaintManager();
 13.1222 +                paintManager.RepaintController = this;
 13.1223 +            }
 13.1224 +        }
 13.1225 +        if (!paintManager.paint(paintingComponent, bufferComponent, g,
 13.1226 +                                x, y, w, h)) {
 13.1227 +            g.setClip(x, y, w, h);
 13.1228 +            paintingComponent.paintToOffscreen(g, x, y, w, h, x + w, y + h);
 13.1229 +        }
 13.1230 +    }
 13.1231 +
 13.1232 +    /**
 13.1233 +     * Does a copy area on the specified region.
 13.1234 +     *
 13.1235 +     * @param clip Whether or not the copyArea needs to be clipped to the
 13.1236 +     *             Component's bounds.
 13.1237 +     */
 13.1238 +    void copyArea(JComponent c, Graphics g, int x, int y, int w, int h,
 13.1239 +                  int deltaX, int deltaY, boolean clip) {
 13.1240 +        getPaintManager().copyArea(c, g, x, y, w, h, deltaX, deltaY, clip);
 13.1241 +    }
 13.1242 +
 13.1243 +    /**
 13.1244 +     * Invoked prior to any paint/copyArea method calls.  This will
 13.1245 +     * be followed by an invocation of <code>endPaint</code>.
 13.1246 +     * <b>WARNING</b>: Callers of this method need to wrap the call
 13.1247 +     * in a <code>try/finally</code>, otherwise if an exception is thrown
 13.1248 +     * during the course of painting the RepaintController may
 13.1249 +     * be left in a state in which the screen is not updated, eg:
 13.1250 +     * <pre>
 13.1251 +     * RepaintController.beginPaint();
 13.1252 +     * try {
 13.1253 +     *   RepaintController.paint(...);
 13.1254 +     * } finally {
 13.1255 +     *   RepaintController.endPaint();
 13.1256 +     * }
 13.1257 +     * </pre>
 13.1258 +     */
 13.1259 +    void beginPaint() {
 13.1260 +        boolean multiThreadedPaint = false;
 13.1261 +        int paintDepth;
 13.1262 +        Thread currentThread = Thread.currentThread();
 13.1263 +        synchronized(this) {
 13.1264 +            paintDepth = this.paintDepth;
 13.1265 +            if (paintThread == null || currentThread == paintThread) {
 13.1266 +                paintThread = currentThread;
 13.1267 +                this.paintDepth++;
 13.1268 +            } else {
 13.1269 +                multiThreadedPaint = true;
 13.1270 +            }
 13.1271 +        }
 13.1272 +        if (!multiThreadedPaint && paintDepth == 0) {
 13.1273 +            getPaintManager().beginPaint();
 13.1274 +        }
 13.1275 +    }
 13.1276 +
 13.1277 +    /**
 13.1278 +     * Invoked after <code>beginPaint</code> has been invoked.
 13.1279 +     */
 13.1280 +    void endPaint() {
 13.1281 +        if (isPaintingThread()) {
 13.1282 +            PaintManager paintManager = null;
 13.1283 +            synchronized(this) {
 13.1284 +                if (--paintDepth == 0) {
 13.1285 +                    paintManager = getPaintManager();
 13.1286 +                }
 13.1287 +            }
 13.1288 +            if (paintManager != null) {
 13.1289 +                paintManager.endPaint();
 13.1290 +                synchronized(this) {
 13.1291 +                    paintThread = null;
 13.1292 +                }
 13.1293 +            }
 13.1294 +        }
 13.1295 +    }
 13.1296 +
 13.1297 +    /**
 13.1298 +     * If possible this will show a previously rendered portion of
 13.1299 +     * a Component.  If successful, this will return true, otherwise false.
 13.1300 +     * <p>
 13.1301 +     * WARNING: This method is invoked from the native toolkit thread, be
 13.1302 +     * very careful as to what methods this invokes!
 13.1303 +     */
 13.1304 +    boolean show(Container c, int x, int y, int w, int h) {
 13.1305 +        return getPaintManager().show(c, x, y, w, h);
 13.1306 +    }
 13.1307 +
 13.1308 +    /**
 13.1309 +     * Invoked when the doubleBuffered or useTrueDoubleBuffering
 13.1310 +     * properties of a JRootPane change.  This may come in on any thread.
 13.1311 +     */
 13.1312 +    void doubleBufferingChanged(JRootPane rootPane) {
 13.1313 +        getPaintManager().doubleBufferingChanged(rootPane);
 13.1314 +    }
 13.1315 +
 13.1316 +    /**
 13.1317 +     * Sets the <code>PaintManager</code> that is used to handle all
 13.1318 +     * double buffered painting.
 13.1319 +     *
 13.1320 +     * @param paintManager The PaintManager to use.  Passing in null indicates
 13.1321 +     *        the fallback PaintManager should be used.
 13.1322 +     */
 13.1323 +    void setPaintManager(PaintManager paintManager) {
 13.1324 +        if (paintManager == null) {
 13.1325 +            paintManager = new PaintManager();
 13.1326 +        }
 13.1327 +        PaintManager oldPaintManager;
 13.1328 +        synchronized(this) {
 13.1329 +            oldPaintManager = this.paintManager;
 13.1330 +            this.paintManager = paintManager;
 13.1331 +            paintManager.RepaintController = this;
 13.1332 +        }
 13.1333 +        if (oldPaintManager != null) {
 13.1334 +            oldPaintManager.dispose();
 13.1335 +        }
 13.1336 +    }
 13.1337 +
 13.1338 +    private synchronized PaintManager getPaintManager() {
 13.1339 +        if (paintManager == null) {
 13.1340 +            PaintManager paintManager = null;
 13.1341 +            if (doubleBufferingEnabled && !nativeDoubleBuffering) {
 13.1342 +                switch (bufferStrategyType) {
 13.1343 +                case BUFFER_STRATEGY_NOT_SPECIFIED:
 13.1344 +                    Toolkit tk = Toolkit.getDefaultToolkit();
 13.1345 +                    if (tk instanceof SunToolkit) {
 13.1346 +                        SunToolkit stk = (SunToolkit) tk;
 13.1347 +                        if (stk.useBufferPerWindow()) {
 13.1348 +                            paintManager = new BufferStrategyPaintManager();
 13.1349 +                        }
 13.1350 +                    }
 13.1351 +                    break;
 13.1352 +                case BUFFER_STRATEGY_SPECIFIED_ON:
 13.1353 +                    paintManager = new BufferStrategyPaintManager();
 13.1354 +                    break;
 13.1355 +                default:
 13.1356 +                    break;
 13.1357 +                }
 13.1358 +            }
 13.1359 +            // null case handled in setPaintManager
 13.1360 +            setPaintManager(paintManager);
 13.1361 +        }
 13.1362 +        return paintManager;
 13.1363 +    }
 13.1364 +
 13.1365 +    private void scheduleProcessingRunnable() {
 13.1366 +        scheduleProcessingRunnable(AppContext.getAppContext());
 13.1367 +    }
 13.1368 +
 13.1369 +    private void scheduleProcessingRunnable(AppContext context) {
 13.1370 +        if (processingRunnable.markPending()) {
 13.1371 +            Toolkit tk = Toolkit.getDefaultToolkit();
 13.1372 +            if (tk instanceof SunToolkit) {
 13.1373 +                SunToolkit.getSystemEventQueueImplPP(context).
 13.1374 +                  postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
 13.1375 +                                                processingRunnable));
 13.1376 +            } else {
 13.1377 +                Toolkit.getDefaultToolkit().getSystemEventQueue().
 13.1378 +                      postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
 13.1379 +                                                    processingRunnable));
 13.1380 +            }
 13.1381 +        }
 13.1382 +    }
 13.1383 +
 13.1384 +
 13.1385 +    /**
 13.1386 +     * PaintManager is used to handle all double buffered painting for
 13.1387 +     * Swing.  Subclasses should call back into the JComponent method
 13.1388 +     * <code>paintToOffscreen</code> to handle the actual painting.
 13.1389 +     */
 13.1390 +    static class PaintManager {
 13.1391 +        /**
 13.1392 +         * RepaintController the PaintManager has been installed on.
 13.1393 +         */
 13.1394 +        protected RepaintController RepaintController;
 13.1395 +        boolean isRepaintingRoot;
 13.1396 +
 13.1397 +        /**
 13.1398 +         * Paints a region of a component
 13.1399 +         *
 13.1400 +         * @param paintingComponent Component to paint
 13.1401 +         * @param bufferComponent Component to obtain buffer for
 13.1402 +         * @param g Graphics to paint to
 13.1403 +         * @param x X-coordinate
 13.1404 +         * @param y Y-coordinate
 13.1405 +         * @param w Width
 13.1406 +         * @param h Height
 13.1407 +         * @return true if painting was successful.
 13.1408 +         */
 13.1409 +        public boolean paint(JComponent paintingComponent,
 13.1410 +                             JComponent bufferComponent, Graphics g,
 13.1411 +                             int x, int y, int w, int h) {
 13.1412 +            // First attempt to use VolatileImage buffer for performance.
 13.1413 +            // If this fails (which should rarely occur), fallback to a
 13.1414 +            // standard Image buffer.
 13.1415 +            boolean paintCompleted = false;
 13.1416 +            Image offscreen;
 13.1417 +            if (RepaintController.useVolatileDoubleBuffer() &&
 13.1418 +                (offscreen = getValidImage(RepaintController.
 13.1419 +                getVolatileOffscreenBuffer(bufferComponent, w, h))) != null) {
 13.1420 +                VolatileImage vImage = (java.awt.image.VolatileImage)offscreen;
 13.1421 +                GraphicsConfiguration gc = bufferComponent.
 13.1422 +                                            getGraphicsConfiguration();
 13.1423 +                for (int i = 0; !paintCompleted &&
 13.1424 +                         i < RepaintController.VOLATILE_LOOP_MAX; i++) {
 13.1425 +                    if (vImage.validate(gc) ==
 13.1426 +                                   VolatileImage.IMAGE_INCOMPATIBLE) {
 13.1427 +                        RepaintController.resetVolatileDoubleBuffer(gc);
 13.1428 +                        offscreen = RepaintController.getVolatileOffscreenBuffer(
 13.1429 +                            bufferComponent,w, h);
 13.1430 +                        vImage = (java.awt.image.VolatileImage)offscreen;
 13.1431 +                    }
 13.1432 +                    paintDoubleBuffered(paintingComponent, vImage, g, x, y,
 13.1433 +                                        w, h);
 13.1434 +                    paintCompleted = !vImage.contentsLost();
 13.1435 +                }
 13.1436 +            }
 13.1437 +            // VolatileImage painting loop failed, fallback to regular
 13.1438 +            // offscreen buffer
 13.1439 +            if (!paintCompleted && (offscreen = getValidImage(
 13.1440 +                      RepaintController.getOffscreenBuffer(
 13.1441 +                      bufferComponent, w, h))) != null) {
 13.1442 +                paintDoubleBuffered(paintingComponent, offscreen, g, x, y, w,
 13.1443 +                                    h);
 13.1444 +                paintCompleted = true;
 13.1445 +            }
 13.1446 +            return paintCompleted;
 13.1447 +        }
 13.1448 +
 13.1449 +        /**
 13.1450 +         * Does a copy area on the specified region.
 13.1451 +         */
 13.1452 +        public void copyArea(JComponent c, Graphics g, int x, int y, int w,
 13.1453 +                             int h, int deltaX, int deltaY, boolean clip) {
 13.1454 +            g.copyArea(x, y, w, h, deltaX, deltaY);
 13.1455 +        }
 13.1456 +
 13.1457 +        /**
 13.1458 +         * Invoked prior to any calls to paint or copyArea.
 13.1459 +         */
 13.1460 +        public void beginPaint() {
 13.1461 +        }
 13.1462 +
 13.1463 +        /**
 13.1464 +         * Invoked to indicate painting has been completed.
 13.1465 +         */
 13.1466 +        public void endPaint() {
 13.1467 +        }
 13.1468 +
 13.1469 +        /**
 13.1470 +         * Shows a region of a previously rendered component.  This
 13.1471 +         * will return true if successful, false otherwise.  The default
 13.1472 +         * implementation returns false.
 13.1473 +         */
 13.1474 +        public boolean show(Container c, int x, int y, int w, int h) {
 13.1475 +            return false;
 13.1476 +        }
 13.1477 +
 13.1478 +        /**
 13.1479 +         * Invoked when the doubleBuffered or useTrueDoubleBuffering
 13.1480 +         * properties of a JRootPane change.  This may come in on any thread.
 13.1481 +         */
 13.1482 +        public void doubleBufferingChanged(JRootPane rootPane) {
 13.1483 +        }
 13.1484 +
 13.1485 +        /**
 13.1486 +         * Paints a portion of a component to an offscreen buffer.
 13.1487 +         */
 13.1488 +        protected void paintDoubleBuffered(JComponent c, Image image,
 13.1489 +                            Graphics g, int clipX, int clipY,
 13.1490 +                            int clipW, int clipH) {
 13.1491 +            Graphics osg = image.getGraphics();
 13.1492 +            int bw = Math.min(clipW, image.getWidth(null));
 13.1493 +            int bh = Math.min(clipH, image.getHeight(null));
 13.1494 +            int x,y,maxx,maxy;
 13.1495 +
 13.1496 +            try {
 13.1497 +                for(x = clipX, maxx = clipX+clipW; x < maxx ;  x += bw ) {
 13.1498 +                    for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
 13.1499 +                        osg.translate(-x, -y);
 13.1500 +                        osg.setClip(x,y,bw,bh);
 13.1501 +                        c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
 13.1502 +                        g.setClip(x, y, bw, bh);
 13.1503 +                        g.drawImage(image, x, y, c);
 13.1504 +                        osg.translate(x, y);
 13.1505 +                    }
 13.1506 +                }
 13.1507 +            } finally {
 13.1508 +                osg.dispose();
 13.1509 +            }
 13.1510 +        }
 13.1511 +
 13.1512 +        /**
 13.1513 +         * If <code>image</code> is non-null with a positive size it
 13.1514 +         * is returned, otherwise null is returned.
 13.1515 +         */
 13.1516 +        private Image getValidImage(Image image) {
 13.1517 +            if (image != null && image.getWidth(null) > 0 &&
 13.1518 +                                 image.getHeight(null) > 0) {
 13.1519 +                return image;
 13.1520 +            }
 13.1521 +            return null;
 13.1522 +        }
 13.1523 +
 13.1524 +        /**
 13.1525 +         * Schedules a repaint for the specified component.  This differs
 13.1526 +         * from <code>root.repaint</code> in that if the RepaintController is
 13.1527 +         * currently processing paint requests it'll process this request
 13.1528 +         * with the current set of requests.
 13.1529 +         */
 13.1530 +        protected void repaintRoot(JComponent root) {
 13.1531 +            assert (RepaintController.repaintRoot == null);
 13.1532 +            if (RepaintController.painting) {
 13.1533 +                RepaintController.repaintRoot = root;
 13.1534 +            }
 13.1535 +            else {
 13.1536 +                root.repaint();
 13.1537 +            }
 13.1538 +        }
 13.1539 +
 13.1540 +        /**
 13.1541 +         * Returns true if the component being painted is the root component
 13.1542 +         * that was previously passed to <code>repaintRoot</code>.
 13.1543 +         */
 13.1544 +        protected boolean isRepaintingRoot() {
 13.1545 +            return isRepaintingRoot;
 13.1546 +        }
 13.1547 +
 13.1548 +        /**
 13.1549 +         * Cleans up any state.  After invoked the PaintManager will no
 13.1550 +         * longer be used anymore.
 13.1551 +         */
 13.1552 +        protected void dispose() {
 13.1553 +        }
 13.1554 +    }
 13.1555 +
 13.1556 +
 13.1557 +    private class DoubleBufferInfo {
 13.1558 +        public Image image;
 13.1559 +        public Dimension size;
 13.1560 +        public boolean needsReset = false;
 13.1561 +    }
 13.1562 +
 13.1563 +
 13.1564 +    /**
 13.1565 +     * Listener installed to detect display changes. When display changes,
 13.1566 +     * schedules a callback to notify all RepaintControllers of the display
 13.1567 +     * changes. Only one DisplayChangedHandler is ever installed. The
 13.1568 +     * singleton instance will schedule notification for all AppContexts.
 13.1569 +     */
 13.1570 +    private static final class DisplayChangedHandler implements
 13.1571 +                                             DisplayChangedListener {
 13.1572 +        public void displayChanged() {
 13.1573 +            scheduleDisplayChanges();
 13.1574 +        }
 13.1575 +
 13.1576 +        public void paletteChanged() {
 13.1577 +        }
 13.1578 +
 13.1579 +        private void scheduleDisplayChanges() {
 13.1580 +            // To avoid threading problems, we notify each RepaintController
 13.1581 +            // on the thread it was created on.
 13.1582 +            for (Object c : AppContext.getAppContexts()) {
 13.1583 +                AppContext context = (AppContext) c;
 13.1584 +                synchronized(context) {
 13.1585 +                    if (!context.isDisposed()) {
 13.1586 +                        EventQueue eventQueue = (EventQueue)context.get(
 13.1587 +                            AppContext.EVENT_QUEUE_KEY);
 13.1588 +                        if (eventQueue != null) {
 13.1589 +                            eventQueue.postEvent(new InvocationEvent(
 13.1590 +                                Toolkit.getDefaultToolkit(),
 13.1591 +                                new DisplayChangedRunnable()));
 13.1592 +                        }
 13.1593 +                    }
 13.1594 +                }
 13.1595 +            }
 13.1596 +        }
 13.1597 +    }
 13.1598 +
 13.1599 +
 13.1600 +    private static final class DisplayChangedRunnable implements Runnable {
 13.1601 +        public void run() {
 13.1602 +            RepaintController.currentManager((JComponent)null).displayChanged();
 13.1603 +        }
 13.1604 +    }
 13.1605 +
 13.1606 +
 13.1607 +    /**
 13.1608 +     * Runnable used to process all repaint/revalidate requests.
 13.1609 +     */
 13.1610 +    private final class ProcessingRunnable implements Runnable {
 13.1611 +        // If true, we're wainting on the EventQueue.
 13.1612 +        private boolean pending;
 13.1613 +
 13.1614 +        /**
 13.1615 +         * Marks this processing runnable as pending. If this was not
 13.1616 +         * already marked as pending, true is returned.
 13.1617 +         */
 13.1618 +        public synchronized boolean markPending() {
 13.1619 +            if (!pending) {
 13.1620 +                pending = true;
 13.1621 +                return true;
 13.1622 +            }
 13.1623 +            return false;
 13.1624 +        }
 13.1625 +
 13.1626 +        public void run() {
 13.1627 +            synchronized (this) {
 13.1628 +                pending = false;
 13.1629 +            }
 13.1630 +            // First pass, flush any heavy paint events into real paint
 13.1631 +            // events.  If there are pending heavy weight requests this will
 13.1632 +            // result in q'ing this request up one more time.  As
 13.1633 +            // long as no other requests come in between now and the time
 13.1634 +            // the second one is processed nothing will happen.  This is not
 13.1635 +            // ideal, but the logic needed to suppress the second request is
 13.1636 +            // more headache than it's worth.
 13.1637 +            scheduleHeavyWeightPaints();
 13.1638 +            // Do the actual validation and painting.
 13.1639 +            validateInvalidComponents();
 13.1640 +            prePaintDirtyRegions();
 13.1641 +        }
 13.1642 +    }
 13.1643 +    private RepaintController getDelegate(Component c) {
 13.1644 +        RepaintController delegate = SwingUtilities3.getDelegateRepaintController(c);
 13.1645 +        if (this == delegate) {
 13.1646 +            delegate = null;
 13.1647 +        }
 13.1648 +        return delegate;
 13.1649 +    }
 13.1650 +}
    14.1 --- a/src/share/classes/javax/swing/RepaintManager.java	Fri Jun 19 21:46:14 2009 +0200
    14.2 +++ b/src/share/classes/javax/swing/RepaintManager.java	Sat Jun 20 22:10:34 2009 +0200
    14.3 @@ -27,13 +27,13 @@
    14.4  
    14.5  import java.awt.*;
    14.6  import java.awt.event.*;
    14.7 -import java.awt.peer.ComponentPeer;
    14.8 -import java.awt.peer.ContainerPeer;
    14.9  import java.awt.image.VolatileImage;
   14.10  import java.security.AccessController;
   14.11  import java.util.*;
   14.12  import java.applet.*;
   14.13  
   14.14 +import javax.swing.RepaintController.PaintManager;
   14.15 +
   14.16  import sun.awt.AWTAccessor;
   14.17  import sun.awt.AppContext;
   14.18  import sun.awt.DisplayChangedListener;
   14.19 @@ -56,155 +56,24 @@
   14.20   * appropriate <code>addDirtyRegion</code> method.
   14.21   *
   14.22   * @author Arnaud Weber
   14.23 + * @deprecated Use RepaintController
   14.24   */
   14.25 +@Deprecated
   14.26  public class RepaintManager
   14.27  {
   14.28 -    /**
   14.29 -     * Whether or not the RepaintManager should handle paint requests
   14.30 -     * for top levels.
   14.31 -     */
   14.32 -    static final boolean HANDLE_TOP_LEVEL_PAINT;
   14.33 -
   14.34 -    private static final short BUFFER_STRATEGY_NOT_SPECIFIED = 0;
   14.35 -    private static final short BUFFER_STRATEGY_SPECIFIED_ON = 1;
   14.36 -    private static final short BUFFER_STRATEGY_SPECIFIED_OFF = 2;
   14.37 -
   14.38 -    private static final short BUFFER_STRATEGY_TYPE;
   14.39 -
   14.40 -    /**
   14.41 -     * Maps from GraphicsConfiguration to VolatileImage.
   14.42 -     */
   14.43 -    private Map<GraphicsConfiguration,VolatileImage> volatileMap = new
   14.44 -                        HashMap<GraphicsConfiguration,VolatileImage>(1);
   14.45 -
   14.46 +    // JST-XXX:
   14.47 +    // Deprecation note: One possibility is to subclass RepaintController,
   14.48 +    // other delegate. This code delegates, but it is yet to be seen what
   14.49 +    // is simpler and more compatible.
   14.50      //
   14.51 -    // As of 1.6 Swing handles scheduling of paint events from native code.
   14.52 -    // That is, SwingPaintEventDispatcher is invoked on the toolkit thread,
   14.53 -    // which in turn invokes nativeAddDirtyRegion.  Because this is invoked
   14.54 -    // from the native thread we can not invoke any public methods and so
   14.55 -    // we introduce these added maps.  So, any time nativeAddDirtyRegion is
   14.56 -    // invoked the region is added to hwDirtyComponents and a work request
   14.57 -    // is scheduled.  When the work request is processed all entries in
   14.58 -    // this map are pushed to the real map (dirtyComponents) and then
   14.59 -    // painted with the rest of the components.
   14.60 -    //
   14.61 -    private Map<Container,Rectangle> hwDirtyComponents;
   14.62 -
   14.63 -    private Map<Component,Rectangle> dirtyComponents;
   14.64 -    private Map<Component,Rectangle> tmpDirtyComponents;
   14.65 -    private java.util.List<Component> invalidComponents;
   14.66 -
   14.67 -    // List of Runnables that need to be processed before painting from AWT.
   14.68 -    private java.util.List<Runnable> runnableList;
   14.69 -
   14.70 -    boolean   doubleBufferingEnabled = true;
   14.71 -
   14.72 -    private Dimension doubleBufferMaxSize;
   14.73 -
   14.74 -    // Support for both the standard and volatile offscreen buffers exists to
   14.75 -    // provide backwards compatibility for the [rare] programs which may be
   14.76 -    // calling getOffScreenBuffer() and not expecting to get a VolatileImage.
   14.77 -    // Swing internally is migrating to use *only* the volatile image buffer.
   14.78 -
   14.79 -    // Support for standard offscreen buffer
   14.80 -    //
   14.81 -    DoubleBufferInfo standardDoubleBuffer;
   14.82 -
   14.83 -    /**
   14.84 -     * Object responsible for hanlding core paint functionality.
   14.85 -     */
   14.86 -    private PaintManager paintManager;
   14.87  
   14.88      private static final Object repaintManagerKey = RepaintManager.class;
   14.89 -
   14.90 -    // Whether or not a VolatileImage should be used for double-buffered painting
   14.91 -    static boolean volatileImageBufferEnabled = true;
   14.92 -    /**
   14.93 -     * Value of the system property awt.nativeDoubleBuffering.
   14.94 -     */
   14.95 -    private static boolean nativeDoubleBuffering;
   14.96 -
   14.97 -    // The maximum number of times Swing will attempt to use the VolatileImage
   14.98 -    // buffer during a paint operation.
   14.99 -    private static final int VOLATILE_LOOP_MAX = 2;
  14.100 -
  14.101 -    /**
  14.102 -     * Number of <code>beginPaint</code> that have been invoked.
  14.103 -     */
  14.104 -    private int paintDepth = 0;
  14.105 -
  14.106 -    /**
  14.107 -     * Type of buffer strategy to use.  Will be one of the BUFFER_STRATEGY_
  14.108 -     * constants.
  14.109 -     */
  14.110 -    private short bufferStrategyType;
  14.111 -
  14.112 -    //
  14.113 -    // BufferStrategyPaintManager has the unique characteristic that it
  14.114 -    // must deal with the buffer being lost while painting to it.  For
  14.115 -    // example, if we paint a component and show it and the buffer has
  14.116 -    // become lost we must repaint the whole window.  To deal with that
  14.117 -    // the PaintManager calls into repaintRoot, and if we're still in
  14.118 -    // the process of painting the repaintRoot field is set to the JRootPane
  14.119 -    // and after the current JComponent.paintImmediately call finishes
  14.120 -    // paintImmediately will be invoked on the repaintRoot.  In this
  14.121 -    // way we don't try to show garbage to the screen.
  14.122 -    //
  14.123 -    /**
  14.124 -     * True if we're in the process of painting the dirty regions.  This is
  14.125 -     * set to true in <code>paintDirtyRegions</code>.
  14.126 -     */
  14.127 -    private boolean painting;
  14.128 -    /**
  14.129 -     * If the PaintManager calls into repaintRoot during painting this field
  14.130 -     * will be set to the root.
  14.131 -     */
  14.132 -    private JComponent repaintRoot;
  14.133 -
  14.134 -    /**
  14.135 -     * The Thread that has initiated painting.  If null it
  14.136 -     * indicates painting is not currently in progress.
  14.137 -     */
  14.138 -    private Thread paintThread;
  14.139 -
  14.140 -    /**
  14.141 -     * Runnable used to process all repaint/revalidate requests.
  14.142 -     */
  14.143 -    private final ProcessingRunnable processingRunnable;
  14.144 -
  14.145 -
  14.146 -    static {
  14.147 -        volatileImageBufferEnabled = "true".equals(AccessController.
  14.148 -                doPrivileged(new GetPropertyAction(
  14.149 -                "swing.volatileImageBufferEnabled", "true")));
  14.150 -        boolean headless = GraphicsEnvironment.isHeadless();
  14.151 -        if (volatileImageBufferEnabled && headless) {
  14.152 -            volatileImageBufferEnabled = false;
  14.153 -        }
  14.154 -        nativeDoubleBuffering = "true".equals(AccessController.doPrivileged(
  14.155 -                    new GetPropertyAction("awt.nativeDoubleBuffering")));
  14.156 -        String bs = AccessController.doPrivileged(
  14.157 -                          new GetPropertyAction("swing.bufferPerWindow"));
  14.158 -        if (headless) {
  14.159 -            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
  14.160 -        }
  14.161 -        else if (bs == null) {
  14.162 -            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_NOT_SPECIFIED;
  14.163 -        }
  14.164 -        else if ("true".equals(bs)) {
  14.165 -            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_ON;
  14.166 -        }
  14.167 -        else {
  14.168 -            BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
  14.169 -        }
  14.170 -        HANDLE_TOP_LEVEL_PAINT = "true".equals(AccessController.doPrivileged(
  14.171 -               new GetPropertyAction("swing.handleTopLevelPaint", "true")));
  14.172 -        GraphicsEnvironment ge = GraphicsEnvironment.
  14.173 -                getLocalGraphicsEnvironment();
  14.174 -        if (ge instanceof SunGraphicsEnvironment) {
  14.175 -            ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
  14.176 -                    new DisplayChangedHandler());
  14.177 -        }
  14.178 +    private final RepaintController delegate;
  14.179 +    public RepaintManager() {
  14.180 +        this(new RepaintController());
  14.181 +    }
  14.182 +    private RepaintManager(RepaintController rc) {
  14.183 +        this.delegate = rc;
  14.184      }
  14.185  
  14.186      /**
  14.187 @@ -229,12 +98,7 @@
  14.188       * AppContext this will return null.
  14.189       */
  14.190      static RepaintManager currentManager(AppContext appContext) {
  14.191 -        RepaintManager rm = (RepaintManager)appContext.get(repaintManagerKey);
  14.192 -        if (rm == null) {
  14.193 -            rm = new RepaintManager(BUFFER_STRATEGY_TYPE);
  14.194 -            appContext.put(repaintManagerKey, rm);
  14.195 -        }
  14.196 -        return rm;
  14.197 +        return new RepaintManager(RepaintController.currentManager(appContext));
  14.198      }
  14.199  
  14.200      /**
  14.201 @@ -259,6 +123,7 @@
  14.202       * @param aRepaintManager  the RepaintManager object to use
  14.203       */
  14.204      public static void setCurrentManager(RepaintManager aRepaintManager) {
  14.205 +        // JST-XXX: Not fully correct.
  14.206          if (aRepaintManager != null) {
  14.207              SwingUtilities.appContextPut(repaintManagerKey, aRepaintManager);
  14.208          } else {
  14.209 @@ -267,36 +132,6 @@
  14.210      }
  14.211  
  14.212      /**
  14.213 -     * Create a new RepaintManager instance. You rarely call this constructor.
  14.214 -     * directly. To get the default RepaintManager, use
  14.215 -     * RepaintManager.currentManager(JComponent) (normally "this").
  14.216 -     */
  14.217 -    public RepaintManager() {
  14.218 -        // Because we can't know what a subclass is doing with the
  14.219 -        // volatile image we immediately punt in subclasses.  If this
  14.220 -        // poses a problem we'll need a more sophisticated detection algorithm,
  14.221 -        // or API.
  14.222 -        this(BUFFER_STRATEGY_SPECIFIED_OFF);
  14.223 -    }
  14.224 -
  14.225 -    private RepaintManager(short bufferStrategyType) {
  14.226 -        // If native doublebuffering is being used, do NOT use
  14.227 -        // Swing doublebuffering.
  14.228 -        doubleBufferingEnabled = !nativeDoubleBuffering;
  14.229 -        synchronized(this) {
  14.230 -            dirtyComponents = new IdentityHashMap<Component,Rectangle>();
  14.231 -            tmpDirtyComponents = new IdentityHashMap<Component,Rectangle>();
  14.232 -            this.bufferStrategyType = bufferStrategyType;
  14.233 -            hwDirtyComponents = new IdentityHashMap<Container,Rectangle>();
  14.234 -        }
  14.235 -        processingRunnable = new ProcessingRunnable();
  14.236 -    }
  14.237 -
  14.238 -    private void displayChanged() {
  14.239 -        clearImages();
  14.240 -    }
  14.241 -
  14.242 -    /**
  14.243       * Mark the component as in need of layout and queue a runnable
  14.244       * for the event dispatching thread that will validate the components
  14.245       * first isValidateRoot() ancestor.
  14.246 @@ -304,163 +139,18 @@
  14.247       * @see JComponent#isValidateRoot
  14.248       * @see #removeInvalidComponent
  14.249       */
  14.250 -    public synchronized void addInvalidComponent(JComponent invalidComponent)
  14.251 +    public void addInvalidComponent(JComponent invalidComponent)
  14.252      {
  14.253 -        RepaintManager delegate = getDelegate(invalidComponent);
  14.254 -        if (delegate != null) {
  14.255 -            delegate.addInvalidComponent(invalidComponent);
  14.256 -            return;
  14.257 -        }
  14.258 -        Component validateRoot = null;
  14.259 -
  14.260 -        /* Find the first JComponent ancestor of this component whose
  14.261 -         * isValidateRoot() method returns true.
  14.262 -         */
  14.263 -        for(Component c = invalidComponent; c != null; c = c.getParent()) {
  14.264 -            if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
  14.265 -                return;
  14.266 -            }
  14.267 -            if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
  14.268 -                validateRoot = c;
  14.269 -                break;
  14.270 -            }
  14.271 -        }
  14.272 -
  14.273 -        /* There's no validateRoot to apply validate to, so we're done.
  14.274 -         */
  14.275 -        if (validateRoot == null) {
  14.276 -            return;
  14.277 -        }
  14.278 -
  14.279 -        /* If the validateRoot and all of its ancestors aren't visible
  14.280 -         * then we don't do anything.  While we're walking up the tree
  14.281 -         * we find the root Window or Applet.
  14.282 -         */
  14.283 -        Component root = null;
  14.284 -
  14.285 -        for(Component c = validateRoot; c != null; c = c.getParent()) {
  14.286 -            if (!c.isVisible() || (c.getPeer() == null)) {
  14.287 -                return;
  14.288 -            }
  14.289 -            if ((c instanceof Window) || SwingUtilities2.isApplet(c)) {
  14.290 -                root = c;
  14.291 -                break;
  14.292 -            }
  14.293 -        }
  14.294 -
  14.295 -        if (root == null) {
  14.296 -            return;
  14.297 -        }
  14.298 -
  14.299 -        /* Lazily create the invalidateComponents vector and add the
  14.300 -         * validateRoot if it's not there already.  If this validateRoot
  14.301 -         * is already in the vector, we're done.
  14.302 -         */
  14.303 -        if (invalidComponents == null) {
  14.304 -            invalidComponents = new ArrayList<Component>();
  14.305 -        }
  14.306 -        else {
  14.307 -            int n = invalidComponents.size();
  14.308 -            for(int i = 0; i < n; i++) {
  14.309 -                if(validateRoot == invalidComponents.get(i)) {
  14.310 -                    return;
  14.311 -                }
  14.312 -            }
  14.313 -        }
  14.314 -        invalidComponents.add(validateRoot);
  14.315 -
  14.316 -        // Queue a Runnable to invoke paintDirtyRegions and
  14.317 -        // validateInvalidComponents.
  14.318 -        scheduleProcessingRunnable();
  14.319 +        delegate.addInvalidComponent(invalidComponent);
  14.320      }
  14.321  
  14.322 -
  14.323      /**
  14.324       * Remove a component from the list of invalid components.
  14.325       *
  14.326       * @see #addInvalidComponent
  14.327       */
  14.328 -    public synchronized void removeInvalidComponent(JComponent component) {
  14.329 -        RepaintManager delegate = getDelegate(component);
  14.330 -        if (delegate != null) {
  14.331 -            delegate.removeInvalidComponent(component);
  14.332 -            return;
  14.333 -        }
  14.334 -        if(invalidComponents != null) {
  14.335 -            int index = invalidComponents.indexOf(component);
  14.336 -            if(index != -1) {
  14.337 -                invalidComponents.remove(index);
  14.338 -            }
  14.339 -        }
  14.340 -    }
  14.341 -
  14.342 -
  14.343 -    /**
  14.344 -     * Add a component in the list of components that should be refreshed.
  14.345 -     * If <i>c</i> already has a dirty region, the rectangle <i>(x,y,w,h)</i>
  14.346 -     * will be unioned with the region that should be redrawn.
  14.347 -     *
  14.348 -     * @see JComponent#repaint
  14.349 -     */
  14.350 -    private void addDirtyRegion0(Container c, int x, int y, int w, int h) {
  14.351 -        /* Special cases we don't have to bother with.
  14.352 -         */
  14.353 -        if ((w <= 0) || (h <= 0) || (c == null)) {
  14.354 -            return;
  14.355 -        }
  14.356 -
  14.357 -        if ((c.getWidth() <= 0) || (c.getHeight() <= 0)) {
  14.358 -            return;
  14.359 -        }
  14.360 -
  14.361 -        if (extendDirtyRegion(c, x, y, w, h)) {
  14.362 -            // Component was already marked as dirty, region has been
  14.363 -            // extended, no need to continue.
  14.364 -            return;
  14.365 -        }
  14.366 -
  14.367 -        /* Make sure that c and all it ancestors (up to an Applet or
  14.368 -         * Window) are visible.  This loop has the same effect as
  14.369 -         * checking c.isShowing() (and note that it's still possible
  14.370 -         * that c is completely obscured by an opaque ancestor in
  14.371 -         * the specified rectangle).
  14.372 -         */
  14.373 -        Component root = null;
  14.374 -
  14.375 -        // Note: We can't synchronize around this, Frame.getExtendedState
  14.376 -        // is synchronized so that if we were to synchronize around this
  14.377 -        // it could lead to the possibility of getting locks out
  14.378 -        // of order and deadlocking.
  14.379 -        for (Container p = c; p != null; p = p.getParent()) {
  14.380 -            if (!p.isVisible() || (p.getPeer() == null)) {
  14.381 -                return;
  14.382 -            }
  14.383 -            if ((p instanceof Window) || SwingUtilities2.isApplet(p)) {
  14.384 -                // Iconified frames are still visible!
  14.385 -                if (p instanceof Frame &&
  14.386 -                        (((Frame)p).getExtendedState() & Frame.ICONIFIED) ==
  14.387 -                                    Frame.ICONIFIED) {
  14.388 -                    return;
  14.389 -                }
  14.390 -                root = p;
  14.391 -                break;
  14.392 -            }
  14.393 -        }
  14.394 -
  14.395 -        if (root == null) return;
  14.396 -
  14.397 -        synchronized(this) {
  14.398 -            if (extendDirtyRegion(c, x, y, w, h)) {
  14.399 -                // In between last check and this check another thread
  14.400 -                // queued up runnable, can bail here.
  14.401 -                return;
  14.402 -            }
  14.403 -            dirtyComponents.put(c, new Rectangle(x, y, w, h));
  14.404 -        }
  14.405 -
  14.406 -        // Queue a Runnable to invoke paintDirtyRegions and
  14.407 -        // validateInvalidComponents.
  14.408 -        scheduleProcessingRunnable();
  14.409 +    public void removeInvalidComponent(JComponent component) {
  14.410 +        delegate.removeInvalidComponent(component);
  14.411      }
  14.412  
  14.413      /**
  14.414 @@ -477,12 +167,7 @@
  14.415       */
  14.416      public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
  14.417      {
  14.418 -        RepaintManager delegate = getDelegate(c);
  14.419 -        if (delegate != null) {
  14.420 -            delegate.addDirtyRegion(c, x, y, w, h);
  14.421 -            return;
  14.422 -        }
  14.423 -        addDirtyRegion0(c, x, y, w, h);
  14.424 +        delegate.addDirtyRegion(c, x, y, w, h);
  14.425      }
  14.426  
  14.427      /**
  14.428 @@ -500,7 +185,7 @@
  14.429       * @since 1.6
  14.430       */
  14.431      public void addDirtyRegion(Window window, int x, int y, int w, int h) {
  14.432 -        addDirtyRegion0(window, x, y, w, h);
  14.433 +        delegate.addDirtyRegion(window, x, y, w, h);
  14.434      }
  14.435  
  14.436      /**
  14.437 @@ -516,89 +201,7 @@
  14.438       * @since 1.6
  14.439       */
  14.440      public void addDirtyRegion(Applet applet, int x, int y, int w, int h) {
  14.441 -        addDirtyRegion0(applet, x, y, w, h);
  14.442 -    }
  14.443 -
  14.444 -    void scheduleHeavyWeightPaints() {
  14.445 -        Map<Container,Rectangle> hws;
  14.446 -
  14.447 -        synchronized(this) {
  14.448 -            if (hwDirtyComponents.size() == 0) {
  14.449 -                return;
  14.450 -            }
  14.451 -            hws = hwDirtyComponents;
  14.452 -            hwDirtyComponents =  new IdentityHashMap<Container,Rectangle>();
  14.453 -        }
  14.454 -        for (Container hw : hws.keySet()) {
  14.455 -            Rectangle dirty = hws.get(hw);
  14.456 -            if (hw instanceof Window) {
  14.457 -                addDirtyRegion((Window)hw, dirty.x, dirty.y,
  14.458 -                               dirty.width, dirty.height);
  14.459 -            }
  14.460 -            else if (SwingUtilities2.isApplet(hw)) {
  14.461 -                addDirtyRegion((Applet)hw, dirty.x, dirty.y,
  14.462 -                               dirty.width, dirty.height);
  14.463 -            }
  14.464 -            else { // SwingHeavyWeight
  14.465 -                addDirtyRegion0(hw, dirty.x, dirty.y,
  14.466 -                                dirty.width, dirty.height);
  14.467 -            }
  14.468 -        }
  14.469 -    }
  14.470 -
  14.471 -    //
  14.472 -    // This is called from the toolkit thread when a native expose is
  14.473 -    // received.
  14.474 -    //
  14.475 -    void nativeAddDirtyRegion(AppContext appContext, Container c,
  14.476 -                              int x, int y, int w, int h) {
  14.477 -        if (w > 0 && h > 0) {
  14.478 -            synchronized(this) {
  14.479 -                Rectangle dirty = hwDirtyComponents.get(c);
  14.480 -                if (dirty == null) {
  14.481 -                    hwDirtyComponents.put(c, new Rectangle(x, y, w, h));
  14.482 -                }
  14.483 -                else {
  14.484 -                    hwDirtyComponents.put(c, SwingUtilities.computeUnion(
  14.485 -                                              x, y, w, h, dirty));
  14.486 -                }
  14.487 -            }
  14.488 -            scheduleProcessingRunnable(appContext);
  14.489 -        }
  14.490 -    }
  14.491 -
  14.492 -    //
  14.493 -    // This is called from the toolkit thread when awt needs to run a
  14.494 -    // Runnable before we paint.
  14.495 -    //
  14.496 -    void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
  14.497 -                                        Runnable r) {
  14.498 -        synchronized(this) {
  14.499 -            if (runnableList == null) {
  14.500 -                runnableList = new LinkedList<Runnable>();
  14.501 -            }
  14.502 -            runnableList.add(r);
  14.503 -        }
  14.504 -        scheduleProcessingRunnable(appContext);
  14.505 -    }
  14.506 -
  14.507 -    /**
  14.508 -     * Extends the dirty region for the specified component to include
  14.509 -     * the new region.
  14.510 -     *
  14.511 -     * @return false if <code>c</code> is not yet marked dirty.
  14.512 -     */
  14.513 -    private synchronized boolean extendDirtyRegion(
  14.514 -        Component c, int x, int y, int w, int h) {
  14.515 -        Rectangle r = dirtyComponents.get(c);
  14.516 -        if (r != null) {
  14.517 -            // A non-null r implies c is already marked as dirty,
  14.518 -            // and that the parent is valid. Therefore we can
  14.519 -            // just union the rect and bail.
  14.520 -            SwingUtilities.computeUnion(x, y, w, h, r);
  14.521 -            return true;
  14.522 -        }
  14.523 -        return false;
  14.524 +        delegate.addDirtyRegion0(applet, x, y, w, h);
  14.525      }
  14.526  
  14.527      /** Return the current dirty region for a component.
  14.528 @@ -606,18 +209,7 @@
  14.529       *  dirty.
  14.530       */
  14.531      public Rectangle getDirtyRegion(JComponent aComponent) {
  14.532 -        RepaintManager delegate = getDelegate(aComponent);
  14.533 -        if (delegate != null) {
  14.534 -            return delegate.getDirtyRegion(aComponent);
  14.535 -        }
  14.536 -        Rectangle r;
  14.537 -        synchronized(this) {
  14.538 -            r = dirtyComponents.get(aComponent);
  14.539 -        }
  14.540 -        if(r == null)
  14.541 -            return new Rectangle(0,0,0,0);
  14.542 -        else
  14.543 -            return new Rectangle(r);
  14.544 +        return delegate.getDirtyRegion(aComponent);
  14.545      }
  14.546  
  14.547      /**
  14.548 @@ -625,12 +217,7 @@
  14.549       * completely painted during the next paintDirtyRegions() call.
  14.550       */
  14.551      public void markCompletelyDirty(JComponent aComponent) {
  14.552 -        RepaintManager delegate = getDelegate(aComponent);
  14.553 -        if (delegate != null) {
  14.554 -            delegate.markCompletelyDirty(aComponent);
  14.555 -            return;
  14.556 -        }
  14.557 -        addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE);
  14.558 +        delegate.markCompletelyDirty(aComponent);
  14.559      }
  14.560  
  14.561      /**
  14.562 @@ -638,14 +225,7 @@
  14.563       * get painted during the next paintDirtyRegions() call.
  14.564       */
  14.565      public void markCompletelyClean(JComponent aComponent) {
  14.566 -        RepaintManager delegate = getDelegate(aComponent);
  14.567 -        if (delegate != null) {
  14.568 -            delegate.markCompletelyClean(aComponent);
  14.569 -            return;
  14.570 -        }
  14.571 -        synchronized(this) {
  14.572 -                dirtyComponents.remove(aComponent);
  14.573 -        }
  14.574 +        delegate.markCompletelyClean(aComponent);
  14.575      }
  14.576  
  14.577      /**
  14.578 @@ -655,18 +235,7 @@
  14.579       * if it return true.
  14.580       */
  14.581      public boolean isCompletelyDirty(JComponent aComponent) {
  14.582 -        RepaintManager delegate = getDelegate(aComponent);
  14.583 -        if (delegate != null) {
  14.584 -            return delegate.isCompletelyDirty(aComponent);
  14.585 -        }
  14.586 -        Rectangle r;
  14.587 -
  14.588 -        r = getDirtyRegion(aComponent);
  14.589 -        if(r.width == Integer.MAX_VALUE &&
  14.590 -           r.height == Integer.MAX_VALUE)
  14.591 -            return true;
  14.592 -        else
  14.593 -            return false;
  14.594 +        return delegate.isCompletelyDirty(aComponent);
  14.595      }
  14.596  
  14.597  
  14.598 @@ -675,77 +244,7 @@
  14.599       * @see #addInvalidComponent
  14.600       */
  14.601      public void validateInvalidComponents() {
  14.602 -        java.util.List<Component> ic;
  14.603 -        synchronized(this) {
  14.604 -            if(invalidComponents == null) {
  14.605 -                return;
  14.606 -            }
  14.607 -            ic = invalidComponents;
  14.608 -            invalidComponents = null;
  14.609 -        }
  14.610 -        int n = ic.size();
  14.611 -        for(int i = 0; i < n; i++) {
  14.612 -            ic.get(i).validate();
  14.613 -        }
  14.614 -    }
  14.615 -
  14.616 -
  14.617 -    /**
  14.618 -     * This is invoked to process paint requests.  It's needed
  14.619 -     * for backward compatability in so far as RepaintManager would previously
  14.620 -     * not see paint requests for top levels, so, we have to make sure
  14.621 -     * a subclass correctly paints any dirty top levels.
  14.622 -     */
  14.623 -    private void prePaintDirtyRegions() {
  14.624 -        Map<Component,Rectangle> dirtyComponents;
  14.625 -        java.util.List<Runnable> runnableList;
  14.626 -        synchronized(this) {
  14.627 -            dirtyComponents = this.dirtyComponents;
  14.628 -            runnableList = this.runnableList;
  14.629 -            this.runnableList = null;
  14.630 -        }
  14.631 -        if (runnableList != null) {
  14.632 -            for (Runnable runnable : runnableList) {
  14.633 -                runnable.run();
  14.634 -            }
  14.635 -        }
  14.636 -        paintDirtyRegions();
  14.637 -        if (dirtyComponents.size() > 0) {
  14.638 -            // This'll only happen if a subclass isn't correctly dealing
  14.639 -            // with toplevels.
  14.640 -            paintDirtyRegions(dirtyComponents);
  14.641 -        }
  14.642 -    }
  14.643 -
  14.644 -    private void updateWindows(Map<Component,Rectangle> dirtyComponents) {
  14.645 -        Toolkit toolkit = Toolkit.getDefaultToolkit();
  14.646 -        if (!(toolkit instanceof SunToolkit &&
  14.647 -              ((SunToolkit)toolkit).needUpdateWindow()))
  14.648 -        {
  14.649 -            return;
  14.650 -        }
  14.651 -
  14.652 -        Set<Window> windows = new HashSet<Window>();
  14.653 -        Set<Component> dirtyComps = dirtyComponents.keySet();
  14.654 -        for (Iterator<Component> it = dirtyComps.iterator(); it.hasNext();) {
  14.655 -            Component dirty = it.next();
  14.656 -            Window window = dirty instanceof Window ?
  14.657 -                (Window)dirty :
  14.658 -                SwingUtilities.getWindowAncestor(dirty);
  14.659 -            if (window != null &&
  14.660 -                !AWTAccessor.getWindowAccessor().isOpaque(window))
  14.661 -            {
  14.662 -                windows.add(window);
  14.663 -            }
  14.664 -        }
  14.665 -
  14.666 -        for (Window window : windows) {
  14.667 -            AWTAccessor.getWindowAccessor().updateWindow(window);
  14.668 -        }
  14.669 -    }
  14.670 -
  14.671 -    boolean isPainting() {
  14.672 -        return painting;
  14.673 +        delegate.validateInvalidComponents();
  14.674      }
  14.675  
  14.676      /**
  14.677 @@ -754,208 +253,17 @@
  14.678       * @see #addDirtyRegion
  14.679       */
  14.680      public void paintDirtyRegions() {
  14.681 -        synchronized(this) {  // swap for thread safety
  14.682 -            Map<Component,Rectangle> tmp = tmpDirtyComponents;
  14.683 -            tmpDirtyComponents = dirtyComponents;
  14.684 -            dirtyComponents = tmp;
  14.685 -            dirtyComponents.clear();
  14.686 -        }
  14.687 -        paintDirtyRegions(tmpDirtyComponents);
  14.688 +        delegate.paintDirtyRegions();
  14.689      }
  14.690  
  14.691 -    private void paintDirtyRegions(Map<Component,Rectangle>
  14.692 -                                   tmpDirtyComponents){
  14.693 -        int i, count;
  14.694 -        java.util.List<Component> roots;
  14.695 -        Component dirtyComponent;
  14.696 -
  14.697 -        count = tmpDirtyComponents.size();
  14.698 -        if (count == 0) {
  14.699 -            return;
  14.700 -        }
  14.701 -
  14.702 -        Rectangle rect;
  14.703 -        int localBoundsX = 0;
  14.704 -        int localBoundsY = 0;
  14.705 -        int localBoundsH;
  14.706 -        int localBoundsW;
  14.707 -        Enumeration keys;
  14.708 -
  14.709 -        roots = new ArrayList<Component>(count);
  14.710 -
  14.711 -        for (Component dirty : tmpDirtyComponents.keySet()) {
  14.712 -            collectDirtyComponents(tmpDirtyComponents, dirty, roots);
  14.713 -        }
  14.714 -
  14.715 -        count = roots.size();
  14.716 -        painting = true;
  14.717 -        try {
  14.718 -            for(i=0 ; i < count ; i++) {
  14.719 -                dirtyComponent = roots.get(i);
  14.720 -                rect = tmpDirtyComponents.get(dirtyComponent);
  14.721 -                localBoundsH = dirtyComponent.getHeight();
  14.722 -                localBoundsW = dirtyComponent.getWidth();
  14.723 -
  14.724 -                SwingUtilities.computeIntersection(localBoundsX,
  14.725 -                                                   localBoundsY,
  14.726 -                                                   localBoundsW,
  14.727 -                                                   localBoundsH,
  14.728 -                                                   rect);
  14.729 -                if (dirtyComponent instanceof JComponent) {
  14.730 -                    ((JComponent)dirtyComponent).paintImmediately(
  14.731 -                        rect.x,rect.y,rect.width, rect.height);
  14.732 -                }
  14.733 -                else if (dirtyComponent.isShowing()) {
  14.734 -                    Graphics g = JComponent.safelyGetGraphics(
  14.735 -                            dirtyComponent, dirtyComponent);
  14.736 -                    // If the Graphics goes away, it means someone disposed of
  14.737 -                    // the window, don't do anything.
  14.738 -                    if (g != null) {
  14.739 -                        g.setClip(rect.x, rect.y, rect.width, rect.height);
  14.740 -                        try {
  14.741 -                            dirtyComponent.paint(g);
  14.742 -                        } finally {
  14.743 -                            g.dispose();
  14.744 -                        }
  14.745 -                    }
  14.746 -                }
  14.747 -                // If the repaintRoot has been set, service it now and
  14.748 -                // remove any components that are children of repaintRoot.
  14.749 -                if (repaintRoot != null) {
  14.750 -                    adjustRoots(repaintRoot, roots, i + 1);
  14.751 -                    count = roots.size();
  14.752 -                    paintManager.isRepaintingRoot = true;
  14.753 -                    repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
  14.754 -                                                 repaintRoot.getHeight());
  14.755 -                    paintManager.isRepaintingRoot = false;
  14.756 -                    // Only service repaintRoot once.
  14.757 -                    repaintRoot = null;
  14.758 -                }
  14.759 -            }
  14.760 -        } finally {
  14.761 -            painting = false;
  14.762 -        }
  14.763 -
  14.764 -        updateWindows(tmpDirtyComponents);
  14.765 -
  14.766 -        tmpDirtyComponents.clear();
  14.767 -    }
  14.768 -
  14.769 -
  14.770 -    /**
  14.771 -     * Removes any components from roots that are children of
  14.772 -     * root.
  14.773 -     */
  14.774 -    private void adjustRoots(JComponent root,
  14.775 -                             java.util.List<Component> roots, int index) {
  14.776 -        for (int i = roots.size() - 1; i >= index; i--) {
  14.777 -            Component c = roots.get(i);
  14.778 -            for(;;) {
  14.779 -                if (c == root || c == null || !(c instanceof JComponent)) {
  14.780 -                    break;
  14.781 -                }
  14.782 -                c = c.getParent();
  14.783 -            }
  14.784 -            if (c == root) {
  14.785 -                roots.remove(i);
  14.786 -            }
  14.787 -        }
  14.788 -    }
  14.789 -
  14.790 -    Rectangle tmp = new Rectangle();
  14.791 -
  14.792 -    void collectDirtyComponents(Map<Component,Rectangle> dirtyComponents,
  14.793 -                                Component dirtyComponent,
  14.794 -                                java.util.List<Component> roots) {
  14.795 -        int dx, dy, rootDx, rootDy;
  14.796 -        Component component, rootDirtyComponent,parent;
  14.797 -        Rectangle cBounds;
  14.798 -
  14.799 -        // Find the highest parent which is dirty.  When we get out of this
  14.800 -        // rootDx and rootDy will contain the translation from the
  14.801 -        // rootDirtyComponent's coordinate system to the coordinates of the
  14.802 -        // original dirty component.  The tmp Rect is also used to compute the
  14.803 -        // visible portion of the dirtyRect.
  14.804 -
  14.805 -        component = rootDirtyComponent = dirtyComponent;
  14.806 -
  14.807 -        int x = dirtyComponent.getX();
  14.808 -        int y = dirtyComponent.getY();
  14.809 -        int w = dirtyComponent.getWidth();
  14.810 -        int h = dirtyComponent.getHeight();
  14.811 -
  14.812 -        dx = rootDx = 0;
  14.813 -        dy = rootDy = 0;
  14.814 -        tmp.setBounds(dirtyComponents.get(dirtyComponent));
  14.815 -
  14.816 -        // System.out.println("Collect dirty component for bound " + tmp +
  14.817 -        //                                   "component bounds is " + cBounds);;
  14.818 -        SwingUtilities.computeIntersection(0,0,w,h,tmp);
  14.819 -
  14.820 -        if (tmp.isEmpty()) {
  14.821 -            // System.out.println("Empty 1");
  14.822 -            return;
  14.823 -        }
  14.824 -
  14.825 -        for(;;) {
  14.826 -            if(!(component instanceof JComponent))
  14.827 -                break;
  14.828 -
  14.829 -            parent = component.getParent();
  14.830 -            if(parent == null)
  14.831 -                break;
  14.832 -
  14.833 -            component = parent;
  14.834 -
  14.835 -            dx += x;
  14.836 -            dy += y;
  14.837 -            tmp.setLocation(tmp.x + x, tmp.y + y);
  14.838 -
  14.839 -            x = component.getX();
  14.840 -            y = component.getY();
  14.841 -            w = component.getWidth();
  14.842 -            h = component.getHeight();
  14.843 -            tmp = SwingUtilities.computeIntersection(0,0,w,h,tmp);
  14.844 -
  14.845 -            if (tmp.isEmpty()) {
  14.846 -                // System.out.println("Empty 2");
  14.847 -                return;
  14.848 -            }
  14.849 -
  14.850 -            if (dirtyComponents.get(component) != null) {
  14.851 -                rootDirtyComponent = component;
  14.852 -                rootDx = dx;
  14.853 -                rootDy = dy;
  14.854 -            }
  14.855 -        }
  14.856 -
  14.857 -        if (dirtyComponent != rootDirtyComponent) {
  14.858 -            Rectangle r;
  14.859 -            tmp.setLocation(tmp.x + rootDx - dx,
  14.860 -                            tmp.y + rootDy - dy);
  14.861 -            r = dirtyComponents.get(rootDirtyComponent);
  14.862 -            SwingUtilities.computeUnion(tmp.x,tmp.y,tmp.width,tmp.height,r);
  14.863 -        }
  14.864 -
  14.865 -        // If we haven't seen this root before, then we need to add it to the
  14.866 -        // list of root dirty Views.
  14.867 -
  14.868 -        if (!roots.contains(rootDirtyComponent))
  14.869 -            roots.add(rootDirtyComponent);
  14.870 -    }
  14.871 -
  14.872 -
  14.873      /**
  14.874       * Returns a string that displays and identifies this
  14.875       * object's properties.
  14.876       *
  14.877       * @return a String representation of this object
  14.878       */
  14.879 -    public synchronized String toString() {
  14.880 -        StringBuffer sb = new StringBuffer();
  14.881 -        if(dirtyComponents != null)
  14.882 -            sb.append("" + dirtyComponents);
  14.883 -        return sb.toString();
  14.884 +    public String toString() {
  14.885 +        return delegate.toString();
  14.886      }
  14.887  
  14.888  
  14.889 @@ -968,11 +276,7 @@
  14.890       * repaint manager.
  14.891       */
  14.892      public Image getOffscreenBuffer(Component c,int proposedWidth,int proposedHeight) {
  14.893 -        RepaintManager delegate = getDelegate(c);
  14.894 -        if (delegate != null) {
  14.895 -            return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight);
  14.896 -        }
  14.897 -        return _getOffscreenBuffer(c, proposedWidth, proposedHeight);
  14.898 +        return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight);
  14.899      }
  14.900  
  14.901    /**
  14.902 @@ -989,153 +293,20 @@
  14.903     */
  14.904      public Image getVolatileOffscreenBuffer(Component c,
  14.905                                              int proposedWidth,int proposedHeight) {
  14.906 -        RepaintManager delegate = getDelegate(c);
  14.907 -        if (delegate != null) {
  14.908 -            return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
  14.909 -                                                        proposedHeight);
  14.910 -        }
  14.911 -
  14.912 -        // If the window is non-opaque, it's double-buffered at peer's level
  14.913 -        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
  14.914 -        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
  14.915 -            Toolkit tk = Toolkit.getDefaultToolkit();
  14.916 -            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
  14.917 -                return null;
  14.918 -            }
  14.919 -        }
  14.920 -
  14.921 -        GraphicsConfiguration config = c.getGraphicsConfiguration();
  14.922 -        if (config == null) {
  14.923 -            config = GraphicsEnvironment.getLocalGraphicsEnvironment().
  14.924 -                            getDefaultScreenDevice().getDefaultConfiguration();
  14.925 -        }
  14.926 -        Dimension maxSize = getDoubleBufferMaximumSize();
  14.927 -        int width = proposedWidth < 1 ? 1 :
  14.928 -            (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
  14.929 -        int height = proposedHeight < 1 ? 1 :
  14.930 -            (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
  14.931 -        VolatileImage image = volatileMap.get(config);
  14.932 -        if (image == null || image.getWidth() < width ||
  14.933 -                             image.getHeight() < height) {
  14.934 -            if (image != null) {
  14.935 -                image.flush();
  14.936 -            }
  14.937 -            image = config.createCompatibleVolatileImage(width, height);
  14.938 -            volatileMap.put(config, image);
  14.939 -        }
  14.940 -        return image;
  14.941 +        return delegate.getVolatileOffscreenBuffer(c, proposedWidth, proposedHeight);
  14.942      }
  14.943  
  14.944 -    private Image _getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
  14.945 -        Dimension maxSize = getDoubleBufferMaximumSize();
  14.946 -        DoubleBufferInfo doubleBuffer;
  14.947 -        int width, height;
  14.948 -
  14.949 -        // If the window is non-opaque, it's double-buffered at peer's level
  14.950 -        Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
  14.951 -        if (!AWTAccessor.getWindowAccessor().isOpaque(w)) {
  14.952 -            Toolkit tk = Toolkit.getDefaultToolkit();
  14.953 -            if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
  14.954 -                return null;
  14.955 -            }
  14.956 -        }
  14.957 -
  14.958 -        if (standardDoubleBuffer == null) {
  14.959 -            standardDoubleBuffer = new DoubleBufferInfo();
  14.960 -        }
  14.961 -        doubleBuffer = standardDoubleBuffer;
  14.962 -
  14.963 -        width = proposedWidth < 1? 1 :
  14.964 -                  (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
  14.965 -        height = proposedHeight < 1? 1 :
  14.966 -                  (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
  14.967 -
  14.968 -        if (doubleBuffer.needsReset || (doubleBuffer.image != null &&
  14.969 -                                        (doubleBuffer.size.width < width ||
  14.970 -                                         doubleBuffer.size.height < height))) {
  14.971 -            doubleBuffer.needsReset = false;
  14.972 -            if (doubleBuffer.image != null) {
  14.973 -                doubleBuffer.image.flush();
  14.974 -                doubleBuffer.image = null;
  14.975 -            }
  14.976 -            width = Math.max(doubleBuffer.size.width, width);
  14.977 -            height = Math.max(doubleBuffer.size.height, height);
  14.978 -        }
  14.979 -
  14.980 -        Image result = doubleBuffer.image;
  14.981 -
  14.982 -        if (doubleBuffer.image == null) {
  14.983 -            result = c.createImage(width , height);
  14.984 -            doubleBuffer.size = new Dimension(width, height);
  14.985 -            if (c instanceof JComponent) {
  14.986 -                ((JComponent)c).setCreatedDoubleBuffer(true);
  14.987 -                doubleBuffer.image = result;
  14.988 -            }
  14.989 -            // JComponent will inform us when it is no longer valid
  14.990 -            // (via removeNotify) we have no such hook to other components,
  14.991 -            // therefore we don't keep a ref to the Component
  14.992 -            // (indirectly through the Image) by stashing the image.
  14.993 -        }
  14.994 -        return result;
  14.995 -    }
  14.996 -
  14.997 -
  14.998      /** Set the maximum double buffer size. **/
  14.999      public void setDoubleBufferMaximumSize(Dimension d) {
 14.1000 -        doubleBufferMaxSize = d;
 14.1001 -        if (doubleBufferMaxSize == null) {
 14.1002 -            clearImages();
 14.1003 -        } else {
 14.1004 -            clearImages(d.width, d.height);
 14.1005 -        }
 14.1006 +        delegate.setDoubleBufferMaximumSize(d);
 14.1007      }
 14.1008 -
 14.1009 -    private void clearImages() {
 14.1010 -        clearImages(0, 0);
 14.1011 -    }
 14.1012 -
 14.1013 -    private void clearImages(int width, int height) {
 14.1014 -        if (standardDoubleBuffer != null && standardDoubleBuffer.image != null) {
 14.1015 -            if (standardDoubleBuffer.image.getWidth(null) > width ||
 14.1016 -                standardDoubleBuffer.image.getHeight(null) > height) {
 14.1017 -                standardDoubleBuffer.image.flush();
 14.1018 -                standardDoubleBuffer.image = null;
 14.1019 -            }
 14.1020 -        }
 14.1021 -        // Clear out the VolatileImages
 14.1022 -        Iterator gcs = volatileMap.keySet().iterator();
 14.1023 -        while (gcs.hasNext()) {
 14.1024 -            GraphicsConfiguration gc = (GraphicsConfiguration)gcs.next();
 14.1025 -            VolatileImage image = volatileMap.get(gc);
 14.1026 -            if (image.getWidth() > width || image.getHeight() > height) {
 14.1027 -                image.flush();
 14.1028 -                gcs.remove();
 14.1029 -            }
 14.1030 -        }
 14.1031 -    }
 14.1032 -
 14.1033      /**
 14.1034       * Returns the maximum double buffer size.
 14.1035       *
 14.1036       * @return a Dimension object representing the maximum size
 14.1037       */
 14.1038      public Dimension getDoubleBufferMaximumSize() {
 14.1039 -        if (doubleBufferMaxSize == null) {
 14.1040 -            try {
 14.1041 -                Rectangle virtualBounds = new Rectangle();
 14.1042 -                GraphicsEnvironment ge = GraphicsEnvironment.
 14.1043 -                                                 getLocalGraphicsEnvironment();
 14.1044 -                for (GraphicsDevice gd : ge.getScreenDevices()) {
 14.1045 -                    GraphicsConfiguration gc = gd.getDefaultConfiguration();
 14.1046 -                    virtualBounds = virtualBounds.union(gc.getBounds());
 14.1047 -                }
 14.1048 -                doubleBufferMaxSize = new Dimension(virtualBounds.width,
 14.1049 -                                                    virtualBounds.height);
 14.1050 -            } catch (HeadlessException e) {
 14.1051 -                doubleBufferMaxSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 14.1052 -            }
 14.1053 -        }
 14.1054 -        return doubleBufferMaxSize;
 14.1055 +        return delegate.getDoubleBufferMaximumSize();
 14.1056      }
 14.1057  
 14.1058      /**
 14.1059 @@ -1148,11 +319,7 @@
 14.1060       * @see #isDoubleBufferingEnabled
 14.1061       */
 14.1062      public void setDoubleBufferingEnabled(boolean aFlag) {
 14.1063 -        doubleBufferingEnabled = aFlag;
 14.1064 -        PaintManager paintManager = getPaintManager();
 14.1065 -        if (!aFlag && paintManager.getClass() != PaintManager.class) {
 14.1066 -            setPaintManager(new PaintManager());
 14.1067 -        }
 14.1068 +        delegate.setDoubleBufferingEnabled(aFlag);
 14.1069      }
 14.1070  
 14.1071      /**
 14.1072 @@ -1167,500 +334,6 @@
 14.1073       * @return true if this object is double buffered
 14.1074       */
 14.1075      public boolean isDoubleBufferingEnabled() {
 14.1076 -        return doubleBufferingEnabled;
 14.1077 -    }
 14.1078 -
 14.1079 -    /**
 14.1080 -     * This resets the double buffer. Actually, it marks the double buffer
 14.1081 -     * as invalid, the double buffer will then be recreated on the next
 14.1082 -     * invocation of getOffscreenBuffer.
 14.1083 -     */
 14.1084 -    void resetDoubleBuffer() {
 14.1085 -        if (standardDoubleBuffer != null) {
 14.1086 -            standardDoubleBuffer.needsReset = true;
 14.1087 -        }
 14.1088 -    }
 14.1089 -
 14.1090 -    /**
 14.1091 -     * This resets the volatile double buffer.
 14.1092 -     */
 14.1093 -    void resetVolatileDoubleBuffer(GraphicsConfiguration gc) {
 14.1094 -        Image image = volatileMap.remove(gc);
 14.1095 -        if (image != null) {
 14.1096 -            image.flush();
 14.1097 -        }
 14.1098 -    }
 14.1099 -
 14.1100 -    /**
 14.1101 -     * Returns true if we should use the <code>Image</code> returned
 14.1102 -     * from <code>getVolatileOffscreenBuffer</code> to do double buffering.
 14.1103 -     */
 14.1104 -    boolean useVolatileDoubleBuffer() {
 14.1105 -        return volatileImageBufferEnabled;
 14.1106 -    }
 14.1107 -
 14.1108 -    /**
 14.1109 -     * Returns true if the current thread is the thread painting.  This
 14.1110 -     * will return false if no threads are painting.
 14.1111 -     */
 14.1112 -    private synchronized boolean isPaintingThread() {
 14.1113 -        return (Thread.currentThread() == paintThread);
 14.1114 -    }
 14.1115 -    //
 14.1116 -    // Paint methods.  You very, VERY rarely need to invoke these.
 14.1117 -    // They are invoked directly from JComponent's painting code and
 14.1118 -    // when painting happens outside the normal flow: DefaultDesktopManager
 14.1119 -    // and JViewport.  If you end up needing these methods in other places be
 14.1120 -    // careful that you don't get stuck in a paint loop.
 14.1121 -    //
 14.1122 -
 14.1123 -    /**
 14.1124 -     * Paints a region of a component
 14.1125 -     *
 14.1126 -     * @param paintingComponent Component to paint
 14.1127 -     * @param bufferComponent Component to obtain buffer for
 14.1128 -     * @param g Graphics to paint to
 14.1129 -     * @param x X-coordinate
 14.1130 -     * @param y Y-coordinate
 14.1131 -     * @param w Width
 14.1132 -     * @param h Height
 14.1133 -     */
 14.1134 -    void paint(JComponent paintingComponent,
 14.1135 -               JComponent bufferComponent, Graphics g,
 14.1136 -               int x, int y, int w, int h) {
 14.1137 -        PaintManager paintManager = getPaintManager();
 14.1138 -        if (!isPaintingThread()) {
 14.1139 -            // We're painting to two threads at once.  PaintManager deals
 14.1140 -            // with this a bit better than BufferStrategyPaintManager, use
 14.1141 -            // it to avoid possible exceptions/corruption.
 14.1142 -            if (paintManager.getClass() != PaintManager.class) {
 14.1143 -                paintManager = new PaintManager();
 14.1144 -                paintManager.repaintManager = this;
 14.1145 -            }
 14.1146 -        }
 14.1147 -        if (!paintManager.paint(paintingComponent, bufferComponent, g,
 14.1148 -                                x, y, w, h)) {
 14.1149 -            g.setClip(x, y, w, h);
 14.1150 -            paintingComponent.paintToOffscreen(g, x, y, w, h, x + w, y + h);
 14.1151 -        }
 14.1152 -    }
 14.1153 -
 14.1154 -    /**
 14.1155 -     * Does a copy area on the specified region.
 14.1156 -     *
 14.1157 -     * @param clip Whether or not the copyArea needs to be clipped to the
 14.1158 -     *             Component's bounds.
 14.1159 -     */
 14.1160 -    void copyArea(JComponent c, Graphics g, int x, int y, int w, int h,
 14.1161 -                  int deltaX, int deltaY, boolean clip) {
 14.1162 -        getPaintManager().copyArea(c, g, x, y, w, h, deltaX, deltaY, clip);
 14.1163 -    }
 14.1164 -
 14.1165 -    /**
 14.1166 -     * Invoked prior to any paint/copyArea method calls.  This will
 14.1167 -     * be followed by an invocation of <code>endPaint</code>.
 14.1168 -     * <b>WARNING</b>: Callers of this method need to wrap the call
 14.1169 -     * in a <code>try/finally</code>, otherwise if an exception is thrown
 14.1170 -     * during the course of painting the RepaintManager may
 14.1171 -     * be left in a state in which the screen is not updated, eg:
 14.1172 -     * <pre>
 14.1173 -     * repaintManager.beginPaint();
 14.1174 -     * try {
 14.1175 -     *   repaintManager.paint(...);
 14.1176 -     * } finally {
 14.1177 -     *   repaintManager.endPaint();
 14.1178 -     * }
 14.1179 -     * </pre>
 14.1180 -     */
 14.1181 -    void beginPaint() {
 14.1182 -        boolean multiThreadedPaint = false;
 14.1183 -        int paintDepth;
 14.1184 -        Thread currentThread = Thread.currentThread();
 14.1185 -        synchronized(this) {
 14.1186 -            paintDepth = this.paintDepth;
 14.1187 -            if (paintThread == null || currentThread == paintThread) {
 14.1188 -                paintThread = currentThread;
 14.1189 -                this.paintDepth++;
 14.1190 -            } else {
 14.1191 -                multiThreadedPaint = true;
 14.1192 -            }
 14.1193 -        }
 14.1194 -        if (!multiThreadedPaint && paintDepth == 0) {
 14.1195 -            getPaintManager().beginPaint();
 14.1196 -        }
 14.1197 -    }
 14.1198 -
 14.1199 -    /**
 14.1200 -     * Invoked after <code>beginPaint</code> has been invoked.
 14.1201 -     */
 14.1202 -    void endPaint() {
 14.1203 -        if (isPaintingThread()) {
 14.1204 -            PaintManager paintManager = null;
 14.1205 -            synchronized(this) {
 14.1206 -                if (--paintDepth == 0) {
 14.1207 -                    paintManager = getPaintManager();
 14.1208 -                }
 14.1209 -            }
 14.1210 -            if (paintManager != null) {
 14.1211 -                paintManager.endPaint();
 14.1212 -                synchronized(this) {
 14.1213 -                    paintThread = null;
 14.1214 -                }
 14.1215 -            }
 14.1216 -        }
 14.1217 -    }
 14.1218 -
 14.1219 -    /**
 14.1220 -     * If possible this will show a previously rendered portion of
 14.1221 -     * a Component.  If successful, this will return true, otherwise false.
 14.1222 -     * <p>
 14.1223 -     * WARNING: This method is invoked from the native toolkit thread, be
 14.1224 -     * very careful as to what methods this invokes!
 14.1225 -     */
 14.1226 -    boolean show(Container c, int x, int y, int w, int h) {
 14.1227 -        return getPaintManager().show(c, x, y, w, h);
 14.1228 -    }
 14.1229 -
 14.1230 -    /**
 14.1231 -     * Invoked when the doubleBuffered or useTrueDoubleBuffering
 14.1232 -     * properties of a JRootPane change.  This may come in on any thread.
 14.1233 -     */
 14.1234 -    void doubleBufferingChanged(JRootPane rootPane) {
 14.1235 -        getPaintManager().doubleBufferingChanged(rootPane);
 14.1236 -    }
 14.1237 -
 14.1238 -    /**
 14.1239 -     * Sets the <code>PaintManager</code> that is used to handle all
 14.1240 -     * double buffered painting.
 14.1241 -     *
 14.1242 -     * @param paintManager The PaintManager to use.  Passing in null indicates
 14.1243 -     *        the fallback PaintManager should be used.
 14.1244 -     */
 14.1245 -    void setPaintManager(PaintManager paintManager) {
 14.1246 -        if (paintManager == null) {
 14.1247 -            paintManager = new PaintManager();
 14.1248 -        }
 14.1249 -        PaintManager oldPaintManager;
 14.1250 -        synchronized(this) {
 14.1251 -            oldPaintManager = this.paintManager;
 14.1252 -            this.paintManager = paintManager;
 14.1253 -            paintManager.repaintManager = this;
 14.1254 -        }
 14.1255 -        if (oldPaintManager != null) {
 14.1256 -            oldPaintManager.dispose();
 14.1257 -        }
 14.1258 -    }
 14.1259 -
 14.1260 -    private synchronized PaintManager getPaintManager() {
 14.1261 -        if (paintManager == null) {
 14.1262 -            PaintManager paintManager = null;
 14.1263 -            if (doubleBufferingEnabled && !nativeDoubleBuffering) {
 14.1264 -                switch (bufferStrategyType) {
 14.1265 -                case BUFFER_STRATEGY_NOT_SPECIFIED:
 14.1266 -                    Toolkit tk = Toolkit.getDefaultToolkit();
 14.1267 -                    if (tk instanceof SunToolkit) {
 14.1268 -                        SunToolkit stk = (SunToolkit) tk;
 14.1269 -                        if (stk.useBufferPerWindow()) {
 14.1270 -                            paintManager = new BufferStrategyPaintManager();
 14.1271 -                        }
 14.1272 -                    }
 14.1273 -                    break;
 14.1274 -                case BUFFER_STRATEGY_SPECIFIED_ON:
 14.1275 -                    paintManager = new BufferStrategyPaintManager();
 14.1276 -                    break;
 14.1277 -                default:
 14.1278 -                    break;
 14.1279 -                }
 14.1280 -            }
 14.1281 -            // null case handled in setPaintManager
 14.1282 -            setPaintManager(paintManager);
 14.1283 -        }
 14.1284 -        return paintManager;
 14.1285 -    }
 14.1286 -
 14.1287 -    private void scheduleProcessingRunnable() {
 14.1288 -        scheduleProcessingRunnable(AppContext.getAppContext());
 14.1289 -    }
 14.1290 -
 14.1291 -    private void scheduleProcessingRunnable(AppContext context) {
 14.1292 -        if (processingRunnable.markPending()) {
 14.1293 -            Toolkit tk = Toolkit.getDefaultToolkit();
 14.1294 -            if (tk instanceof SunToolkit) {
 14.1295 -                SunToolkit.getSystemEventQueueImplPP(context).
 14.1296 -                  postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
 14.1297 -                                                processingRunnable));
 14.1298 -            } else {
 14.1299 -                Toolkit.getDefaultToolkit().getSystemEventQueue().
 14.1300 -                      postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
 14.1301 -                                                    processingRunnable));
 14.1302 -            }
 14.1303 -        }
 14.1304 -    }
 14.1305 -
 14.1306 -
 14.1307 -    /**
 14.1308 -     * PaintManager is used to handle all double buffered painting for
 14.1309 -     * Swing.  Subclasses should call back into the JComponent method
 14.1310 -     * <code>paintToOffscreen</code> to handle the actual painting.
 14.1311 -     */
 14.1312 -    static class PaintManager {
 14.1313 -        /**
 14.1314 -         * RepaintManager the PaintManager has been installed on.
 14.1315 -         */
 14.1316 -        protected RepaintManager repaintManager;
 14.1317 -        boolean isRepaintingRoot;
 14.1318 -
 14.1319 -        /**
 14.1320 -         * Paints a region of a component
 14.1321 -         *
 14.1322 -         * @param paintingComponent Component to paint
 14.1323 -         * @param bufferComponent Component to obtain buffer for
 14.1324 -         * @param g Graphics to paint to
 14.1325 -         * @param x X-coordinate
 14.1326 -         * @param y Y-coordinate
 14.1327 -         * @param w Width
 14.1328 -         * @param h Height
 14.1329 -         * @return true if painting was successful.
 14.1330 -         */
 14.1331 -        public boolean paint(JComponent paintingComponent,
 14.1332 -                             JComponent bufferComponent, Graphics g,
 14.1333 -                             int x, int y, int w, int h) {
 14.1334 -            // First attempt to use VolatileImage buffer for performance.
 14.1335 -            // If this fails (which should rarely occur), fallback to a
 14.1336 -            // standard Image buffer.
 14.1337 -            boolean paintCompleted = false;
 14.1338 -            Image offscreen;
 14.1339 -            if (repaintManager.useVolatileDoubleBuffer() &&
 14.1340 -                (offscreen = getValidImage(repaintManager.
 14.1341 -                getVolatileOffscreenBuffer(bufferComponent, w, h))) != null) {
 14.1342 -                VolatileImage vImage = (java.awt.image.VolatileImage)offscreen;
 14.1343 -                GraphicsConfiguration gc = bufferComponent.
 14.1344 -                                            getGraphicsConfiguration();
 14.1345 -                for (int i = 0; !paintCompleted &&
 14.1346 -                         i < RepaintManager.VOLATILE_LOOP_MAX; i++) {
 14.1347 -                    if (vImage.validate(gc) ==
 14.1348 -                                   VolatileImage.IMAGE_INCOMPATIBLE) {
 14.1349 -                        repaintManager.resetVolatileDoubleBuffer(gc);
 14.1350 -                        offscreen = repaintManager.getVolatileOffscreenBuffer(
 14.1351 -                            bufferComponent,w, h);
 14.1352 -                        vImage = (java.awt.image.VolatileImage)offscreen;
 14.1353 -                    }
 14.1354 -                    paintDoubleBuffered(paintingComponent, vImage, g, x, y,
 14.1355 -                                        w, h);
 14.1356 -                    paintCompleted = !vImage.contentsLost();
 14.1357 -                }
 14.1358 -            }
 14.1359 -            // VolatileImage painting loop failed, fallback to regular
 14.1360 -            // offscreen buffer
 14.1361 -            if (!paintCompleted && (offscreen = getValidImage(
 14.1362 -                      repaintManager.getOffscreenBuffer(
 14.1363 -                      bufferComponent, w, h))) != null) {
 14.1364 -                paintDoubleBuffered(paintingComponent, offscreen, g, x, y, w,
 14.1365 -                                    h);
 14.1366 -                paintCompleted = true;
 14.1367 -            }
 14.1368 -            return paintCompleted;
 14.1369 -        }
 14.1370 -
 14.1371 -        /**
 14.1372 -         * Does a copy area on the specified region.
 14.1373 -         */
 14.1374 -        public void copyArea(JComponent c, Graphics g, int x, int y, int w,
 14.1375 -                             int h, int deltaX, int deltaY, boolean clip) {
 14.1376 -            g.copyArea(x, y, w, h, deltaX, deltaY);
 14.1377 -        }
 14.1378 -
 14.1379 -        /**
 14.1380 -         * Invoked prior to any calls to paint or copyArea.
 14.1381 -         */
 14.1382 -        public void beginPaint() {
 14.1383 -        }
 14.1384 -
 14.1385 -        /**
 14.1386 -         * Invoked to indicate painting has been completed.
 14.1387 -         */
 14.1388 -        public void endPaint() {
 14.1389 -        }
 14.1390 -
 14.1391 -        /**
 14.1392 -         * Shows a region of a previously rendered component.  This
 14.1393 -         * will return true if successful, false otherwise.  The default
 14.1394 -         * implementation returns false.
 14.1395 -         */
 14.1396 -        public boolean show(Container c, int x, int y, int w, int h) {
 14.1397 -            return false;
 14.1398 -        }
 14.1399 -
 14.1400 -        /**
 14.1401 -         * Invoked when the doubleBuffered or useTrueDoubleBuffering
 14.1402 -         * properties of a JRootPane change.  This may come in on any thread.
 14.1403 -         */
 14.1404 -        public void doubleBufferingChanged(JRootPane rootPane) {
 14.1405 -        }
 14.1406 -
 14.1407 -        /**
 14.1408 -         * Paints a portion of a component to an offscreen buffer.
 14.1409 -         */
 14.1410 -        protected void paintDoubleBuffered(JComponent c, Image image,
 14.1411 -                            Graphics g, int clipX, int clipY,
 14.1412 -                            int clipW, int clipH) {
 14.1413 -            Graphics osg = image.getGraphics();
 14.1414 -            int bw = Math.min(clipW, image.getWidth(null));
 14.1415 -            int bh = Math.min(clipH, image.getHeight(null));
 14.1416 -            int x,y,maxx,maxy;
 14.1417 -
 14.1418 -            try {
 14.1419 -                for(x = clipX, maxx = clipX+clipW; x < maxx ;  x += bw ) {
 14.1420 -                    for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
 14.1421 -                        osg.translate(-x, -y);
 14.1422 -                        osg.setClip(x,y,bw,bh);
 14.1423 -                        c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
 14.1424 -                        g.setClip(x, y, bw, bh);
 14.1425 -                        g.drawImage(image, x, y, c);
 14.1426 -                        osg.translate(x, y);
 14.1427 -                    }
 14.1428 -                }
 14.1429 -            } finally {
 14.1430 -                osg.dispose();
 14.1431 -            }
 14.1432 -        }
 14.1433 -
 14.1434 -        /**
 14.1435 -         * If <code>image</code> is non-null with a positive size it
 14.1436 -         * is returned, otherwise null is returned.
 14.1437 -         */
 14.1438 -        private Image getValidImage(Image image) {
 14.1439 -            if (image != null && image.getWidth(null) > 0 &&
 14.1440 -                                 image.getHeight(null) > 0) {
 14.1441 -                return image;
 14.1442 -            }
 14.1443 -            return null;
 14.1444 -        }
 14.1445 -
 14.1446 -        /**
 14.1447 -         * Schedules a repaint for the specified component.  This differs
 14.1448 -         * from <code>root.repaint</code> in that if the RepaintManager is
 14.1449 -         * currently processing paint requests it'll process this request
 14.1450 -         * with the current set of requests.
 14.1451 -         */
 14.1452 -        protected void repaintRoot(JComponent root) {
 14.1453 -            assert (repaintManager.repaintRoot == null);
 14.1454 -            if (repaintManager.painting) {
 14.1455 -                repaintManager.repaintRoot = root;
 14.1456 -            }
 14.1457 -            else {
 14.1458 -                root.repaint();
 14.1459 -            }
 14.1460 -        }
 14.1461 -
 14.1462 -        /**
 14.1463 -         * Returns true if the component being painted is the root component
 14.1464 -         * that was previously passed to <code>repaintRoot</code>.
 14.1465 -         */
 14.1466 -        protected boolean isRepaintingRoot() {
 14.1467 -            return isRepaintingRoot;
 14.1468 -        }
 14.1469 -
 14.1470 -        /**
 14.1471 -         * Cleans up any state.  After invoked the PaintManager will no
 14.1472 -         * longer be used anymore.
 14.1473 -         */
 14.1474 -        protected void dispose() {
 14.1475 -        }
 14.1476 -    }
 14.1477 -
 14.1478 -
 14.1479 -    private class DoubleBufferInfo {
 14.1480 -        public Image image;
 14.1481 -        public Dimension size;
 14.1482 -        public boolean needsReset = false;
 14.1483 -    }
 14.1484 -
 14.1485 -
 14.1486 -    /**
 14.1487 -     * Listener installed to detect display changes. When display changes,
 14.1488 -     * schedules a callback to notify all RepaintManagers of the display
 14.1489 -     * changes. Only one DisplayChangedHandler is ever installed. The
 14.1490 -     * singleton instance will schedule notification for all AppContexts.
 14.1491 -     */
 14.1492 -    private static final class DisplayChangedHandler implements
 14.1493 -                                             DisplayChangedListener {
 14.1494 -        public void displayChanged() {
 14.1495 -            scheduleDisplayChanges();
 14.1496 -        }
 14.1497 -
 14.1498 -        public void paletteChanged() {
 14.1499 -        }
 14.1500 -
 14.1501 -        private void scheduleDisplayChanges() {
 14.1502 -            // To avoid threading problems, we notify each RepaintManager
 14.1503 -            // on the thread it was created on.
 14.1504 -            for (Object c : AppContext.getAppContexts()) {
 14.1505 -                AppContext context = (AppContext) c;
 14.1506 -                synchronized(context) {
 14.1507 -                    if (!context.isDisposed()) {
 14.1508 -                        EventQueue eventQueue = (EventQueue)context.get(
 14.1509 -                            AppContext.EVENT_QUEUE_KEY);
 14.1510 -                        if (eventQueue != null) {
 14.1511 -                            eventQueue.postEvent(new InvocationEvent(
 14.1512 -                                Toolkit.getDefaultToolkit(),
 14.1513 -                                new DisplayChangedRunnable()));
 14.1514 -                        }
 14.1515 -                    }
 14.1516 -                }
 14.1517 -            }
 14.1518 -        }
 14.1519 -    }
 14.1520 -
 14.1521 -
 14.1522 -    private static final class DisplayChangedRunnable implements Runnable {
 14.1523 -        public void run() {
 14.1524 -            RepaintManager.currentManager((JComponent)null).displayChanged();
 14.1525 -        }
 14.1526 -    }
 14.1527 -
 14.1528 -
 14.1529 -    /**
 14.1530 -     * Runnable used to process all repaint/revalidate requests.
 14.1531 -     */
 14.1532 -    private final class ProcessingRunnable implements Runnable {
 14.1533 -        // If true, we're wainting on the EventQueue.
 14.1534 -        private boolean pending;
 14.1535 -
 14.1536 -        /**
 14.1537 -         * Marks this processing runnable as pending. If this was not
 14.1538 -         * already marked as pending, true is returned.
 14.1539 -         */
 14.1540 -        public synchronized boolean markPending() {
 14.1541 -            if (!pending) {
 14.1542 -                pending = true;
 14.1543 -                return true;
 14.1544 -            }
 14.1545 -            return false;
 14.1546 -        }
 14.1547 -
 14.1548 -        public void run() {
 14.1549 -            synchronized (this) {
 14.1550 -                pending = false;
 14.1551 -            }
 14.1552 -            // First pass, flush any heavy paint events into real paint
 14.1553 -            // events.  If there are pending heavy weight requests this will
 14.1554 -            // result in q'ing this request up one more time.  As
 14.1555 -            // long as no other requests come in between now and the time
 14.1556 -            // the second one is processed nothing will happen.  This is not
 14.1557 -            // ideal, but the logic needed to suppress the second request is
 14.1558 -            // more headache than it's worth.
 14.1559 -            scheduleHeavyWeightPaints();
 14.1560 -            // Do the actual validation and painting.
 14.1561 -            validateInvalidComponents();
 14.1562 -            prePaintDirtyRegions();
 14.1563 -        }
 14.1564 -    }
 14.1565 -    private RepaintManager getDelegate(Component c) {
 14.1566 -        RepaintManager delegate = SwingUtilities3.getDelegateRepaintManager(c);
 14.1567 -        if (this == delegate) {
 14.1568 -            delegate = null;
 14.1569 -        }
 14.1570 -        return delegate;
 14.1571 +        return delegate.isDoubleBufferingEnabled();
 14.1572      }
 14.1573  }
    15.1 --- a/src/share/classes/javax/swing/SwingPaintEventDispatcher.java	Fri Jun 19 21:46:14 2009 +0200
    15.2 +++ b/src/share/classes/javax/swing/SwingPaintEventDispatcher.java	Sat Jun 20 22:10:34 2009 +0200
    15.3 @@ -38,7 +38,7 @@
    15.4  /**
    15.5   * Swing's PaintEventDispatcher.  If the component specified by the PaintEvent
    15.6   * is a top level Swing component (JFrame, JWindow, JDialog, JApplet), this
    15.7 - * will forward the request to the RepaintManager for eventual painting.
    15.8 + * will forward the request to the RepaintController for eventual painting.
    15.9   *
   15.10   */
   15.11  class SwingPaintEventDispatcher extends sun.awt.PaintEventDispatcher {
   15.12 @@ -56,7 +56,7 @@
   15.13                                           int w, int h) {
   15.14          if (component instanceof RootPaneContainer) {
   15.15              AppContext appContext = SunToolkit.targetToAppContext(component);
   15.16 -            RepaintManager rm = RepaintManager.currentManager(appContext);
   15.17 +            RepaintController rm = RepaintController.currentManager(appContext);
   15.18              if (!SHOW_FROM_DOUBLE_BUFFER ||
   15.19                    !rm.show((Container)component, x, y, w, h)) {
   15.20                  rm.nativeAddDirtyRegion(appContext, (Container)component,
   15.21 @@ -69,7 +69,7 @@
   15.22          }
   15.23          else if (component instanceof SwingHeavyWeight) {
   15.24              AppContext appContext = SunToolkit.targetToAppContext(component);
   15.25 -            RepaintManager rm = RepaintManager.currentManager(appContext);
   15.26 +            RepaintController rm = RepaintController.currentManager(appContext);
   15.27              rm.nativeAddDirtyRegion(appContext, (Container)component,
   15.28                                      x, y, w, h);
   15.29              return new IgnorePaintEvent(component, PaintEvent.PAINT,
   15.30 @@ -85,7 +85,7 @@
   15.31      public boolean queueSurfaceDataReplacing(Component c, Runnable r) {
   15.32          if (c instanceof RootPaneContainer) {
   15.33              AppContext appContext = SunToolkit.targetToAppContext(c);
   15.34 -            RepaintManager.currentManager(appContext).
   15.35 +            RepaintController.currentManager(appContext).
   15.36                      nativeQueueSurfaceDataRunnable(appContext, c, r);
   15.37              return true;
   15.38          }
    16.1 --- a/src/share/classes/javax/swing/UIManager.java	Fri Jun 19 21:46:14 2009 +0200
    16.2 +++ b/src/share/classes/javax/swing/UIManager.java	Sat Jun 20 22:10:34 2009 +0200
    16.3 @@ -1446,7 +1446,7 @@
    16.4          }
    16.5  
    16.6          // Install Swing's PaintEventDispatcher
    16.7 -        if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
    16.8 +        if (RepaintController.HANDLE_TOP_LEVEL_PAINT) {
    16.9              sun.awt.PaintEventDispatcher.setPaintEventDispatcher(
   16.10                                          new SwingPaintEventDispatcher());
   16.11          }