summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-06-14 11:01:24 +0000
committerRoman Kennke <roman@kennke.org>2006-06-14 11:01:24 +0000
commitbaa5e0cdbb583d22d8d3faadaffbc50a3c4003e4 (patch)
tree563d2646090724010849d44ed562ba851c995627
parent022e46a46da675d62d65788e89515eb6f7fd58a6 (diff)
downloadclasspath-baa5e0cdbb583d22d8d3faadaffbc50a3c4003e4.tar.gz
2006-06-14 Roman Kennke <kennke@aicas.com>
* javax/swing/JComponent.java (isRepainting): New flag. (paintImmediately2): Set isRepainting flag. (getRoot): Removed obsolete method. (paintDoubleBuffered): Differenciate between paint calls from RepaintManager and from AWT refresh. Call RepaintManager.commitBuffer with this and local coordinates. (findOpaqueParent): Stop searching at heavyweight component. These are always opaque. (paintChildrenOptimized): Don't paint heavyweight children. These should care for themselves. (paintChildrenWithOverlap): Don't paint heavyweight children. These should care for themselves. * javax/swing/RepaintManager.java (getOffscreenBuffer): Associate offscreen buffer with toplevel windows only. (getVolatileOffscreenBuffer): Associate offscreen buffer with toplevel windows only. (getRoot): Removed obsolete method. (commitBuffer): Blit buffer on nearest heavyweight. (blitBuffer): New helper method. (getHeavyweightParent): New helper method. (commitRemainingBuffers): Call blitBuffer instead of commitBuffer. * javax/swing/SwingUtilities.java (convertRectangleToAncestor): New helper method.
-rw-r--r--ChangeLog28
-rw-r--r--javax/swing/JComponent.java57
-rw-r--r--javax/swing/RepaintManager.java136
-rw-r--r--javax/swing/SwingUtilities.java23
4 files changed, 141 insertions, 103 deletions
diff --git a/ChangeLog b/ChangeLog
index 30db29138..72c340d8e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2006-06-14 Roman Kennke <kennke@aicas.com>
+
+ * javax/swing/JComponent.java
+ (isRepainting): New flag.
+ (paintImmediately2): Set isRepainting flag.
+ (getRoot): Removed obsolete method.
+ (paintDoubleBuffered): Differenciate between paint calls from
+ RepaintManager and from AWT refresh. Call
+ RepaintManager.commitBuffer with this and local coordinates.
+ (findOpaqueParent): Stop searching at heavyweight component. These
+ are always opaque.
+ (paintChildrenOptimized): Don't paint heavyweight children. These
+ should care for themselves.
+ (paintChildrenWithOverlap): Don't paint heavyweight children. These
+ should care for themselves.
+ * javax/swing/RepaintManager.java
+ (getOffscreenBuffer): Associate offscreen buffer with toplevel
+ windows only.
+ (getVolatileOffscreenBuffer): Associate offscreen buffer with
+ toplevel windows only.
+ (getRoot): Removed obsolete method.
+ (commitBuffer): Blit buffer on nearest heavyweight.
+ (blitBuffer): New helper method.
+ (getHeavyweightParent): New helper method.
+ (commitRemainingBuffers): Call blitBuffer instead of commitBuffer.
+ * javax/swing/SwingUtilities.java
+ (convertRectangleToAncestor): New helper method.
+
2006-06-14 Raif S. Naffah <raif@swiftdsl.com.au>
* gnu/javax/security/auth/login/ConfigFileTokenizer.java: Fixed a typo.
diff --git a/javax/swing/JComponent.java b/javax/swing/JComponent.java
index 66c562d11..bb2326d69 100644
--- a/javax/swing/JComponent.java
+++ b/javax/swing/JComponent.java
@@ -671,6 +671,12 @@ public abstract class JComponent extends Container implements Serializable
static boolean isPaintingDoubleBuffered = false;
/**
+ * Indicates whether we are calling paintDoubleBuffered() from
+ * paintImmadiately (RepaintManager) or from paint() (AWT refresh).
+ */
+ static private boolean isRepainting = false;
+
+ /**
* Listeners for events other than {@link PropertyChangeEvent} are
* handled by this listener list. PropertyChangeEvents are handled in
* {@link #changeSupport}.
@@ -1855,7 +1861,7 @@ public abstract class JComponent extends Container implements Serializable
index < children.length; index++)
{
Component comp = children[index];
- if (! comp.isVisible())
+ if (! comp.isVisible() || ! comp.isLightweight())
continue;
Rectangle compBounds = comp.getBounds();
@@ -2027,7 +2033,7 @@ public abstract class JComponent extends Container implements Serializable
if (i == children.length - 1)
paintingTile = false;
- if (!children[i].isVisible())
+ if (!children[i].isVisible() || ! children[i].isLightweight())
continue;
Rectangle bounds = children[i].getBounds(rectCache);
@@ -2131,41 +2137,16 @@ public abstract class JComponent extends Container implements Serializable
*/
void paintImmediately2(Rectangle r)
{
+ isRepainting = true;
RepaintManager rm = RepaintManager.currentManager(this);
if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
paintDoubleBuffered(r);
else
paintSimple(r);
+ isRepainting = false;
}
/**
- * 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
- * and adding/removing components. 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;
- }
-
- /**
* Performs double buffered repainting.
*/
private void paintDoubleBuffered(Rectangle r)
@@ -2173,7 +2154,7 @@ public abstract class JComponent extends Container implements Serializable
RepaintManager rm = RepaintManager.currentManager(this);
// Paint on the offscreen buffer.
- Component root = getRoot(this);
+ Component root = SwingUtilities.getRoot(this);
Image buffer = rm.getVolatileOffscreenBuffer(this, root.getWidth(),
root.getHeight());
@@ -2183,7 +2164,6 @@ public abstract class JComponent extends Container implements Serializable
buffer = rm.getOffscreenBuffer(this, root.getWidth(), root.getHeight());
//Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
- Point translation = SwingUtilities.convertPoint(this, 0, 0, root);
Graphics g2 = buffer.getGraphics();
clipAndTranslateGraphics(root, this, g2);
g2.clipRect(r.x, r.y, r.width, r.height);
@@ -2191,7 +2171,14 @@ public abstract class JComponent extends Container implements Serializable
isPaintingDoubleBuffered = true;
try
{
- paint(g2);
+ if (isRepainting) // Called from paintImmediately, go through paint().
+ paint(g2);
+ else // Called from paint() (AWT refresh), don't call it again.
+ {
+ paintComponent(g2);
+ paintBorder(g2);
+ paintChildren(g2);
+ }
}
finally
{
@@ -2200,9 +2187,7 @@ public abstract class JComponent extends Container implements Serializable
}
// Paint the buffer contents on screen.
- rm.commitBuffer(root, new Rectangle(translation.x + r.x,
- translation.y + r.y, r.width,
- r.height));
+ rm.commitBuffer(this, r);
}
/**
@@ -3654,7 +3639,7 @@ public abstract class JComponent extends Container implements Serializable
{
if ((found instanceof JComponent) && ((JComponent) found).isOpaque())
break;
- else if (!(found instanceof JComponent))
+ else if (!(found instanceof JComponent) && !found.isLightweight())
break;
Container p = found.getParent();
if (p == null)
diff --git a/javax/swing/RepaintManager.java b/javax/swing/RepaintManager.java
index f95934123..a82b3163a 100644
--- a/javax/swing/RepaintManager.java
+++ b/javax/swing/RepaintManager.java
@@ -618,7 +618,7 @@ public class RepaintManager
public Image getOffscreenBuffer(Component component, int proposedWidth,
int proposedHeight)
{
- Component root = getRoot(component);
+ Component root = SwingUtilities.getWindowAncestor(component);
Image buffer = (Image) offscreenBuffers.get(root);
if (buffer == null
|| buffer.getWidth(null) < proposedWidth
@@ -635,43 +635,26 @@ public class RepaintManager
}
/**
- * 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
* 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.
*
- * @param root the component, either a Window or an Applet instance
- * @param area the area to paint on screen
+ * @param comp the component to be painted
+ * @param area the area to paint on screen, in comp coordinates
*/
- void commitBuffer(Component root, Rectangle area)
+ 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)
@@ -680,54 +663,73 @@ public class RepaintManager
// blit the requested buffer on the screen.
if (! repaintUnderway)
{
- Graphics g = root.getGraphics();
- Image buffer = (Image) offscreenBuffers.get(root);
- Rectangle clip = g.getClipBounds();
- if (clip != null)
- area = SwingUtilities.computeIntersection(clip.x, clip.y,
- clip.width, clip.height,
- area);
- int dx1 = area.x;
- int dy1 = area.y;
- int dx2 = area.x + area.width;
- int dy2 = area.y + area.height;
- // Make sure we have a sane clip at this point.
- g.clipRect(area.x, area.y, area.width, area.height);
-
- // Make sure the coordinates are inside the buffer, everything else
- // might lead to problems.
- // TODO: This code should not really be necessary, however, in fact
- // we have two issues here:
- // 1. We shouldn't get repaint requests in areas outside the buffer
- // region in the first place. This still happens for example
- // when a component is inside a JViewport, and the component has
- // a size that would reach beyond the window size.
- // 2. Graphics.drawImage() should not behave strange when trying
- // to draw regions outside the image.
- int bufferWidth = buffer.getWidth(root);
- int bufferHeight = buffer.getHeight(root);
- dx1 = Math.min(bufferWidth, dx1);
- dy1 = Math.min(bufferHeight, dy1);
- dx2 = Math.min(bufferWidth, dx2);
- dy2 = Math.min(bufferHeight, dy2);
- g.drawImage(buffer, 0, 0, root);
- g.dispose();
+ blitBuffer(root, rootRect);
}
+
// Otherwise queue this request up, until all the RepaintManager work
// is done.
else
{
if (commitRequests.containsKey(root))
- SwingUtilities.computeUnion(area.x, area.y, area.width,
- area.height,
+ SwingUtilities.computeUnion(rootRect.x, rootRect.y,
+ rootRect.width, rootRect.height,
(Rectangle) commitRequests.get(root));
else
- commitRequests.put(root, area);
+ 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
+ */
+ private void blitBuffer(Component root, Rectangle rootRect)
+ {
+ // Find the Window from which we use the backbuffer.
+ Component bufferRoot = root;
+ Rectangle bufferRect = rootRect.getBounds();
+ if (!(bufferRoot instanceof Window))
+ {
+ bufferRoot = SwingUtilities.getWindowAncestor(bufferRoot);
+ SwingUtilities.convertRectangleToAncestor(root, rootRect, bufferRoot);
+ }
+
+ Graphics g = root.getGraphics();
+ Image buffer = (Image) offscreenBuffers.get(bufferRoot);
+
+ // 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.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()
@@ -743,7 +745,7 @@ public class RepaintManager
Map.Entry entry = (Map.Entry) i.next();
Component root = (Component) entry.getKey();
Rectangle area = (Rectangle) entry.getValue();
- commitBuffer(root, area);
+ blitBuffer(root, area);
i.remove();
}
}
@@ -767,7 +769,7 @@ public class RepaintManager
public Image getVolatileOffscreenBuffer(Component comp, int proposedWidth,
int proposedHeight)
{
- Component root = getRoot(comp);
+ Component root = SwingUtilities.getWindowAncestor(comp);
Image buffer = (Image) offscreenBuffers.get(root);
if (buffer == null
|| buffer.getWidth(null) < proposedWidth
diff --git a/javax/swing/SwingUtilities.java b/javax/swing/SwingUtilities.java
index 5d02d9bb3..d7808ba60 100644
--- a/javax/swing/SwingUtilities.java
+++ b/javax/swing/SwingUtilities.java
@@ -1599,4 +1599,27 @@ public class SwingUtilities
throw new IllegalArgumentException("Unrecognised code: " + code);
}
}
+
+ /**
+ * Converts a rectangle in the coordinate system of a child component into
+ * a rectangle of one of it's Ancestors. The result is stored in the input
+ * rectangle.
+ *
+ * @param comp the child component
+ * @param r the rectangle to convert
+ * @param ancestor the ancestor component
+ */
+ static void convertRectangleToAncestor(Component comp, Rectangle r,
+ Component ancestor)
+ {
+ if (comp == ancestor)
+ return;
+
+ r.x += comp.getX();
+ r.y += comp.getY();
+
+ Component parent = comp.getParent();
+ if (parent != null && parent != ancestor)
+ convertRectangleToAncestor(parent, r, ancestor);
+ }
}