summaryrefslogtreecommitdiff
path: root/javax/swing/RepaintManager.java
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-09-05 20:47:38 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-09-05 20:47:38 +0000
commit228fc33f661314b6723b691635085ee4ff6a69b2 (patch)
tree50e78696593f8df21fe9330258dff98537d39f65 /javax/swing/RepaintManager.java
parentf090c35d5776db64813ccf19d8327cf0ae756ac7 (diff)
downloadclasspath-228fc33f661314b6723b691635085ee4ff6a69b2.tar.gz
2006-09-05 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge of HEAD-->generics from 2006/08/12 to 2006/09/03.
Diffstat (limited to 'javax/swing/RepaintManager.java')
-rw-r--r--javax/swing/RepaintManager.java205
1 files changed, 69 insertions, 136 deletions
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index 29bf98fbe..2d29e9076 100644
--- a/javax/swing/RepaintManager.java
+++ b/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;
@@ -49,7 +50,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
@@ -197,19 +197,6 @@ public class RepaintManager
private WeakHashMap offscreenBuffers;
/**
- * Indicates if the RepaintManager is currently repainting an area.
- */
- private boolean repaintUnderway;
-
- /**
- * This holds buffer commit requests when the RepaintManager is working.
- * This maps Component objects (the top level components) to Rectangle
- * objects (the area of the corresponding buffer that must be blitted on
- * the component).
- */
- private HashMap commitRequests;
-
- /**
* The maximum width and height to allocate as a double buffer. Requests
* beyond this size are ignored.
*
@@ -232,8 +219,6 @@ public class RepaintManager
doubleBufferMaximumSize = new Dimension(2000,2000);
doubleBufferingEnabled = true;
offscreenBuffers = new WeakHashMap();
- repaintUnderway = false;
- commitRequests = new HashMap();
}
/**
@@ -398,8 +383,6 @@ public class RepaintManager
if (w <= 0 || h <= 0 || !component.isShowing())
return;
- Component parent = component.getParent();
-
component.computeVisibleRect(rectCache);
SwingUtilities.computeIntersection(x, y, w, h, rectCache);
@@ -557,7 +540,6 @@ public class RepaintManager
compileRepaintRoots(dirtyComponentsWork, dirty, repaintRoots);
}
- repaintUnderway = true;
for (Iterator i = repaintRoots.iterator(); i.hasNext();)
{
JComponent comp = (JComponent) i.next();
@@ -567,13 +549,11 @@ public class RepaintManager
comp.paintImmediately(damaged);
}
dirtyComponentsWork.clear();
- repaintUnderway = false;
- commitRemainingBuffers();
}
-
+
/**
* Compiles a list of components that really get repainted. This is called
- * once for each component in the dirtyComponents HashMap, each time with
+ * once for each component in the dirtyRegions HashMap, each time with
* another <code>dirty</code> parameter. This searches up the component
* hierarchy of <code>dirty</code> to find the highest parent that is also
* marked dirty and merges the dirty regions.
@@ -588,6 +568,29 @@ public class RepaintManager
Component current = dirty;
Component root = dirty;
+ // This will contain the dirty region in the root coordinate system,
+ // possibly clipped by ancestor's bounds.
+ Rectangle originalDirtyRect = (Rectangle) dirtyRegions.get(dirty);
+ rectCache.setBounds(originalDirtyRect);
+
+ // The bounds of the current component.
+ int x = dirty.getX();
+ int y = dirty.getY();
+ int w = dirty.getWidth();
+ int h = dirty.getHeight();
+
+ // Do nothing if dirty region is clipped away by the component's bounds.
+ rectCache = SwingUtilities.computeIntersection(0, 0, w, h, rectCache);
+ if (rectCache.isEmpty())
+ return;
+
+ // The cumulated offsets.
+ int dx = 0;
+ int dy = 0;
+ // The actual offset for the found root.
+ int rootDx = 0;
+ int rootDy = 0;
+
// Search the highest component that is also marked dirty.
Component parent;
while (true)
@@ -597,10 +600,29 @@ public class RepaintManager
break;
current = parent;
+ // Update the offset.
+ dx += x;
+ dy += y;
+ rectCache.x += x;
+ rectCache.y += y;
+
+ x = current.getX();
+ y = current.getY();
+ w = current.getWidth();
+ h = current.getHeight();
+ rectCache = SwingUtilities.computeIntersection(0, 0, w, h, rectCache);
+
+ // Don't paint if the dirty regions is clipped away by any of
+ // its ancestors.
+ if (rectCache.isEmpty())
+ return;
+
// We can skip to the next up when this parent is not dirty.
if (dirtyRegions.containsKey(parent))
{
root = current;
+ rootDx = dx;
+ rootDy = dy;
}
}
@@ -608,15 +630,16 @@ public class RepaintManager
// the are different.
if (root != dirty)
{
- Rectangle dirtyRect = (Rectangle) dirtyRegions.get(dirty);
- dirtyRect = SwingUtilities.convertRectangle(dirty, dirtyRect, root);
- Rectangle rootRect = (Rectangle) dirtyRegions.get(root);
- SwingUtilities.computeUnion(dirtyRect.x, dirtyRect.y, dirtyRect.width,
- dirtyRect.height, rootRect);
+ rectCache.x += rootDx - dx;
+ rectCache.y += rootDy - dy;
+ Rectangle dirtyRect = (Rectangle) dirtyRegions.get(root);
+ SwingUtilities.computeUnion(rectCache.x, rectCache.y, rectCache.width,
+ rectCache.height, dirtyRect);
}
// Adds the root to the roots set.
- roots.add(root);
+ if (! roots.contains(root))
+ roots.add(root);
}
/**
@@ -643,130 +666,40 @@ public class RepaintManager
width = Math.min(doubleBufferMaximumSize.width, width);
int height = Math.max(proposedHeight, root.getHeight());
height = Math.min(doubleBufferMaximumSize.height, height);
- buffer = root.createImage(width, height);
+ buffer = component.createImage(width, height);
offscreenBuffers.put(root, buffer);
}
return buffer;
}
/**
- * Blits the back buffer of the specified root component to the screen. If
- * the RepaintManager is currently working on a paint request, the commit
- * requests are queued up and committed at once when the paint request is
- * done (by {@link #commitRemainingBuffers}). This is package private because
- * it must get called by JComponent.
+ * Blits the back buffer of the specified root component to the screen.
+ * This is package private because it must get called by JComponent.
*
* @param comp the component to be painted
- * @param area the area to paint on screen, in comp coordinates
- */
- void commitBuffer(Component comp, Rectangle area)
- {
- // Determine the component that we finally paint the buffer upon.
- // We need to paint on the nearest heavyweight component, so that Swing
- // hierarchies inside (non-window) heavyweights get painted correctly.
- // Otherwise we would end up blitting the backbuffer behind the heavyweight
- // which is wrong.
- Component root = getHeavyweightParent(comp);
- // FIXME: Optimize this.
- Rectangle rootRect = SwingUtilities.convertRectangle(comp, area, root);
-
- // We synchronize on dirtyComponents here because that is what
- // paintDirtyRegions also synchronizes on while painting.
- synchronized (dirtyComponents)
- {
- // If the RepaintManager is not currently painting, then directly
- // blit the requested buffer on the screen.
- if (true || ! repaintUnderway)
- {
- blitBuffer(root, rootRect);
- }
-
- // Otherwise queue this request up, until all the RepaintManager work
- // is done.
- else
- {
- if (commitRequests.containsKey(root))
- SwingUtilities.computeUnion(rootRect.x, rootRect.y,
- rootRect.width, rootRect.height,
- (Rectangle) commitRequests.get(root));
- else
- commitRequests.put(root, rootRect);
- }
- }
- }
-
- /**
- * Copies the buffer to the screen. Note that the root component here is
- * not necessarily the component with which the offscreen buffer is
- * associated. The offscreen buffers are always allocated for the toplevel
- * windows. However, painted is performed on lower-level heavyweight
- * components too, if they contain Swing components.
- *
- * @param root the heavyweight component to blit upon
- * @param rootRect the rectangle in the root component's coordinate space
+ * @param x the area to paint on screen, in comp coordinates
+ * @param y the area to paint on screen, in comp coordinates
+ * @param w the area to paint on screen, in comp coordinates
+ * @param h the area to paint on screen, in comp coordinates
*/
- private void blitBuffer(Component root, Rectangle rootRect)
+ void commitBuffer(Component comp, int x, int y, int w, int h)
{
- if (! root.isShowing())
- return;
-
- // Find the Window from which we use the backbuffer.
- Component bufferRoot = root;
- Rectangle bufferRect = rootRect.getBounds();
- if (!(bufferRoot instanceof Window))
+ Component root = comp;
+ while (root != null
+ && ! (root instanceof Window || root instanceof Applet))
{
- bufferRoot = SwingUtilities.getWindowAncestor(bufferRoot);
- SwingUtilities.convertRectangleToAncestor(root, rootRect, bufferRoot);
+ x += root.getX();
+ y += root.getY();
+ root = root.getParent();
}
Graphics g = root.getGraphics();
- Image buffer = (Image) offscreenBuffers.get(bufferRoot);
+ Image buffer = (Image) offscreenBuffers.get(root);
// Make sure we have a sane clip at this point.
- g.clipRect(rootRect.x, rootRect.y, rootRect.width, rootRect.height);
- g.drawImage(buffer, rootRect.x - bufferRect.x, rootRect.y - bufferRect.y,
- root);
+ g.clipRect(x, y, w, h);
+ g.drawImage(buffer, 0, 0, root);
g.dispose();
-
- }
-
- /**
- * Finds and returns the nearest heavyweight parent for the specified
- * component. If the component isn't contained inside a heavyweight parent,
- * this returns null.
- *
- * @param comp the component
- *
- * @return the nearest heavyweight parent for the specified component or
- * null if the component has no heavyweight ancestor
- */
- private Component getHeavyweightParent(Component comp)
- {
- while (comp != null && comp.isLightweight())
- comp = comp.getParent();
- return comp;
- }
-
- /**
- * Commits the queued up back buffers to screen all at once.
- */
- private void commitRemainingBuffers()
- {
- // We synchronize on dirtyComponents here because that is what
- // paintDirtyRegions also synchronizes on while painting.
- synchronized (dirtyComponents)
- {
- Set entrySet = commitRequests.entrySet();
- Iterator i = entrySet.iterator();
- while (i.hasNext())
- {
- Map.Entry entry = (Map.Entry) i.next();
- Component root = (Component) entry.getKey();
- Rectangle area = (Rectangle) entry.getValue();
- blitBuffer(root, area);
- i.remove();
- }
- }
}
/**