src/share/classes/javax/swing/RepaintManager.java

Print this page




 102 
 103     // Support for both the standard and volatile offscreen buffers exists to
 104     // provide backwards compatibility for the [rare] programs which may be
 105     // calling getOffScreenBuffer() and not expecting to get a VolatileImage.
 106     // Swing internally is migrating to use *only* the volatile image buffer.
 107 
 108     // Support for standard offscreen buffer
 109     //
 110     DoubleBufferInfo standardDoubleBuffer;
 111 
 112     /**
 113      * Object responsible for hanlding core paint functionality.
 114      */
 115     private PaintManager paintManager;
 116 
 117     private static final Object repaintManagerKey = RepaintManager.class;
 118 
 119     // Whether or not a VolatileImage should be used for double-buffered painting
 120     static boolean volatileImageBufferEnabled = true;
 121     /**





 122      * Value of the system property awt.nativeDoubleBuffering.
 123      */
 124     private static boolean nativeDoubleBuffering;
 125 
 126     // The maximum number of times Swing will attempt to use the VolatileImage
 127     // buffer during a paint operation.
 128     private static final int VOLATILE_LOOP_MAX = 2;
 129 
 130     /**
 131      * Number of <code>beginPaint</code> that have been invoked.
 132      */
 133     private int paintDepth = 0;
 134 
 135     /**
 136      * Type of buffer strategy to use.  Will be one of the BUFFER_STRATEGY_
 137      * constants.
 138      */
 139     private short bufferStrategyType;
 140 
 141     //


 187         if (headless) {
 188             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
 189         }
 190         else if (bs == null) {
 191             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_NOT_SPECIFIED;
 192         }
 193         else if ("true".equals(bs)) {
 194             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_ON;
 195         }
 196         else {
 197             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
 198         }
 199         HANDLE_TOP_LEVEL_PAINT = "true".equals(AccessController.doPrivileged(
 200                new GetPropertyAction("swing.handleTopLevelPaint", "true")));
 201         GraphicsEnvironment ge = GraphicsEnvironment.
 202                 getLocalGraphicsEnvironment();
 203         if (ge instanceof SunGraphicsEnvironment) {
 204             ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
 205                     new DisplayChangedHandler());
 206         }







 207     }
 208 
 209     /**
 210      * Return the RepaintManager for the calling thread given a Component.
 211      *
 212      * @param c a Component -- unused in the default implementation, but could
 213      *          be used by an overridden version to return a different RepaintManager
 214      *          depending on the Component
 215      * @return the RepaintManager object
 216      */
 217     public static RepaintManager currentManager(Component c) {
 218         // Note: DisplayChangedRunnable passes in null as the component, so if
 219         // component is ever used to determine the current
 220         // RepaintManager, DisplayChangedRunnable will need to be modified
 221         // accordingly.
 222         return currentManager(AppContext.getAppContext());
 223     }
 224 
 225     /**
 226      * Returns the RepaintManager for the specified AppContext.  If


 972                 return null;
 973             }
 974         }
 975 
 976         GraphicsConfiguration config = c.getGraphicsConfiguration();
 977         if (config == null) {
 978             config = GraphicsEnvironment.getLocalGraphicsEnvironment().
 979                             getDefaultScreenDevice().getDefaultConfiguration();
 980         }
 981         Dimension maxSize = getDoubleBufferMaximumSize();
 982         int width = proposedWidth < 1 ? 1 :
 983             (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
 984         int height = proposedHeight < 1 ? 1 :
 985             (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
 986         VolatileImage image = volatileMap.get(config);
 987         if (image == null || image.getWidth() < width ||
 988                              image.getHeight() < height) {
 989             if (image != null) {
 990                 image.flush();
 991             }
 992             image = config.createCompatibleVolatileImage(width, height);

 993             volatileMap.put(config, image);
 994         }
 995         return image;
 996     }
 997 
 998     private Image _getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
 999         Dimension maxSize = getDoubleBufferMaximumSize();
1000         DoubleBufferInfo doubleBuffer;
1001         int width, height;
1002 
1003         // If the window is non-opaque, it's double-buffered at peer's level
1004         Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
1005         if (!w.isOpaque()) {
1006             Toolkit tk = Toolkit.getDefaultToolkit();
1007             if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
1008                 return null;
1009             }
1010         }
1011 
1012         if (standardDoubleBuffer == null) {


1466          */
1467         public void doubleBufferingChanged(JRootPane rootPane) {
1468         }
1469 
1470         /**
1471          * Paints a portion of a component to an offscreen buffer.
1472          */
1473         protected void paintDoubleBuffered(JComponent c, Image image,
1474                             Graphics g, int clipX, int clipY,
1475                             int clipW, int clipH) {
1476             Graphics osg = image.getGraphics();
1477             int bw = Math.min(clipW, image.getWidth(null));
1478             int bh = Math.min(clipH, image.getHeight(null));
1479             int x,y,maxx,maxy;
1480 
1481             try {
1482                 for(x = clipX, maxx = clipX+clipW; x < maxx ;  x += bw ) {
1483                     for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
1484                         osg.translate(-x, -y);
1485                         osg.setClip(x,y,bw,bh);








1486                         c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
1487                         g.setClip(x, y, bw, bh);








1488                         g.drawImage(image, x, y, c);

1489                         osg.translate(x, y);
1490                     }
1491                 }
1492             } finally {
1493                 osg.dispose();
1494             }
1495         }
1496 
1497         /**
1498          * If <code>image</code> is non-null with a positive size it
1499          * is returned, otherwise null is returned.
1500          */
1501         private Image getValidImage(Image image) {
1502             if (image != null && image.getWidth(null) > 0 &&
1503                                  image.getHeight(null) > 0) {
1504                 return image;
1505             }
1506             return null;
1507         }
1508 




 102 
 103     // Support for both the standard and volatile offscreen buffers exists to
 104     // provide backwards compatibility for the [rare] programs which may be
 105     // calling getOffScreenBuffer() and not expecting to get a VolatileImage.
 106     // Swing internally is migrating to use *only* the volatile image buffer.
 107 
 108     // Support for standard offscreen buffer
 109     //
 110     DoubleBufferInfo standardDoubleBuffer;
 111 
 112     /**
 113      * Object responsible for hanlding core paint functionality.
 114      */
 115     private PaintManager paintManager;
 116 
 117     private static final Object repaintManagerKey = RepaintManager.class;
 118 
 119     // Whether or not a VolatileImage should be used for double-buffered painting
 120     static boolean volatileImageBufferEnabled = true;
 121     /**
 122      * Type of VolatileImage which should be used for double-buffered
 123      * painting.
 124      */
 125     private static final int volatileBufferType;
 126     /**
 127      * Value of the system property awt.nativeDoubleBuffering.
 128      */
 129     private static boolean nativeDoubleBuffering;
 130 
 131     // The maximum number of times Swing will attempt to use the VolatileImage
 132     // buffer during a paint operation.
 133     private static final int VOLATILE_LOOP_MAX = 2;
 134 
 135     /**
 136      * Number of <code>beginPaint</code> that have been invoked.
 137      */
 138     private int paintDepth = 0;
 139 
 140     /**
 141      * Type of buffer strategy to use.  Will be one of the BUFFER_STRATEGY_
 142      * constants.
 143      */
 144     private short bufferStrategyType;
 145 
 146     //


 192         if (headless) {
 193             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
 194         }
 195         else if (bs == null) {
 196             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_NOT_SPECIFIED;
 197         }
 198         else if ("true".equals(bs)) {
 199             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_ON;
 200         }
 201         else {
 202             BUFFER_STRATEGY_TYPE = BUFFER_STRATEGY_SPECIFIED_OFF;
 203         }
 204         HANDLE_TOP_LEVEL_PAINT = "true".equals(AccessController.doPrivileged(
 205                new GetPropertyAction("swing.handleTopLevelPaint", "true")));
 206         GraphicsEnvironment ge = GraphicsEnvironment.
 207                 getLocalGraphicsEnvironment();
 208         if (ge instanceof SunGraphicsEnvironment) {
 209             ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
 210                     new DisplayChangedHandler());
 211         }
 212         Toolkit tk = Toolkit.getDefaultToolkit();
 213         if ((tk instanceof SunToolkit)
 214                 && ((SunToolkit) tk).isSwingBackbufferTranslucencySupported()) {
 215             volatileBufferType = Transparency.TRANSLUCENT;
 216         } else {
 217             volatileBufferType = Transparency.OPAQUE;
 218         }
 219     }
 220 
 221     /**
 222      * Return the RepaintManager for the calling thread given a Component.
 223      *
 224      * @param c a Component -- unused in the default implementation, but could
 225      *          be used by an overridden version to return a different RepaintManager
 226      *          depending on the Component
 227      * @return the RepaintManager object
 228      */
 229     public static RepaintManager currentManager(Component c) {
 230         // Note: DisplayChangedRunnable passes in null as the component, so if
 231         // component is ever used to determine the current
 232         // RepaintManager, DisplayChangedRunnable will need to be modified
 233         // accordingly.
 234         return currentManager(AppContext.getAppContext());
 235     }
 236 
 237     /**
 238      * Returns the RepaintManager for the specified AppContext.  If


 984                 return null;
 985             }
 986         }
 987 
 988         GraphicsConfiguration config = c.getGraphicsConfiguration();
 989         if (config == null) {
 990             config = GraphicsEnvironment.getLocalGraphicsEnvironment().
 991                             getDefaultScreenDevice().getDefaultConfiguration();
 992         }
 993         Dimension maxSize = getDoubleBufferMaximumSize();
 994         int width = proposedWidth < 1 ? 1 :
 995             (proposedWidth > maxSize.width? maxSize.width : proposedWidth);
 996         int height = proposedHeight < 1 ? 1 :
 997             (proposedHeight > maxSize.height? maxSize.height : proposedHeight);
 998         VolatileImage image = volatileMap.get(config);
 999         if (image == null || image.getWidth() < width ||
1000                              image.getHeight() < height) {
1001             if (image != null) {
1002                 image.flush();
1003             }
1004             image = config.createCompatibleVolatileImage(width, height,
1005                                                          volatileBufferType);
1006             volatileMap.put(config, image);
1007         }
1008         return image;
1009     }
1010 
1011     private Image _getOffscreenBuffer(Component c, int proposedWidth, int proposedHeight) {
1012         Dimension maxSize = getDoubleBufferMaximumSize();
1013         DoubleBufferInfo doubleBuffer;
1014         int width, height;
1015 
1016         // If the window is non-opaque, it's double-buffered at peer's level
1017         Window w = (c instanceof Window) ? (Window)c : SwingUtilities.getWindowAncestor(c);
1018         if (!w.isOpaque()) {
1019             Toolkit tk = Toolkit.getDefaultToolkit();
1020             if ((tk instanceof SunToolkit) && (((SunToolkit)tk).needUpdateWindow())) {
1021                 return null;
1022             }
1023         }
1024 
1025         if (standardDoubleBuffer == null) {


1479          */
1480         public void doubleBufferingChanged(JRootPane rootPane) {
1481         }
1482 
1483         /**
1484          * Paints a portion of a component to an offscreen buffer.
1485          */
1486         protected void paintDoubleBuffered(JComponent c, Image image,
1487                             Graphics g, int clipX, int clipY,
1488                             int clipW, int clipH) {
1489             Graphics osg = image.getGraphics();
1490             int bw = Math.min(clipW, image.getWidth(null));
1491             int bh = Math.min(clipH, image.getHeight(null));
1492             int x,y,maxx,maxy;
1493 
1494             try {
1495                 for(x = clipX, maxx = clipX+clipW; x < maxx ;  x += bw ) {
1496                     for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
1497                         osg.translate(-x, -y);
1498                         osg.setClip(x,y,bw,bh);
1499                         if (volatileBufferType != Transparency.OPAQUE
1500                                 && osg instanceof Graphics2D) {
1501                             final Graphics2D g2d = (Graphics2D) osg;
1502                             final Color oldBg = g2d.getBackground();
1503                             g2d.setBackground(c.getBackground());
1504                             g2d.clearRect(x, y, bw, bh);
1505                             g2d.setBackground(oldBg);
1506                         }
1507                         c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
1508                         g.setClip(x, y, bw, bh);
1509                         if (volatileBufferType != Transparency.OPAQUE
1510                                 && g instanceof Graphics2D) {
1511                             final Graphics2D g2d = (Graphics2D) g;
1512                             final Composite oldComposite = g2d.getComposite();
1513                             g2d.setComposite(AlphaComposite.Src);
1514                             g2d.drawImage(image, x, y, c);
1515                             g2d.setComposite(oldComposite);
1516                         } else {
1517                             g.drawImage(image, x, y, c);
1518                         }
1519                         osg.translate(x, y);
1520                     }
1521                 }
1522             } finally {
1523                 osg.dispose();
1524             }
1525         }
1526 
1527         /**
1528          * If <code>image</code> is non-null with a positive size it
1529          * is returned, otherwise null is returned.
1530          */
1531         private Image getValidImage(Image image) {
1532             if (image != null && image.getWidth(null) > 0 &&
1533                                  image.getHeight(null) > 0) {
1534                 return image;
1535             }
1536             return null;
1537         }
1538