diff --git a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java index 1fad05a..09a9619 100644 --- a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java +++ b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwing.java @@ -28,21 +28,20 @@ */ package edu.umd.cs.piccolox.pswing; -import edu.umd.cs.piccolo.PCamera; -import edu.umd.cs.piccolo.PLayer; -import edu.umd.cs.piccolo.PNode; -import edu.umd.cs.piccolo.util.PBounds; -import edu.umd.cs.piccolo.util.PPaintContext; - -import javax.swing.*; -import java.awt.*; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ContainerAdapter; import java.awt.event.ContainerEvent; -import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; @@ -51,6 +50,15 @@ import java.util.ArrayList; import java.util.Arrays; +import javax.swing.JComponent; +import javax.swing.RepaintManager; + +import edu.umd.cs.piccolo.PCamera; +import edu.umd.cs.piccolo.PLayer; +import edu.umd.cs.piccolo.PNode; +import edu.umd.cs.piccolo.util.PBounds; +import edu.umd.cs.piccolo.util.PPaintContext; + /* This message was sent to Sun on August 27, 1999 @@ -212,7 +220,7 @@ // /////Following fields are for automatic canvas/camera detection // ////////////////////////////////////////////////////////// /* - * /keep track of which nodes we've attached listeners to since no built in + * Keep track of which nodes we've attached listeners to since no built in * support in PNode */ private ArrayList listeningTo = new ArrayList(); @@ -250,13 +258,11 @@ }); component.addComponentListener(new ComponentAdapter() { - public void componentHidden(ComponentEvent e) { - System.out.println("Hiding component"); + public void componentHidden(ComponentEvent e) { setVisible(false); } - public void componentShown(ComponentEvent e) { - System.out.println("Showing component"); + public void componentShown(ComponentEvent e) { setVisible(true); } }); diff --git a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java index d4ee62e..247ec7e 100644 --- a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java +++ b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingCanvas.java @@ -43,13 +43,13 @@ */ public class PSwingCanvas extends PCanvas { public static final String SWING_WRAPPER_KEY = "Swing Wrapper"; - private SwingWrapper swingWrapper; + private ChildWrapper swingWrapper; /** * Construct a new PSwingCanvas. */ public PSwingCanvas() { - swingWrapper = new SwingWrapper(this); + swingWrapper = new ChildWrapper(); add(swingWrapper); initRepaintManager(); new PSwingEventHandler(this, getCamera()).setActive(true); @@ -71,43 +71,27 @@ return swingWrapper; } - public void addPSwing(PSwing pSwing) { + void addPSwing(PSwing pSwing) { swingWrapper.add(pSwing.getComponent()); } - public void removePSwing(PSwing pSwing) { + void removePSwing(PSwing pSwing) { swingWrapper.remove(pSwing.getComponent()); } /** * JComponent wrapper for a PSwingCanvas. Used by PSwingRepaintManager. */ - static class SwingWrapper extends JComponent { - - /** PSwingCanvas to wrap. */ - private PSwingCanvas canvas; - - + static class ChildWrapper extends JComponent { /** * Create a new JComponent wrapper for the specified PSwingCanvas. * * @param canvas PSwingCanvas to wrap */ - SwingWrapper(final PSwingCanvas canvas) { - this.canvas = canvas; + public ChildWrapper() { setSize(new Dimension(0, 0)); setPreferredSize(new Dimension(0, 0)); putClientProperty(SWING_WRAPPER_KEY, SWING_WRAPPER_KEY); - } - - - /** - * Return the PSwingCanvas this JComponent wrapper is wrapping. - * - * @return the PSwingCanvas this JComponent wrapper is wrapping - */ - PSwingCanvas getPSwingCanvas() { - return canvas; - } + } } } \ No newline at end of file diff --git a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingRepaintManager.java b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingRepaintManager.java index 72da218..54906a1 100644 --- a/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingRepaintManager.java +++ b/extras/src/main/java/edu/umd/cs/piccolox/pswing/PSwingRepaintManager.java @@ -32,6 +32,7 @@ import javax.swing.*; import java.awt.*; +import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Vector; @@ -71,127 +72,133 @@ */ public class PSwingRepaintManager extends RepaintManager { - // The components that are currently painting - // This needs to be a vector for thread safety - private Vector paintingComponents = new Vector(); + // The components that are currently painting + // This needs to be a vector for thread safety + private Vector paintingComponents = new Vector(); - /** - * Locks repaint for a particular (Swing) component displayed by PCanvas - * - * @param c The component for which the repaint is to be locked - */ - public void lockRepaint(JComponent c) { - paintingComponents.addElement(c); - } + /** + * Locks repaint for a particular (Swing) component displayed by PCanvas + * + * @param c + * The component for which the repaint is to be locked + */ + public void lockRepaint(JComponent c) { + paintingComponents.addElement(c); + } - /** - * Unlocks repaint for a particular (Swing) component displayed by PCanvas - * - * @param c The component for which the repaint is to be unlocked - */ - public void unlockRepaint(JComponent c) { - synchronized (paintingComponents) { - paintingComponents.removeElementAt(paintingComponents.lastIndexOf(c)); - } - } + /** + * Unlocks repaint for a particular (Swing) component displayed by PCanvas + * + * @param c + * The component for which the repaint is to be unlocked + */ + public void unlockRepaint(JComponent c) { + paintingComponents.remove(c); + } - /** - * Returns true if repaint is currently locked for a component and false - * otherwise - * - * @param c The component for which the repaint status is desired - * @return Whether the component is currently painting - */ - public boolean isPainting(JComponent c) { - return paintingComponents.contains(c); - } + /** + * Returns true if repaint is currently locked for a component and false + * otherwise + * + * @param c + * The component for which the repaint status is desired + * @return Whether the component is currently painting + */ + public boolean isPainting(JComponent c) { + return paintingComponents.contains(c); + } - /** - * This is the method "repaint" now calls in the Swing components. - * Overridden to capture repaint calls from those Swing components which are - * being used as Piccolo visual components and to call the Piccolo repaint - * mechanism rather than the traditional Component hierarchy repaint - * mechanism. Otherwise, behaves like the superclass. - * - * @param c Component to be repainted - * @param x X coordinate of the dirty region in the component - * @param y Y coordinate of the dirty region in the component - * @param w Width of the dirty region in the component - * @param h Height of the dirty region in the component - */ - public synchronized void addDirtyRegion(JComponent c, int x, int y, final int w, final int h) { - boolean captureRepaint = false; - JComponent capturedComponent = null; - int captureX = x, captureY = y; + /** + * This is the method "repaint" now calls in the Swing components. + * Overridden to capture repaint calls from those Swing components which are + * being used as Piccolo visual components and to call the Piccolo repaint + * mechanism rather than the traditional Component hierarchy repaint + * mechanism. Otherwise, behaves like the superclass. + * + * @param c + * Component to be repainted + * @param x + * X coordinate of the dirty region in the component + * @param y + * Y coordinate of the dirty region in the component + * @param w + * Width of the dirty region in the component + * @param h + * Height of the dirty region in the component + */ + public synchronized void addDirtyRegion(JComponent c, int x, int y, + final int w, final int h) { + boolean captureRepaint = false; + JComponent childComponent = null; - // We have to check to see if the PCanvas - // (ie. the SwingWrapper) is in the components ancestry. If so, - // we will want to capture that repaint. However, we also will - // need to translate the repaint request since the component may - // be offset inside another component. - for (Component comp = c; comp != null && comp.isLightweight() && !captureRepaint; comp = comp.getParent()) { - if (comp.getParent() instanceof PSwingCanvas.SwingWrapper) { - if (comp instanceof JComponent) { - captureRepaint = true; - capturedComponent = (JComponent) comp; - } - } - else { - // Adds to the offset since the component is nested - captureX += comp.getLocation().getX(); - captureY += comp.getLocation().getY(); - } - } + int captureX = x, captureY = y; - // Now we check to see if we should capture the repaint and act - // accordingly - if (captureRepaint) { - if (!isPainting(capturedComponent)) { - final PSwing vis = (PSwing) capturedComponent.getClientProperty(PSwing.PSWING_PROPERTY); - if (vis != null) { - final int repaintX = captureX; - final int repaintY = captureY; - Runnable repainter = new Runnable() { - public void run() { - vis.repaint(new PBounds((double) repaintX, (double) repaintY, (double) w, (double) h)); - } - }; - SwingUtilities.invokeLater(repainter); - } - } - } - else { - super.addDirtyRegion(c, x, y, w, h); - } - } + // We have to check to see if the PCanvas + // (ie. the SwingWrapper) is in the components ancestry. If so, + // we will want to capture that repaint. However, we also will + // need to translate the repaint request since the component may + // be offset inside another component. + for (Component comp = c; comp != null && comp.isLightweight(); comp = comp + .getParent()) { + if (comp.getParent() instanceof PSwingCanvas.ChildWrapper) { + captureRepaint = true; + childComponent = (JComponent) comp; + break; + } else { + // Adds to the offset since the component is nested + captureX += comp.getLocation().getX(); + captureY += comp.getLocation().getY(); + } + } - /** - * This is the method "revalidate" calls in the Swing components. Overridden - * to capture revalidate calls from those Swing components being used as - * Piccolo visual components and to update Piccolo's visual component - * wrapper bounds (these are stored separately from the Swing component). - * Otherwise, behaves like the superclass. - * - * @param invalidComponent The Swing component that needs validation - */ - public synchronized void addInvalidComponent(JComponent invalidComponent) { - final JComponent capturedComponent = invalidComponent; + // Now we check to see if we should capture the repaint and act + // accordingly + if (captureRepaint) { + if (!isPainting(childComponent)) { + dispatchRepaint(childComponent, new PBounds(captureX, captureY, w, h)); + } + } else { + super.addDirtyRegion(c, x, y, w, h); + } + } - if (capturedComponent.getParent() != null - && capturedComponent.getParent() instanceof JComponent - && ((JComponent) capturedComponent.getParent()).getClientProperty(PSwingCanvas.SWING_WRAPPER_KEY) != null) { + private void dispatchRepaint(JComponent childComponent, + final PBounds repaintBounds) { + final PSwing pSwing = (PSwing) childComponent + .getClientProperty(PSwing.PSWING_PROPERTY); - Runnable validater = new Runnable() { - public void run() { - capturedComponent.validate(); - PSwing swing = (PSwing) capturedComponent.getClientProperty(PSwing.PSWING_PROPERTY); - swing.reshape(); - } - }; - SwingUtilities.invokeLater(validater); - } - else { - super.addInvalidComponent(invalidComponent); - } - } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + pSwing.repaint(repaintBounds); + } + }); + } + + /** + * This is the method "revalidate" calls in the Swing components. Overridden + * to capture revalidate calls from those Swing components being used as + * Piccolo visual components and to update Piccolo's visual component + * wrapper bounds (these are stored separately from the Swing component). + * Otherwise, behaves like the superclass. + * + * @param invalidComponent + * The Swing component that needs validation + */ + public synchronized void addInvalidComponent(JComponent invalidComponent) { + final JComponent capturedComponent = invalidComponent; + + if (capturedComponent.getParent() == null + || !(capturedComponent.getParent() instanceof PSwingCanvas.ChildWrapper)) { + super.addInvalidComponent(invalidComponent); + } else { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + capturedComponent.validate(); + PSwing pSwing = (PSwing) capturedComponent + .getClientProperty(PSwing.PSWING_PROPERTY); + pSwing.reshape(); + } + }); + } + } } \ No newline at end of file