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

Print this page




  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         }