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
|