30 import java.awt.image.VolatileImage; 31 import java.security.AccessControlContext; 32 import java.security.AccessController; 33 import java.security.PrivilegedAction; 34 import java.util.*; 35 import java.util.concurrent.atomic.AtomicInteger; 36 import java.applet.*; 37 38 import sun.awt.AWTAccessor; 39 import sun.awt.AppContext; 40 import sun.awt.DisplayChangedListener; 41 import sun.awt.SunToolkit; 42 import sun.java2d.SunGraphicsEnvironment; 43 import sun.misc.JavaSecurityAccess; 44 import sun.misc.SharedSecrets; 45 import sun.security.action.GetPropertyAction; 46 47 import com.sun.java.swing.SwingUtilities3; 48 import sun.swing.SwingAccessor; 49 import sun.swing.SwingUtilities2.RepaintListener; 50 51 /** 52 * This class manages repaint requests, allowing the number 53 * of repaints to be minimized, for example by collapsing multiple 54 * requests into a single repaint for members of a component tree. 55 * <p> 56 * As of 1.6 <code>RepaintManager</code> handles repaint requests 57 * for Swing's top level components (<code>JApplet</code>, 58 * <code>JWindow</code>, <code>JFrame</code> and <code>JDialog</code>). 59 * Any calls to <code>repaint</code> on one of these will call into the 60 * appropriate <code>addDirtyRegion</code> method. 61 * 62 * @author Arnaud Weber 63 */ 64 public class RepaintManager 65 { 66 /** 67 * Whether or not the RepaintManager should handle paint requests 68 * for top levels. 69 */ 1069 } 1070 doubleBuffer = standardDoubleBuffer; 1071 1072 width = proposedWidth < 1? 1 : 1073 (proposedWidth > maxSize.width? maxSize.width : proposedWidth); 1074 height = proposedHeight < 1? 1 : 1075 (proposedHeight > maxSize.height? maxSize.height : proposedHeight); 1076 1077 if (doubleBuffer.needsReset || (doubleBuffer.image != null && 1078 (doubleBuffer.size.width < width || 1079 doubleBuffer.size.height < height))) { 1080 doubleBuffer.needsReset = false; 1081 if (doubleBuffer.image != null) { 1082 doubleBuffer.image.flush(); 1083 doubleBuffer.image = null; 1084 } 1085 width = Math.max(doubleBuffer.size.width, width); 1086 height = Math.max(doubleBuffer.size.height, height); 1087 } 1088 1089 Image result = doubleBuffer.image; 1090 1091 if (doubleBuffer.image == null) { 1092 result = c.createImage(width , height); 1093 doubleBuffer.size = new Dimension(width, height); 1094 if (c instanceof JComponent) { 1095 ((JComponent)c).setCreatedDoubleBuffer(true); 1096 doubleBuffer.image = result; 1097 } 1098 // JComponent will inform us when it is no longer valid 1099 // (via removeNotify) we have no such hook to other components, 1100 // therefore we don't keep a ref to the Component 1101 // (indirectly through the Image) by stashing the image. 1102 } 1103 return result; 1104 } 1105 1106 1107 /** Set the maximum double buffer size. **/ 1108 public void setDoubleBufferMaximumSize(Dimension d) { 1109 doubleBufferMaxSize = d; 1110 if (doubleBufferMaxSize == null) { 1111 clearImages(); 1112 } else { 1535 * implementation returns false. 1536 */ 1537 public boolean show(Container c, int x, int y, int w, int h) { 1538 return false; 1539 } 1540 1541 /** 1542 * Invoked when the doubleBuffered or useTrueDoubleBuffering 1543 * properties of a JRootPane change. This may come in on any thread. 1544 */ 1545 public void doubleBufferingChanged(JRootPane rootPane) { 1546 } 1547 1548 /** 1549 * Paints a portion of a component to an offscreen buffer. 1550 */ 1551 protected void paintDoubleBuffered(JComponent c, Image image, 1552 Graphics g, int clipX, int clipY, 1553 int clipW, int clipH) { 1554 Graphics osg = image.getGraphics(); 1555 int bw = Math.min(clipW, image.getWidth(null)); 1556 int bh = Math.min(clipH, image.getHeight(null)); 1557 int x,y,maxx,maxy; 1558 1559 try { 1560 for(x = clipX, maxx = clipX+clipW; x < maxx ; x += bw ) { 1561 for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) { 1562 osg.translate(-x, -y); 1563 osg.setClip(x,y,bw,bh); 1564 if (volatileBufferType != Transparency.OPAQUE 1565 && osg instanceof Graphics2D) { 1566 final Graphics2D g2d = (Graphics2D) osg; 1567 final Color oldBg = g2d.getBackground(); 1568 g2d.setBackground(c.getBackground()); 1569 g2d.clearRect(x, y, bw, bh); 1570 g2d.setBackground(oldBg); 1571 } 1572 c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy); 1573 g.setClip(x, y, bw, bh); 1574 if (volatileBufferType != Transparency.OPAQUE 1575 && g instanceof Graphics2D) { 1576 final Graphics2D g2d = (Graphics2D) g; 1577 final Composite oldComposite = g2d.getComposite(); 1578 g2d.setComposite(AlphaComposite.Src); 1579 g2d.drawImage(image, x, y, c); 1580 g2d.setComposite(oldComposite); 1581 } else { 1582 g.drawImage(image, x, y, c); 1583 } 1584 osg.translate(x, y); 1585 } 1586 } 1587 } finally { 1588 osg.dispose(); 1589 } 1590 } 1591 1592 /** 1593 * If <code>image</code> is non-null with a positive size it 1594 * is returned, otherwise null is returned. 1595 */ 1596 private Image getValidImage(Image image) { 1597 if (image != null && image.getWidth(null) > 0 && 1598 image.getHeight(null) > 0) { 1599 return image; 1600 } 1601 return null; 1602 } | 30 import java.awt.image.VolatileImage; 31 import java.security.AccessControlContext; 32 import java.security.AccessController; 33 import java.security.PrivilegedAction; 34 import java.util.*; 35 import java.util.concurrent.atomic.AtomicInteger; 36 import java.applet.*; 37 38 import sun.awt.AWTAccessor; 39 import sun.awt.AppContext; 40 import sun.awt.DisplayChangedListener; 41 import sun.awt.SunToolkit; 42 import sun.java2d.SunGraphicsEnvironment; 43 import sun.misc.JavaSecurityAccess; 44 import sun.misc.SharedSecrets; 45 import sun.security.action.GetPropertyAction; 46 47 import com.sun.java.swing.SwingUtilities3; 48 import sun.swing.SwingAccessor; 49 import sun.swing.SwingUtilities2.RepaintListener; 50 import sun.awt.image.OffScreenImage; 51 import sun.awt.image.SurfaceManager; 52 import sun.java2d.SunGraphics2D; 53 import sun.swing.JLightweightFrame; 54 55 /** 56 * This class manages repaint requests, allowing the number 57 * of repaints to be minimized, for example by collapsing multiple 58 * requests into a single repaint for members of a component tree. 59 * <p> 60 * As of 1.6 <code>RepaintManager</code> handles repaint requests 61 * for Swing's top level components (<code>JApplet</code>, 62 * <code>JWindow</code>, <code>JFrame</code> and <code>JDialog</code>). 63 * Any calls to <code>repaint</code> on one of these will call into the 64 * appropriate <code>addDirtyRegion</code> method. 65 * 66 * @author Arnaud Weber 67 */ 68 public class RepaintManager 69 { 70 /** 71 * Whether or not the RepaintManager should handle paint requests 72 * for top levels. 73 */ 1073 } 1074 doubleBuffer = standardDoubleBuffer; 1075 1076 width = proposedWidth < 1? 1 : 1077 (proposedWidth > maxSize.width? maxSize.width : proposedWidth); 1078 height = proposedHeight < 1? 1 : 1079 (proposedHeight > maxSize.height? maxSize.height : proposedHeight); 1080 1081 if (doubleBuffer.needsReset || (doubleBuffer.image != null && 1082 (doubleBuffer.size.width < width || 1083 doubleBuffer.size.height < height))) { 1084 doubleBuffer.needsReset = false; 1085 if (doubleBuffer.image != null) { 1086 doubleBuffer.image.flush(); 1087 doubleBuffer.image = null; 1088 } 1089 width = Math.max(doubleBuffer.size.width, width); 1090 height = Math.max(doubleBuffer.size.height, height); 1091 } 1092 1093 Graphics g = c.getGraphics(); 1094 int scale = g instanceof SunGraphics2D ? 1095 ((SunGraphics2D)g).surfaceData.getDefaultScale() : 1; 1096 1097 Image result = doubleBuffer.image; 1098 1099 if (doubleBuffer.image == null || 1100 SurfaceManager.getImageScale(doubleBuffer.image) != scale) 1101 { 1102 if (w instanceof JLightweightFrame) { 1103 result = ((JLightweightFrame)w).createHiDPIImage(width, height); 1104 } else { 1105 result = c.createImage(width, height); 1106 } 1107 doubleBuffer.size = new Dimension(width, height); 1108 if (c instanceof JComponent) { 1109 ((JComponent)c).setCreatedDoubleBuffer(true); 1110 doubleBuffer.image = result; 1111 } 1112 // JComponent will inform us when it is no longer valid 1113 // (via removeNotify) we have no such hook to other components, 1114 // therefore we don't keep a ref to the Component 1115 // (indirectly through the Image) by stashing the image. 1116 } 1117 return result; 1118 } 1119 1120 1121 /** Set the maximum double buffer size. **/ 1122 public void setDoubleBufferMaximumSize(Dimension d) { 1123 doubleBufferMaxSize = d; 1124 if (doubleBufferMaxSize == null) { 1125 clearImages(); 1126 } else { 1549 * implementation returns false. 1550 */ 1551 public boolean show(Container c, int x, int y, int w, int h) { 1552 return false; 1553 } 1554 1555 /** 1556 * Invoked when the doubleBuffered or useTrueDoubleBuffering 1557 * properties of a JRootPane change. This may come in on any thread. 1558 */ 1559 public void doubleBufferingChanged(JRootPane rootPane) { 1560 } 1561 1562 /** 1563 * Paints a portion of a component to an offscreen buffer. 1564 */ 1565 protected void paintDoubleBuffered(JComponent c, Image image, 1566 Graphics g, int clipX, int clipY, 1567 int clipW, int clipH) { 1568 Graphics osg = image.getGraphics(); 1569 int lw = image.getWidth(null); 1570 int lh = image.getHeight(null); 1571 if (image instanceof OffScreenImage) { 1572 lw = ((OffScreenImage)image).getLayoutWidth(); 1573 lh = ((OffScreenImage)image).getLayoutHeight(); 1574 } 1575 int bw = Math.min(clipW, lw); 1576 int bh = Math.min(clipH, lh); 1577 int x,y,maxx,maxy; 1578 1579 try { 1580 for(x = clipX, maxx = clipX+clipW; x < maxx ; x += bw ) { 1581 for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) { 1582 osg.translate(-x, -y); 1583 osg.setClip(x,y,bw,bh); 1584 if (volatileBufferType != Transparency.OPAQUE 1585 && osg instanceof Graphics2D) { 1586 final Graphics2D g2d = (Graphics2D) osg; 1587 final Color oldBg = g2d.getBackground(); 1588 g2d.setBackground(c.getBackground()); 1589 g2d.clearRect(x, y, bw, bh); 1590 g2d.setBackground(oldBg); 1591 } 1592 c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy); 1593 g.setClip(x, y, bw, bh); 1594 if (volatileBufferType != Transparency.OPAQUE 1595 && g instanceof Graphics2D) { 1596 final Graphics2D g2d = (Graphics2D) g; 1597 final Composite oldComposite = g2d.getComposite(); 1598 g2d.setComposite(AlphaComposite.Src); 1599 g2d.drawImage(image, x, y, lw, lh, c); 1600 g2d.setComposite(oldComposite); 1601 } else { 1602 g.drawImage(image, x, y, lw, lh, c); 1603 } 1604 osg.translate(x, y); 1605 } 1606 } 1607 } finally { 1608 osg.dispose(); 1609 } 1610 } 1611 1612 /** 1613 * If <code>image</code> is non-null with a positive size it 1614 * is returned, otherwise null is returned. 1615 */ 1616 private Image getValidImage(Image image) { 1617 if (image != null && image.getWidth(null) > 0 && 1618 image.getHeight(null) > 0) { 1619 return image; 1620 } 1621 return null; 1622 } |