jdk/src/share/classes/javax/swing/RepaintManager.java
changeset 16092 129d7d8a7399
parent 13233 4d45f7ebc0d7
child 18231 2948d734293d
equal deleted inserted replaced
16091:4eb1062acb5b 16092:129d7d8a7399
    25 package javax.swing;
    25 package javax.swing;
    26 
    26 
    27 
    27 
    28 import java.awt.*;
    28 import java.awt.*;
    29 import java.awt.event.*;
    29 import java.awt.event.*;
    30 import java.awt.peer.ComponentPeer;
       
    31 import java.awt.peer.ContainerPeer;
       
    32 import java.awt.image.VolatileImage;
    30 import java.awt.image.VolatileImage;
       
    31 import java.security.AccessControlContext;
    33 import java.security.AccessController;
    32 import java.security.AccessController;
       
    33 import java.security.PrivilegedAction;
    34 import java.util.*;
    34 import java.util.*;
       
    35 import java.util.concurrent.atomic.AtomicInteger;
    35 import java.applet.*;
    36 import java.applet.*;
    36 
    37 
    37 import sun.awt.AWTAccessor;
    38 import sun.awt.AWTAccessor;
    38 import sun.awt.AppContext;
    39 import sun.awt.AppContext;
    39 import sun.awt.DisplayChangedListener;
    40 import sun.awt.DisplayChangedListener;
    40 import sun.awt.SunToolkit;
    41 import sun.awt.SunToolkit;
    41 import sun.java2d.SunGraphicsEnvironment;
    42 import sun.java2d.SunGraphicsEnvironment;
       
    43 import sun.misc.JavaSecurityAccess;
       
    44 import sun.misc.SharedSecrets;
    42 import sun.security.action.GetPropertyAction;
    45 import sun.security.action.GetPropertyAction;
    43 
    46 
    44 import com.sun.java.swing.SwingUtilities3;
    47 import com.sun.java.swing.SwingUtilities3;
    45 
    48 
    46 /**
    49 /**
   173 
   176 
   174     /**
   177     /**
   175      * Runnable used to process all repaint/revalidate requests.
   178      * Runnable used to process all repaint/revalidate requests.
   176      */
   179      */
   177     private final ProcessingRunnable processingRunnable;
   180     private final ProcessingRunnable processingRunnable;
       
   181 
       
   182     private final static JavaSecurityAccess javaSecurityAccess =
       
   183         SharedSecrets.getJavaSecurityAccess();
   178 
   184 
   179 
   185 
   180     static {
   186     static {
   181         volatileImageBufferEnabled = "true".equals(AccessController.
   187         volatileImageBufferEnabled = "true".equals(AccessController.
   182                 doPrivileged(new GetPropertyAction(
   188                 doPrivileged(new GetPropertyAction(
   546 
   552 
   547     //
   553     //
   548     // This is called from the toolkit thread when awt needs to run a
   554     // This is called from the toolkit thread when awt needs to run a
   549     // Runnable before we paint.
   555     // Runnable before we paint.
   550     //
   556     //
   551     void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
   557     void nativeQueueSurfaceDataRunnable(AppContext appContext,
   552                                         Runnable r) {
   558                                         final Component c, final Runnable r)
       
   559     {
   553         synchronized(this) {
   560         synchronized(this) {
   554             if (runnableList == null) {
   561             if (runnableList == null) {
   555                 runnableList = new LinkedList<Runnable>();
   562                 runnableList = new LinkedList<Runnable>();
   556             }
   563             }
   557             runnableList.add(r);
   564             runnableList.add(new Runnable() {
       
   565                 public void run() {
       
   566                     AccessControlContext stack = AccessController.getContext();
       
   567                     AccessControlContext acc =
       
   568                         AWTAccessor.getComponentAccessor().getAccessControlContext(c);
       
   569                     javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
       
   570                         public Void run() {
       
   571                             r.run();
       
   572                             return null;
       
   573                         }
       
   574                     }, stack, acc);
       
   575                 }
       
   576             });
   558         }
   577         }
   559         scheduleProcessingRunnable(appContext);
   578         scheduleProcessingRunnable(appContext);
   560     }
   579     }
   561 
   580 
   562     /**
   581     /**
   650     /**
   669     /**
   651      * Validate all of the components that have been marked invalid.
   670      * Validate all of the components that have been marked invalid.
   652      * @see #addInvalidComponent
   671      * @see #addInvalidComponent
   653      */
   672      */
   654     public void validateInvalidComponents() {
   673     public void validateInvalidComponents() {
   655         java.util.List<Component> ic;
   674         final java.util.List<Component> ic;
   656         synchronized(this) {
   675         synchronized(this) {
   657             if(invalidComponents == null) {
   676             if (invalidComponents == null) {
   658                 return;
   677                 return;
   659             }
   678             }
   660             ic = invalidComponents;
   679             ic = invalidComponents;
   661             invalidComponents = null;
   680             invalidComponents = null;
   662         }
   681         }
   663         int n = ic.size();
   682         int n = ic.size();
   664         for(int i = 0; i < n; i++) {
   683         for(int i = 0; i < n; i++) {
   665             ic.get(i).validate();
   684             final Component c = ic.get(i);
       
   685             AccessControlContext stack = AccessController.getContext();
       
   686             AccessControlContext acc =
       
   687                 AWTAccessor.getComponentAccessor().getAccessControlContext(c);
       
   688             javaSecurityAccess.doIntersectionPrivilege(
       
   689                 new PrivilegedAction<Void>() {
       
   690                     public Void run() {
       
   691                         c.validate();
       
   692                         return null;
       
   693                     }
       
   694                 }, stack, acc);
   666         }
   695         }
   667     }
   696     }
   668 
   697 
   669 
   698 
   670     /**
   699     /**
   738             dirtyComponents.clear();
   767             dirtyComponents.clear();
   739         }
   768         }
   740         paintDirtyRegions(tmpDirtyComponents);
   769         paintDirtyRegions(tmpDirtyComponents);
   741     }
   770     }
   742 
   771 
   743     private void paintDirtyRegions(Map<Component,Rectangle>
   772     private void paintDirtyRegions(
   744                                    tmpDirtyComponents){
   773         final Map<Component,Rectangle> tmpDirtyComponents)
   745         int i, count;
   774     {
   746         java.util.List<Component> roots;
   775         if (tmpDirtyComponents.isEmpty()) {
   747         Component dirtyComponent;
       
   748 
       
   749         count = tmpDirtyComponents.size();
       
   750         if (count == 0) {
       
   751             return;
   776             return;
   752         }
   777         }
   753 
   778 
   754         Rectangle rect;
   779         final java.util.List<Component> roots =
   755         int localBoundsX = 0;
   780             new ArrayList<Component>(tmpDirtyComponents.size());
   756         int localBoundsY = 0;
       
   757         int localBoundsH;
       
   758         int localBoundsW;
       
   759 
       
   760         roots = new ArrayList<Component>(count);
       
   761 
       
   762         for (Component dirty : tmpDirtyComponents.keySet()) {
   781         for (Component dirty : tmpDirtyComponents.keySet()) {
   763             collectDirtyComponents(tmpDirtyComponents, dirty, roots);
   782             collectDirtyComponents(tmpDirtyComponents, dirty, roots);
   764         }
   783         }
   765 
   784 
   766         count = roots.size();
   785         final AtomicInteger count = new AtomicInteger(roots.size());
   767         painting = true;
   786         painting = true;
   768         try {
   787         try {
   769             for(i=0 ; i < count ; i++) {
   788             for (int j=0 ; j < count.get(); j++) {
   770                 dirtyComponent = roots.get(i);
   789                 final int i = j;
   771                 rect = tmpDirtyComponents.get(dirtyComponent);
   790                 final Component dirtyComponent = roots.get(j);
   772                 // Sometimes when RepaintManager is changed during the painting
   791                 AccessControlContext stack = AccessController.getContext();
   773                 // we may get null here, see #6995769 for details
   792                 AccessControlContext acc =
   774                 if (rect == null) {
   793                     AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
   775                     continue;
   794                 javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
   776                 }
   795                     public Void run() {
   777                 localBoundsH = dirtyComponent.getHeight();
   796                         Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
   778                 localBoundsW = dirtyComponent.getWidth();
   797                         // Sometimes when RepaintManager is changed during the painting
   779 
   798                         // we may get null here, see #6995769 for details
   780                 SwingUtilities.computeIntersection(localBoundsX,
   799                         if (rect == null) {
   781                                                    localBoundsY,
   800                             return null;
   782                                                    localBoundsW,
       
   783                                                    localBoundsH,
       
   784                                                    rect);
       
   785                 if (dirtyComponent instanceof JComponent) {
       
   786                     ((JComponent)dirtyComponent).paintImmediately(
       
   787                         rect.x,rect.y,rect.width, rect.height);
       
   788                 }
       
   789                 else if (dirtyComponent.isShowing()) {
       
   790                     Graphics g = JComponent.safelyGetGraphics(
       
   791                             dirtyComponent, dirtyComponent);
       
   792                     // If the Graphics goes away, it means someone disposed of
       
   793                     // the window, don't do anything.
       
   794                     if (g != null) {
       
   795                         g.setClip(rect.x, rect.y, rect.width, rect.height);
       
   796                         try {
       
   797                             dirtyComponent.paint(g);
       
   798                         } finally {
       
   799                             g.dispose();
       
   800                         }
   801                         }
       
   802 
       
   803                         int localBoundsH = dirtyComponent.getHeight();
       
   804                         int localBoundsW = dirtyComponent.getWidth();
       
   805                         SwingUtilities.computeIntersection(0,
       
   806                                                            0,
       
   807                                                            localBoundsW,
       
   808                                                            localBoundsH,
       
   809                                                            rect);
       
   810                         if (dirtyComponent instanceof JComponent) {
       
   811                             ((JComponent)dirtyComponent).paintImmediately(
       
   812                                 rect.x,rect.y,rect.width, rect.height);
       
   813                         }
       
   814                         else if (dirtyComponent.isShowing()) {
       
   815                             Graphics g = JComponent.safelyGetGraphics(
       
   816                                     dirtyComponent, dirtyComponent);
       
   817                             // If the Graphics goes away, it means someone disposed of
       
   818                             // the window, don't do anything.
       
   819                             if (g != null) {
       
   820                                 g.setClip(rect.x, rect.y, rect.width, rect.height);
       
   821                                 try {
       
   822                                     dirtyComponent.paint(g);
       
   823                                 } finally {
       
   824                                     g.dispose();
       
   825                                 }
       
   826                             }
       
   827                         }
       
   828                         // If the repaintRoot has been set, service it now and
       
   829                         // remove any components that are children of repaintRoot.
       
   830                         if (repaintRoot != null) {
       
   831                             adjustRoots(repaintRoot, roots, i + 1);
       
   832                             count.set(roots.size());
       
   833                             paintManager.isRepaintingRoot = true;
       
   834                             repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
       
   835                                                          repaintRoot.getHeight());
       
   836                             paintManager.isRepaintingRoot = false;
       
   837                             // Only service repaintRoot once.
       
   838                             repaintRoot = null;
       
   839                         }
       
   840 
       
   841                         return null;
   801                     }
   842                     }
   802                 }
   843                 }, stack, acc);
   803                 // If the repaintRoot has been set, service it now and
       
   804                 // remove any components that are children of repaintRoot.
       
   805                 if (repaintRoot != null) {
       
   806                     adjustRoots(repaintRoot, roots, i + 1);
       
   807                     count = roots.size();
       
   808                     paintManager.isRepaintingRoot = true;
       
   809                     repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
       
   810                                                  repaintRoot.getHeight());
       
   811                     paintManager.isRepaintingRoot = false;
       
   812                     // Only service repaintRoot once.
       
   813                     repaintRoot = null;
       
   814                 }
       
   815             }
   844             }
   816         } finally {
   845         } finally {
   817             painting = false;
   846             painting = false;
   818         }
   847         }
   819 
   848