summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/RepaintManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/RepaintManager.java')
-rw-r--r--libjava/classpath/javax/swing/RepaintManager.java95
1 files changed, 66 insertions, 29 deletions
diff --git a/libjava/classpath/javax/swing/RepaintManager.java b/libjava/classpath/javax/swing/RepaintManager.java
index ed0500992c5..345c348db52 100644
--- a/libjava/classpath/javax/swing/RepaintManager.java
+++ b/libjava/classpath/javax/swing/RepaintManager.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package javax.swing;
+import java.applet.Applet;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -161,9 +162,9 @@ public class RepaintManager
if (o1 instanceof JComponent && o2 instanceof JComponent)
{
JComponent c1 = (JComponent) o1;
- Rectangle d1 = (Rectangle) dirtyComponents.get(c1);
+ Rectangle d1 = (Rectangle) dirtyComponentsWork.get(c1);
JComponent c2 = (JComponent) o2;
- Rectangle d2 = (Rectangle) dirtyComponents.get(c2);
+ Rectangle d2 = (Rectangle) dirtyComponentsWork.get(c2);
return d2.width * d2.height - d1.width * d1.height;
}
throw new ClassCastException("This comparator can only be used with "
@@ -189,6 +190,12 @@ public class RepaintManager
HashMap dirtyComponents;
/**
+ * The dirtyComponents which is used in paintDiryRegions to avoid unnecessary
+ * locking.
+ */
+ HashMap dirtyComponentsWork;
+
+ /**
* The comparator used for ordered inserting into the repaintOrder list.
*/
private transient Comparator comparator;
@@ -263,6 +270,7 @@ public class RepaintManager
public RepaintManager()
{
dirtyComponents = new HashMap();
+ dirtyComponentsWork = new HashMap();
invalidComponents = new ArrayList();
repaintWorker = new RepaintWorker();
doubleBufferMaximumSize = new Dimension(2000,2000);
@@ -414,7 +422,6 @@ public class RepaintManager
{
if (w <= 0 || h <= 0 || !component.isShowing())
return;
-
component.computeVisibleRect(rectCache);
SwingUtilities.computeIntersection(x, y, w, h, rectCache);
@@ -556,31 +563,36 @@ public class RepaintManager
if (dirtyComponents.size() == 0)
return;
+ // Swap dirtyRegions with dirtyRegionsWork to avoid locking.
synchronized (dirtyComponents)
{
- // We sort the components by their size here. This way we have a good
- // chance that painting the bigger components also paints the smaller
- // components and we don't need to paint them twice.
- ArrayList repaintOrder = new ArrayList(dirtyComponents.size());
- repaintOrder.addAll(dirtyComponents.keySet());
- if (comparator == null)
- comparator = new ComponentComparator();
- Collections.sort(repaintOrder, comparator);
- repaintUnderway = true;
- for (Iterator i = repaintOrder.iterator(); i.hasNext();)
- {
- JComponent comp = (JComponent) i.next();
- // If a component is marked completely clean in the meantime, then skip
- // it.
- Rectangle damaged = (Rectangle) dirtyComponents.get(comp);
- if (damaged == null || damaged.isEmpty())
- continue;
- comp.paintImmediately(damaged);
- dirtyComponents.remove(comp);
- }
- repaintUnderway = false;
- commitRemainingBuffers();
+ HashMap swap = dirtyComponents;
+ dirtyComponents = dirtyComponentsWork;
+ dirtyComponentsWork = swap;
}
+
+ ArrayList repaintOrder = new ArrayList(dirtyComponentsWork.size());;
+ // We sort the components by their size here. This way we have a good
+ // chance that painting the bigger components also paints the smaller
+ // components and we don't need to paint them twice.
+ repaintOrder.addAll(dirtyComponentsWork.keySet());
+
+ if (comparator == null)
+ comparator = new ComponentComparator();
+ Collections.sort(repaintOrder, comparator);
+ repaintUnderway = true;
+ for (Iterator i = repaintOrder.iterator(); i.hasNext();)
+ {
+ JComponent comp = (JComponent) i.next();
+ // If a component is marked completely clean in the meantime, then skip
+ // it.
+ Rectangle damaged = (Rectangle) dirtyComponentsWork.remove(comp);
+ if (damaged == null || damaged.isEmpty())
+ continue;
+ comp.paintImmediately(damaged);
+ }
+ repaintUnderway = false;
+ commitRemainingBuffers();
}
/**
@@ -597,7 +609,7 @@ public class RepaintManager
public Image getOffscreenBuffer(Component component, int proposedWidth,
int proposedHeight)
{
- Component root = SwingUtilities.getRoot(component);
+ Component root = getRoot(component);
Image buffer = (Image) offscreenBuffers.get(root);
if (buffer == null
|| buffer.getWidth(null) < proposedWidth
@@ -612,7 +624,33 @@ public class RepaintManager
}
return buffer;
}
-
+
+ /**
+ * Gets the root of the component given. If a parent of the
+ * component is an instance of Applet, then the applet is
+ * returned. The applet is considered the root for painting.
+ * Otherwise, the root Window is returned if it exists.
+ *
+ * @param comp - The component to get the root for.
+ * @return the parent root. An applet if it is a parent,
+ * or the root window. If neither exist, null is returned.
+ */
+ private Component getRoot(Component comp)
+ {
+ Applet app = null;
+
+ while (comp != null)
+ {
+ if (app == null && comp instanceof Window)
+ return comp;
+ else if (comp instanceof Applet)
+ app = (Applet) comp;
+ comp = comp.getParent();
+ }
+
+ return app;
+ }
+
/**
* Blits the back buffer of the specified root component to the screen. If
* the RepaintManager is currently working on a paint request, the commit
@@ -663,8 +701,7 @@ public class RepaintManager
dy1 = Math.min(bufferHeight, dy1);
dx2 = Math.min(bufferWidth, dx2);
dy2 = Math.min(bufferHeight, dy2);
- g.drawImage(buffer, dx1, dy1, dx2, dy2,
- dx1, dy1, dx2, dy2, root);
+ g.drawImage(buffer, 0, 0, root);
g.dispose();
}
// Otherwise queue this request up, until all the RepaintManager work
OpenPOWER on IntegriCloud