diff options
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java')
-rw-r--r-- | libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java | 156 |
1 files changed, 133 insertions, 23 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java index 96ccc00b8f0..bfa14dddee3 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java @@ -42,6 +42,7 @@ import java.awt.AWTException; import java.awt.BufferCapabilities; import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; @@ -62,6 +63,10 @@ import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; +import java.awt.peer.LightweightPeer; + +import javax.swing.JComponent; +import javax.swing.RepaintManager; /** * The base class for Swing based component peers. This provides the basic @@ -97,9 +102,18 @@ public class SwingComponentPeer protected SwingComponent swingComponent; /** + * The font that is set for this peer. + */ + protected Font peerFont; + + /** + * The current repaint area. + */ + protected Rectangle paintArea; + + /** * Creates a SwingComponentPeer instance. Subclasses are expected to call - * this constructor and thereafter call - * {@link #init(Component,SwingComponent)} + * this constructor and thereafter call {@link #init(Component, JComponent)} * in order to setup the AWT and Swing components properly. */ protected SwingComponentPeer() @@ -118,6 +132,38 @@ public class SwingComponentPeer { awtComponent = awtComp; swingComponent = swingComp; + if (swingComponent != null) + { + JComponent c = swingComponent.getJComponent(); + if (c != null) + { + c.addNotify(); + RepaintManager.currentManager(c).setDoubleBufferingEnabled(false); + System.setProperty("gnu.awt.swing.doublebuffering", "true"); + } + } + + // Register this heavyweight component with the nearest heavyweight + // container, so we get peerPaint() triggered by that container. + if (! (this instanceof LightweightPeer)) + { + Component comp = awtComponent; + Container parent = comp.getParent(); + while (parent != null && + ! (parent.getPeer() instanceof SwingContainerPeer)) + { + comp = parent; + parent = comp.getParent(); + } + + // At this point we have the ancestor with a SwingContainerPeer + // (or null peer). + if (parent != null && parent.getPeer() instanceof SwingContainerPeer) + { + SwingContainerPeer p = (SwingContainerPeer) parent.getPeer(); + p.addHeavyweightDescendent(awtComponent); + } + } } /** @@ -185,6 +231,28 @@ public class SwingComponentPeer */ public void dispose() { + // Unregister this heavyweight component from the nearest heavyweight + // container. + if (! (this instanceof LightweightPeer)) + { + Component comp = awtComponent; + Container parent = comp.getParent(); + while (parent != null && + ! (parent.getPeer() instanceof SwingContainerPeer)) + { + comp = parent; + parent = comp.getParent(); + } + + // At this point we have the ancestor with a SwingContainerPeer + // (or null peer). + if (parent != null && parent.getPeer() instanceof SwingContainerPeer) + { + SwingContainerPeer p = (SwingContainerPeer) parent.getPeer(); + p.removeHeavyweightDescendent(awtComponent); + } + } + awtComponent = null; swingComponent = null; } @@ -244,8 +312,7 @@ public class SwingComponentPeer public Graphics getGraphics() { Component parent = awtComponent.getParent(); - ComponentPeer parentPeer = parent.getPeer(); - Graphics g = parentPeer.getGraphics(); + Graphics g = parent.getGraphics(); g.translate(awtComponent.getX(), awtComponent.getY()); g.setClip(0, 0, awtComponent.getWidth(), awtComponent.getHeight()); return g; @@ -331,23 +398,28 @@ public class SwingComponentPeer { case PaintEvent.UPDATE: case PaintEvent.PAINT: - // This only will work when the component is showing. - if (awtComponent.isShowing()) + // Need to synchronize to avoid threading problems on the + // paint event list. + // We must synchronize on the tree lock first to avoid deadlock, + // because Container.paint() will grab it anyway. + synchronized (this) { - Graphics g = getGraphics(); - Rectangle clip = ((PaintEvent)e).getUpdateRect(); - g.clipRect(clip.x, clip.y, clip.width, clip.height); - //if (this instanceof LightweightPeer) - // { - if (e.getID() == PaintEvent.UPDATE) - awtComponent.update(g); - else - awtComponent.paint(g); - // } - // We paint the 'heavyweights' at last, so that they appear on top of - // everything else. - peerPaint(g); - g.dispose(); + assert paintArea != null; + if (awtComponent.isShowing()) + { + Graphics g = awtComponent.getGraphics(); + try + { + Rectangle clip = paintArea; + g.clipRect(clip.x, clip.y, clip.width, clip.height); + peerPaint(g, e.getID() == PaintEvent.UPDATE); + } + finally + { + g.dispose(); + paintArea = null; + } + } } break; case MouseEvent.MOUSE_PRESSED: @@ -451,9 +523,15 @@ public class SwingComponentPeer return retVal; } + /** + * Paints the component. This is triggered by + * {@link Component#paintAll(Graphics)}. + * + * @param graphics the graphics to paint with + */ public void paint(Graphics graphics) { - // FIXME: I don't know what this method is supposed to do. + peerPaint(graphics, false); } /** @@ -634,6 +712,7 @@ public class SwingComponentPeer */ public void setFont(Font font) { + peerFont = font; if (swingComponent != null) swingComponent.getJComponent().setFont(font); } @@ -741,7 +820,14 @@ public class SwingComponentPeer */ public void coalescePaintEvent(PaintEvent e) { - // Nothing to do here yet. + synchronized (this) + { + Rectangle newRect = e.getUpdateRect(); + if (paintArea == null) + paintArea = newRect; + else + Rectangle.union(paintArea, newRect, paintArea); + } } /** @@ -947,9 +1033,33 @@ public class SwingComponentPeer * paint() on the Swing component. * * @param g the graphics context to use for painting + * @param update wether we need to call update or paint on the AWT component + */ + protected void peerPaint(Graphics g, boolean update) + { + peerPaintComponent(g); + + Graphics userGraphics = g.create(); + try{ + if (update) + awtComponent.update(userGraphics); + else + awtComponent.paint(userGraphics); + } finally { + userGraphics.dispose(); + } + + } + + /** + * Paints the actual 'heavyweight' swing component, if there is one + * associated to this peer. + * + * @param g the graphics to paint the component with */ - protected void peerPaint(Graphics g) + protected void peerPaintComponent(Graphics g) { + // Paint the actual Swing component if this peer has one. if (swingComponent != null) swingComponent.getJComponent().paint(g); } |