diff --git a/examples/edu/umd/cs/piccolo/examples/PSwingExample.java b/examples/edu/umd/cs/piccolo/examples/PSwingExample.java index 54cfd17..8dd7ba7 100644 --- a/examples/edu/umd/cs/piccolo/examples/PSwingExample.java +++ b/examples/edu/umd/cs/piccolo/examples/PSwingExample.java @@ -35,7 +35,7 @@ } } ); js.setBorder( BorderFactory.createTitledBorder( "Test JSlider" ) ); - PSwing pSwing = new PSwing( pswingCanvas, js ); + PSwing pSwing = new PSwing( js ); pSwing.translate( 100, 100 ); l.addChild( pSwing ); diff --git a/examples/edu/umd/cs/piccolo/examples/SliderExample.java b/examples/edu/umd/cs/piccolo/examples/SliderExample.java index f956ded..fbfa5ed 100644 --- a/examples/edu/umd/cs/piccolo/examples/SliderExample.java +++ b/examples/edu/umd/cs/piccolo/examples/SliderExample.java @@ -75,7 +75,7 @@ buttonPreset.setLocation( 240, 285 ); tabPanel.add( buttonPreset ); // Create a pswing object for the tab panel - swing = new PSwing( canvas, tabPanel ); + swing = new PSwing( tabPanel ); swing.translate( 0, 0 ); // Add the pswing object to the canvas canvas.getLayer().addChild( swing ); diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwing.java b/extras/edu/umd/cs/piccolox/pswing/PSwing.java index 21fccb4..3bd2e74 100644 --- a/extras/edu/umd/cs/piccolox/pswing/PSwing.java +++ b/extras/edu/umd/cs/piccolox/pswing/PSwing.java @@ -1,415 +1,546 @@ -/** - * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA - * All rights reserved. - */ -package edu.umd.cs.piccolox.pswing; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -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; -import java.io.ObjectInputStream; -import java.io.Serializable; - -import javax.swing.JComponent; -import javax.swing.RepaintManager; - -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 - - ----------------------------------------------- - - We are currently developing Piccolo, a "scenegraph" for use in 2D graphics. - One of our ultimate goals is to support Swing lightweight components - within Piccolo, whose graphical space supports arbitray affine transforms. - The challenge in this pursuit is getting the components to respond and - render properly though not actually displayed in a standard Java component - hierarchy. - - - The first issues involved making the Swing components focusable and - showing. This was accomplished by adding the Swing components to a 0x0 - JComponent which was in turn added to our main Piccolo application component. - To our good fortune, a Java component is showing merely if it and its - ancestors are showing and not based on whether it is ACTUALLY visible. - Likewise, focus in a JComponent depends merely on the component's - containing window having focus. - - - The second issue involved capturing the repaint calls on a Swing - component. Normally, for a repaint and the consequent call to - paintImmediately, a Swing component obtains the Graphics object necessary - to render itself through the Java component heirarchy. However, for Piccolo - we would like the component to render using a Graphics object that Piccolo - may have arbitrarily transformed in some way. By capturing in the - RepaintManager the repaint calls made on our special Swing components, we - are able to redirect the repaint requests through the Piccolo architecture to - put the Graphics in its proper context. Unfortunately, this means that - if the Swing component contains other Swing components, then any repaint - requests made by one of these nested components must go through - the Piccolo architecture then through the top level Swing component - down to the nested Swing component. This normally doesn't cause a - problem. However, if calling paint on one of these nested - children causes a call to repaint then an infinite loop ensues. This does - in fact happen in the Swing components that use cell renderers. Before - the cell renderer is painted, it is invalidated and consequently - repainted. We solved this problem by putting a lock on repaint calls for - a component while that component is painting. (A similar problem faced - the Swing team over this same issue. They solved it by inserting a - CellRendererPane to capture the renderer's invalidate calls.) - - - Another issue arose over the forwarding of mouse events to the Swing - components. Since our Swing components are not actually displayed on - screen in the standard manner, we must manually dispatch any MouseEvents - we want the component to receive. Hence, we needed to find the deepest - visible component at a particular location that accepts MouseEvents. - Finding the deepest visible component at a point was achieved with the - "findComponentAt" method in java.awt.Container. With the - "getListeners(Class listenerType)" method added in JDK1.3 Beta we are able - to determine if the component has any Mouse Listeners. However, we haven't - yet found a way to determine if MouseEvents have been specifically enabled - for a component. The package private method "eventEnabled" in - java.awt.Component does exactly what we want but is, of course, - inaccessible. In order to dispatch events correctly we would need a - public accessor to the method "boolean eventEnabled(AWTEvent)" in - java.awt.Component. - - - Still another issue involves the management of cursors when the mouse is - over a Swing component in our application. To the Java mechanisms, the - mouse never appears to enter the bounds of the Swing components since they - are contained by a 0x0 JComponent. Hence, we must manually change the - cursor when the mouse enters one of the Swing components in our - application. This generally works but becomes a problem if the Swing - component's cursor changes while we are over that Swing component (for - instance, if you resize a Table Column). In order to manage cursors - properly, we would need setCursor to fire property change events. - - - With the above fixes, most Swing components work. The only Swing - components that are definitely broken are ToolTips and those that rely on - JPopupMenu. In order to implement ToolTips properly, we would need to have - a method in ToolTipManager that allows us to set the current manager, as - is possible with RepaintManager. In order to implement JPopupMenu, we - will likely need to reimplement JPopupMenu to function in Piccolo with - a transformed Graphics and to insert itself in the proper place in the - Piccolo scenegraph. - -*/ - - -/** - * PSwing is used to add Swing Components to a Piccolo canvas. - *
- * Example: adding a swing JButton to a PCanvas: - *
- * PSwingCanvas canvas = new PSwingCanvas();
- * JButton button = new JButton("Button");
- * swing = new PSwing(canvas, button);
- * canvas.getLayer().addChild(swing);
- *
- *
- * NOTE: PSwing has the current limitation that it does not listen for
- * Container events. This is only an issue if you create a PSwing
- * and later add Swing components to the PSwing's component hierarchy
- * that do not have double buffering turned off or have a smaller font
- * size than the minimum font size of the original PSwing's component
- * hierarchy.
- *
- * For instance, the following bit of code will give unexpected
- * results:
- *
- * JPanel panel = new JPanel();
- * PSwing swing = new PSwing(panel);
- * JPanel newChild = new JPanel();
- * newChild.setDoubleBuffered(true);
- * panel.add(newChild);
- *
- *
- * NOTE: PSwing cannot be correctly interacted with through multiple cameras.
- * There is no support for it yet.
- *
- * NOTE: PSwing is java.io.Serializable.
- *
- * Warning: Serialized objects of this class will not be
- * compatible with future Piccolo releases. The current serialization support is
- * appropriate for short term storage or RMI between applications running the
- * same version of Piccolo. A future release of Piccolo will provide support for long
- * term persistence.
- *
- * @author Sam R. Reid
- * @author Benjamin B. Bederson
- * @author Lance E. Good
- */
-public class PSwing extends PNode implements Serializable, PropertyChangeListener {
-
-
- /**
- * Used as a hashtable key for this object in the Swing component's
- * client properties.
- */
- public static final String PSWING_PROPERTY = "PSwing";
- private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
- private static PBounds TEMP_REPAINT_BOUNDS2 = new PBounds();
- private static boolean highQualityRender = false;
-
- /**
- * The cutoff at which the Swing component is rendered greek
- */
- private double renderCutoff = 0.3;
- private JComponent component = null;
- private double minFontSize = Double.MAX_VALUE;
- private Stroke defaultStroke = new BasicStroke();
- private Font defaultFont = new Font( "Serif", Font.PLAIN, 12 );
- private BufferedImage buffer;
- private PSwingCanvas pSwingCanvas;
-
- /**
- * Constructs a new visual component wrapper for the Swing component
- * and adds the Swing component to the SwingWrapper component of
- * the PCanvas
- *
- * @param canvas The PSwingCanvas to which the Swing component will
- * be added
- * @param component The swing component to be wrapped
- */
- public PSwing( PSwingCanvas canvas, JComponent component ) {
- this.pSwingCanvas = canvas;
- this.component = component;
- component.putClientProperty( PSWING_PROPERTY, this );
- init( component );
- this.pSwingCanvas.getSwingWrapper().add( component );
- component.revalidate();
- reshape();
- }
-
- /**
- * Ensures the bounds of the underlying component are accurate, and sets the bounds of this PNode.
- */
- void reshape() {
- component.setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height );
- setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height );
- }
-
- /**
- * Determines if the Swing component should be rendered normally or
- * as a filled rectangle.
- *
- * The transform, clip, and composite will be set appropriately when this object
- * is rendered. It is up to this object to restore the transform, clip, and composite of
- * the Graphics2D if this node changes any of them. However, the color, font, and stroke are
- * unspecified by Piccolo. This object should set those things if they are used, but
- * they do not need to be restored.
- *
- * @param renderContext Contains information about current render.
- */
- public void paint( PPaintContext renderContext ) {
- Graphics2D g2 = renderContext.getGraphics();
-
- if( defaultStroke == null ) {
- defaultStroke = new BasicStroke();
- }
- g2.setStroke( defaultStroke );
-
- if( defaultFont == null ) {
- defaultFont = new Font( "Serif", Font.PLAIN, 12 );
- }
-
- g2.setFont( defaultFont );
-
- if( component.getParent() == null ) {
- pSwingCanvas.getSwingWrapper().add( component );
- component.revalidate();
- }
-
- if( shouldRenderGreek( renderContext ) ) {
- paintAsGreek( g2 );
- }
- else {
- paint( g2 );
- }
-
- }
-
- protected boolean shouldRenderGreek( PPaintContext renderContext ) {
- return ( renderContext.getScale() < renderCutoff && pSwingCanvas.getInteracting() ) ||
- minFontSize * renderContext.getScale() < 0.5;
- }
-
- /**
- * Paints the Swing component as greek.
- *
- * @param g2 The graphics used to render the filled rectangle
- */
- public void paintAsGreek( Graphics2D g2 ) {
- Color background = component.getBackground();
- Color foreground = component.getForeground();
- Rectangle2D rect = getBounds();
-
- if( background != null ) {
- g2.setColor( background );
- }
- g2.fill( rect );
-
- if( foreground != null ) {
- g2.setColor( foreground );
- }
- g2.draw( rect );
- }
-
- /**
- * Renders to a buffered image, then draws that to the screen.
- *
- * @param g2 The graphics on which to render the JComponent.
- */
- public void paint( Graphics2D g2 ) {
- if( component.getBounds().isEmpty() ) {
- // The component has not been initialized yet.
- return;
- }
-
- PSwingRepaintManager manager = (PSwingRepaintManager)RepaintManager.currentManager( component );
- manager.lockRepaint( component );
-
- if( buffer == null || buffer.getWidth() != component.getWidth() || buffer.getHeight() != component.getHeight() )
- {
- buffer = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB );
- }
- else {
- Graphics2D bufferedGraphics = buffer.createGraphics();
- bufferedGraphics.setBackground( Color.black );
- bufferedGraphics.clipRect( 0, 0, component.getWidth(), component.getHeight() );
- }
- Graphics2D bufferedGraphics = buffer.createGraphics();
-
- //optionally prepare buffered graphics for better rendering.
- if( highQualityRender ) {
- bufferedGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
- bufferedGraphics.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
- }
-
- component.paint( bufferedGraphics );
- Object origHint = g2.getRenderingHint( RenderingHints.KEY_INTERPOLATION );
- g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
- g2.drawRenderedImage( buffer, IDENTITY_TRANSFORM );
- if( origHint != null ) {
- g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, origHint );
- }
- else {
- g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR );
- }
-
- manager.unlockRepaint( component );
- }
-
- /**
- * Repaints the specified portion of this visual component
- * Note that the input parameter may be modified as a result of this call.
- *
- * @param repaintBounds
- */
- public void repaint( PBounds repaintBounds ) {
- Shape sh = getTransform().createTransformedShape( repaintBounds );
- TEMP_REPAINT_BOUNDS2.setRect( sh.getBounds2D() );
- repaintFrom( TEMP_REPAINT_BOUNDS2, this );
- }
-
- /**
- * Sets the Swing component's bounds to its preferred bounds
- * unless it already is set to its preferred size. Also
- * updates the visual components copy of these bounds
- */
- public void computeBounds() {
- if( !component.getBounds().isEmpty() ) {
- Dimension d = component.getPreferredSize();
- getBoundsReference().setRect( 0, 0, d.getWidth(), d.getHeight() );
- if( !component.getSize().equals( d ) ) {
- component.setBounds( 0, 0, (int)d.getWidth(), (int)d.getHeight() );
- }
- }
- }
-
- /**
- * Returns the Swing component that this visual component wraps
- *
- * @return The Swing component that this visual component wraps
- */
- public JComponent getComponent() {
- return component;
- }
-
- /**
- * We need to turn off double buffering of Swing components within
- * Piccolo since all components contained within a native container
- * use the same buffer for double buffering. With normal Swing
- * widgets this is fine, but for Swing components within Piccolo this
- * causes problems. This function recurses the component tree
- * rooted at c, and turns off any double buffering in use. It also
- * updates the minimum font size based on the font size of c and adds
- * a property change listener to listen for changes to the font.
- *
- * @param c The Component to be recursively unDoubleBuffered
- */
- void init( Component c ) {
- Component[] children = null;
- if( c instanceof Container ) {
- children = ( (Container)c ).getComponents();
- }
-
- if( c.getFont() != null ) {
- minFontSize = Math.min( minFontSize, c.getFont().getSize() );
- }
-
- if( children != null ) {
- for( int j = 0; j < children.length; j++ ) {
- init( children[j] );
- }
- }
-
- if( c instanceof JComponent ) {
- ( (JComponent)c ).setDoubleBuffered( false );
- c.addPropertyChangeListener( "font", this );
- }
- }
-
- /**
- * Listens for changes in font on components rooted at this PSwing
- */
- public void propertyChange( PropertyChangeEvent evt ) {
- if( component.isAncestorOf( (Component)evt.getSource() ) &&
- ( (Component)evt.getSource() ).getFont() != null ) {
- minFontSize = Math.min( minFontSize, ( (Component)evt.getSource() ).getFont().getSize() );
- }
- }
-
- private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- init( component );
- }
-
- /**
- * Set high quality buffer rendering.
- *
- * @param highQuality
- */
- public static void setHighQualityRender( boolean highQuality ) {
- highQualityRender = highQuality;
- }
-}
+/**
+ * Copyright (C) 1998-2000 by University of Maryland, College Park, MD 20742, USA
+ * All rights reserved.
+ */
+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.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+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;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/*
+ This message was sent to Sun on August 27, 1999
+
+ -----------------------------------------------
+
+ We are currently developing Piccolo, a "scenegraph" for use in 2D graphics.
+ One of our ultimate goals is to support Swing lightweight components
+ within Piccolo, whose graphical space supports arbitray affine transforms.
+ The challenge in this pursuit is getting the components to respond and
+ render properly though not actually displayed in a standard Java component
+ hierarchy.
+
+
+ The first issues involved making the Swing components focusable and
+ showing. This was accomplished by adding the Swing components to a 0x0
+ JComponent which was in turn added to our main Piccolo application component.
+ To our good fortune, a Java component is showing merely if it and its
+ ancestors are showing and not based on whether it is ACTUALLY visible.
+ Likewise, focus in a JComponent depends merely on the component's
+ containing window having focus.
+
+
+ The second issue involved capturing the repaint calls on a Swing
+ component. Normally, for a repaint and the consequent call to
+ paintImmediately, a Swing component obtains the Graphics object necessary
+ to render itself through the Java component heirarchy. However, for Piccolo
+ we would like the component to render using a Graphics object that Piccolo
+ may have arbitrarily transformed in some way. By capturing in the
+ RepaintManager the repaint calls made on our special Swing components, we
+ are able to redirect the repaint requests through the Piccolo architecture to
+ put the Graphics in its proper context. Unfortunately, this means that
+ if the Swing component contains other Swing components, then any repaint
+ requests made by one of these nested components must go through
+ the Piccolo architecture then through the top level Swing component
+ down to the nested Swing component. This normally doesn't cause a
+ problem. However, if calling paint on one of these nested
+ children causes a call to repaint then an infinite loop ensues. This does
+ in fact happen in the Swing components that use cell renderers. Before
+ the cell renderer is painted, it is invalidated and consequently
+ repainted. We solved this problem by putting a lock on repaint calls for
+ a component while that component is painting. (A similar problem faced
+ the Swing team over this same issue. They solved it by inserting a
+ CellRendererPane to capture the renderer's invalidate calls.)
+
+
+ Another issue arose over the forwarding of mouse events to the Swing
+ components. Since our Swing components are not actually displayed on
+ screen in the standard manner, we must manually dispatch any MouseEvents
+ we want the component to receive. Hence, we needed to find the deepest
+ visible component at a particular location that accepts MouseEvents.
+ Finding the deepest visible component at a point was achieved with the
+ "findComponentAt" method in java.awt.Container. With the
+ "getListeners(Class listenerType)" method added in JDK1.3 Beta we are able
+ to determine if the component has any Mouse Listeners. However, we haven't
+ yet found a way to determine if MouseEvents have been specifically enabled
+ for a component. The package private method "eventEnabled" in
+ java.awt.Component does exactly what we want but is, of course,
+ inaccessible. In order to dispatch events correctly we would need a
+ public accessor to the method "boolean eventEnabled(AWTEvent)" in
+ java.awt.Component.
+
+
+ Still another issue involves the management of cursors when the mouse is
+ over a Swing component in our application. To the Java mechanisms, the
+ mouse never appears to enter the bounds of the Swing components since they
+ are contained by a 0x0 JComponent. Hence, we must manually change the
+ cursor when the mouse enters one of the Swing components in our
+ application. This generally works but becomes a problem if the Swing
+ component's cursor changes while we are over that Swing component (for
+ instance, if you resize a Table Column). In order to manage cursors
+ properly, we would need setCursor to fire property change events.
+
+
+ With the above fixes, most Swing components work. The only Swing
+ components that are definitely broken are ToolTips and those that rely on
+ JPopupMenu. In order to implement ToolTips properly, we would need to have
+ a method in ToolTipManager that allows us to set the current manager, as
+ is possible with RepaintManager. In order to implement JPopupMenu, we
+ will likely need to reimplement JPopupMenu to function in Piccolo with
+ a transformed Graphics and to insert itself in the proper place in the
+ Piccolo scenegraph.
+
+*/
+
+
+/**
+ * PSwing is used to add Swing Components to a Piccolo canvas.
+ *
+ * Example: adding a swing JButton to a PCanvas:
+ *
+ * PSwingCanvas canvas = new PSwingCanvas();
+ * JButton button = new JButton("Button");
+ * swing = new PSwing(canvas, button);
+ * canvas.getLayer().addChild(swing);
+ *
+ *
+ * NOTE: PSwing has the current limitation that it does not listen for
+ * Container events. This is only an issue if you create a PSwing
+ * and later add Swing components to the PSwing's component hierarchy
+ * that do not have double buffering turned off or have a smaller font
+ * size than the minimum font size of the original PSwing's component
+ * hierarchy.
+ *
+ * For instance, the following bit of code will give unexpected
+ * results:
+ *
+ * JPanel panel = new JPanel();
+ * PSwing swing = new PSwing(panel);
+ * JPanel newChild = new JPanel();
+ * newChild.setDoubleBuffered(true);
+ * panel.add(newChild);
+ *
+ *
+ * NOTE: PSwing cannot be correctly interacted with through multiple cameras.
+ * There is no support for it yet.
+ *
+ * NOTE: PSwing is java.io.Serializable.
+ *
+ * Warning: Serialized objects of this class will not be
+ * compatible with future Piccolo releases. The current serialization support is
+ * appropriate for short term storage or RMI between applications running the
+ * same version of Piccolo. A future release of Piccolo will provide support for long
+ * term persistence.
+ *
+ * @author Sam R. Reid
+ * @author Benjamin B. Bederson
+ * @author Lance E. Good
+ *
+ * 3-23-2007 edited to automatically detect PCamera/PSwingCanvas to allow single-arg constructor usage
+ */
+public class PSwing extends PNode implements Serializable, PropertyChangeListener {
+
+
+ /**
+ * Used as a hashtable key for this object in the Swing component's
+ * client properties.
+ */
+ public static final String PSWING_PROPERTY = "PSwing";
+ private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
+ private static PBounds TEMP_REPAINT_BOUNDS2 = new PBounds();
+
+ /**
+ * The cutoff at which the Swing component is rendered greek
+ */
+ private double renderCutoff = 0.3;
+ private JComponent component = null;
+ private double minFontSize = Double.MAX_VALUE;
+ private Stroke defaultStroke = new BasicStroke();
+ private Font defaultFont = new Font( "Serif", Font.PLAIN, 12 );
+ private BufferedImage buffer;
+ private static final Color BUFFER_BACKGROUND_COLOR = new Color( 0, 0, 0, 0 );
+ private PSwingCanvas canvas;
+
+ ////////////////////////////////////////////////////////////
+ ///////Following fields are for automatic canvas/camera detection
+ ////////////////////////////////////////////////////////////
+ /*/keep track of which nodes we've attached listeners to since no built in support in PNode*/
+ private ArrayList listeningTo = new ArrayList();
+
+ /*The parent listener for camera/canvas changes*/
+ private PropertyChangeListener parentListener = new PropertyChangeListener() {
+ public void propertyChange( PropertyChangeEvent evt ) {
+ PNode source = (PNode)evt.getSource();
+ PNode parent = source.getParent();
+ if( parent != null ) {
+ listenForCanvas( parent );
+ }
+
+ }
+ };
+
+ /**
+ * Constructs a new visual component wrapper for the Swing component.
+ *
+ * @param component The swing component to be wrapped
+ */
+ public PSwing(JComponent component) {
+ this.component = component;
+ component.putClientProperty( PSWING_PROPERTY, this );
+ init( component );
+ component.revalidate();
+ component.addPropertyChangeListener( new PropertyChangeListener() {
+ public void propertyChange( PropertyChangeEvent evt ) {
+ reshape();
+ }
+ } );
+ reshape();
+ listenForCanvas( this );
+ }
+
+ /**
+ * Deprecated constructor for application code still depending on this signature.
+ * @param pSwingCanvas
+ * @param component
+ * @deprecated
+ */
+ public PSwing(PSwingCanvas pSwingCanvas, JComponent component) {
+ this(component);
+ }
+
+ /**
+ * Ensures the bounds of the underlying component are accurate, and sets the bounds of this PNode.
+ */
+ void reshape() {
+ component.setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height );
+ setBounds( 0, 0, component.getPreferredSize().width, component.getPreferredSize().height );
+ }
+
+ /**
+ * Determines if the Swing component should be rendered normally or
+ * as a filled rectangle.
+ *
+ * The transform, clip, and composite will be set appropriately when this object
+ * is rendered. It is up to this object to restore the transform, clip, and composite of
+ * the Graphics2D if this node changes any of them. However, the color, font, and stroke are
+ * unspecified by Piccolo. This object should set those things if they are used, but
+ * they do not need to be restored.
+ *
+ * @param renderContext Contains information about current render.
+ */
+ public void paint( PPaintContext renderContext ) {
+ Graphics2D g2 = renderContext.getGraphics();
+
+ if( defaultStroke == null ) {
+ defaultStroke = new BasicStroke();
+ }
+ g2.setStroke( defaultStroke );
+
+ if( defaultFont == null ) {
+ defaultFont = new Font( "Serif", Font.PLAIN, 12 );
+ }
+
+ g2.setFont( defaultFont );
+
+ if( component.getParent() == null ) {
+// pSwingCanvas.getSwingWrapper().add( component );
+ component.revalidate();
+ }
+
+ if( shouldRenderGreek( renderContext ) ) {
+ paintAsGreek( g2 );
+ }
+ else {
+ paint( g2 );
+ }
+
+ }
+
+ protected boolean shouldRenderGreek( PPaintContext renderContext ) {
+ return ( renderContext.getScale() < renderCutoff
+// && pSwingCanvas.getInteracting()
+ ) ||
+ minFontSize * renderContext.getScale() < 0.5;
+ }
+
+ /**
+ * Paints the Swing component as greek.
+ *
+ * @param g2 The graphics used to render the filled rectangle
+ */
+ public void paintAsGreek( Graphics2D g2 ) {
+ Color background = component.getBackground();
+ Color foreground = component.getForeground();
+ Rectangle2D rect = getBounds();
+
+ if( background != null ) {
+ g2.setColor( background );
+ }
+ g2.fill( rect );
+
+ if( foreground != null ) {
+ g2.setColor( foreground );
+ }
+ g2.draw( rect );
+ }
+
+ /**
+ * Remove from the SwingWrapper; throws an exception if no canvas is associated with this PSwing.
+ */
+ public void removeFromSwingWrapper() {
+ if( canvas != null && Arrays.asList( this.canvas.getSwingWrapper().getComponents() ).contains( component ) ) {
+ this.canvas.getSwingWrapper().remove( component );
+ }
+ }
+
+ /**
+ * Renders to a buffered image, then draws that image to the
+ * drawing surface associated with g2 (usually the screen).
+ *
+ * @param g2 graphics context for rendering the JComponent
+ */
+ public void paint( Graphics2D g2 ) {
+ if( component.getBounds().isEmpty() ) {
+ // The component has not been initialized yet.
+ return;
+ }
+
+ PSwingRepaintManager manager = (PSwingRepaintManager)RepaintManager.currentManager( component );
+ manager.lockRepaint( component );
+
+ Graphics2D bufferedGraphics = null;
+ if( !isBufferValid() ) {
+ // Get the graphics context associated with a new buffered image.
+ // Use TYPE_INT_ARGB_PRE so that transparent components look good on Windows.
+ buffer = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE );
+ bufferedGraphics = buffer.createGraphics();
+ }
+ else {
+ // Use the graphics context associated with the existing buffered image
+ bufferedGraphics = buffer.createGraphics();
+ // Clear the buffered image to prevent artifacts on Macintosh
+ bufferedGraphics.setBackground( BUFFER_BACKGROUND_COLOR );
+ bufferedGraphics.clearRect( 0, 0, component.getWidth(), component.getHeight() );
+ }
+
+ // Start with the rendering hints from the provided graphics context
+ bufferedGraphics.setRenderingHints( g2.getRenderingHints() );
+
+ //PSwing sometimes causes JComponent text to render with "..." when fractional font metrics are enabled. These are now always disabled for the offscreen buffer.
+ bufferedGraphics.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF );
+
+ // Draw the component to the buffer
+ component.paint( bufferedGraphics );
+
+ // Draw the buffer to g2's associated drawing surface
+ g2.drawRenderedImage( buffer, IDENTITY_TRANSFORM );
+
+ manager.unlockRepaint( component );
+ }
+
+ /**
+ * Tells whether the buffer for the image of the Swing components
+ * is currently valid.
+ *
+ * @return true if the buffer is currently valid
+ */
+ private boolean isBufferValid() {
+ return !( buffer == null || buffer.getWidth() != component.getWidth() || buffer.getHeight() != component.getHeight() );
+ }
+
+ /**
+ * Repaints the specified portion of this visual component
+ * Note that the input parameter may be modified as a result of this call.
+ *
+ * @param repaintBounds
+ */
+ public void repaint( PBounds repaintBounds ) {
+ Shape sh = getTransform().createTransformedShape( repaintBounds );
+ TEMP_REPAINT_BOUNDS2.setRect( sh.getBounds2D() );
+ repaintFrom( TEMP_REPAINT_BOUNDS2, this );
+ }
+
+ /**
+ * Sets the Swing component's bounds to its preferred bounds
+ * unless it already is set to its preferred size. Also
+ * updates the visual components copy of these bounds
+ */
+ public void computeBounds() {
+ reshape();
+// if( !component.getBounds().isEmpty() ) {
+// Dimension d = component.getPreferredSize();
+// getBoundsReference().setRect( 0, 0, d.getWidth(), d.getHeight() );
+// if( !component.getSize().equals( d ) ) {
+// component.setBounds( 0, 0, (int)d.getWidth(), (int)d.getHeight() );
+// }
+// }
+ }
+
+ /**
+ * Returns the Swing component that this visual component wraps
+ *
+ * @return The Swing component that this visual component wraps
+ */
+ public JComponent getComponent() {
+ return component;
+ }
+
+ /**
+ * We need to turn off double buffering of Swing components within
+ * Piccolo since all components contained within a native container
+ * use the same buffer for double buffering. With normal Swing
+ * widgets this is fine, but for Swing components within Piccolo this
+ * causes problems. This function recurses the component tree
+ * rooted at c, and turns off any double buffering in use. It also
+ * updates the minimum font size based on the font size of c and adds
+ * a property change listener to listen for changes to the font.
+ *
+ * @param c The Component to be recursively unDoubleBuffered
+ */
+ void init( Component c ) {
+ Component[] children = null;
+ if( c instanceof Container ) {
+ children = ( (Container)c ).getComponents();
+ }
+
+ if( c.getFont() != null ) {
+ minFontSize = Math.min( minFontSize, c.getFont().getSize() );
+ }
+
+ if( children != null ) {
+ for( int j = 0; j < children.length; j++ ) {
+ init( children[j] );
+ }
+ }
+
+ if( c instanceof JComponent ) {
+ ( (JComponent)c ).setDoubleBuffered( false );
+ c.addPropertyChangeListener( "font", this );
+ c.addComponentListener( new ComponentAdapter() {
+ public void componentResized( ComponentEvent e ) {
+ computeBounds();
+ }
+
+ public void componentShown( ComponentEvent e ) {
+ computeBounds();
+ }
+ } );
+ }
+ }
+
+ /**
+ * Listens for changes in font on components rooted at this PSwing
+ */
+ public void propertyChange( PropertyChangeEvent evt ) {
+ if( component.isAncestorOf( (Component)evt.getSource() ) &&
+ ( (Component)evt.getSource() ).getFont() != null ) {
+ minFontSize = Math.min( minFontSize, ( (Component)evt.getSource() ).getFont().getSize() );
+ }
+ }
+
+ private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ init( component );
+ }
+
+ ////////////////////////////////////////////////////////////
+ ///////Start methods for automatic canvas detection
+ ////////////////////////////////////////////////////////////
+ /**
+ * Attaches a listener to the specified node and all its parents to listen
+ * for a change in the PSwingCanvas. Only PROPERTY_PARENT listeners are added
+ * so this code wouldn't handle if a PLayer were viewed by a different PCamera
+ * since that constitutes a child change.
+ * @param node The child node at which to begin a parent-based traversal for adding listeners.
+ */
+ private void listenForCanvas( PNode node ) {
+ //need to get the full tree for this node
+ PNode p = node;
+ while( p != null ) {
+ listenToNode( p );
+
+ PNode parent = p;
+// System.out.println( "parent = " + parent.getClass() );
+ if( parent instanceof PLayer ) {
+ PLayer player = (PLayer)parent;
+// System.out.println( "Found player: with " + player.getCameraCount() + " cameras" );
+ for( int i = 0; i < player.getCameraCount(); i++ ) {
+ PCamera cam = player.getCamera( i );
+ if( cam.getComponent() instanceof PSwingCanvas ) {
+ updateCanvas( (PSwingCanvas)cam.getComponent() );
+ break;
+ }
+ }
+ }
+ p = p.getParent();
+ }
+ }
+
+ /**
+ * Attach a listener to the specified node, if one has not already been attached.
+ * @param node the node to listen to for parent/pcamera/pcanvas changes
+ */
+ private void listenToNode( PNode node ) {
+// System.out.println( "listeningTo.size() = " + listeningTo.size() );
+ if( !listeningTo( node ) ) {
+ listeningTo.add( node );
+ node.addPropertyChangeListener( PNode.PROPERTY_PARENT, parentListener );
+ }
+ }
+
+ /**
+ * Determine whether this PSwing is already listening to the specified node for camera/canvas changes.
+ * @param node the node to check
+ * @return true if this PSwing is already listening to the specified node for camera/canvas changes
+ */
+ private boolean listeningTo( PNode node ) {
+ for( int i = 0; i < listeningTo.size(); i++ ) {
+ PNode pNode = (PNode)listeningTo.get( i );
+ if( pNode == node ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes this PSwing from previous PSwingCanvas (if any), and ensure that this PSwing is attached to the new PSwingCanvas.
+ * @param newCanvas the new PSwingCanvas (may be null)
+ */
+ private void updateCanvas( PSwingCanvas newCanvas ) {
+ if( newCanvas != canvas ) {
+ if( canvas != null ) {
+ canvas.removePSwing( this );
+ }
+ if( newCanvas != null ) {
+ canvas = newCanvas;
+ canvas.addPSwing( this );
+ reshape();
+ repaint();
+ canvas.invalidate();
+ canvas.revalidate();
+ canvas.repaint();
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ ///////End methods for automatic canvas detection
+ ////////////////////////////////////////////////////////////
+}
diff --git a/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java b/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
index 8f6ecd6..d7263f8 100644
--- a/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
+++ b/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java
@@ -1,65 +1,73 @@
-/* Copyright 2003-2005, University of Colorado */
-
-/*
- * CVS Info -
- * Filename : $Source: /fs/cvs/piccolo/piccolo/extras/edu/umd/cs/piccolox/pswing/PSwingCanvas.java,v $
- * Branch : $Name: $
- * Modified by : $Author: jesse $
- * Revision : $Revision: 1.1 $
- * Date modified : $Date: 2006/01/05 16:54:26 $
- */
-package edu.umd.cs.piccolox.pswing;
-
-import edu.umd.cs.piccolo.PCanvas;
-
-import javax.swing.*;
-import java.awt.*;
-
-/**
- * The PSwingCanvas is a PCanvas that can display Swing components with the PSwing adapter.
- *
- * @author Benjamin B. Bederson
- * @author Sam R. Reid
- * @author Lance E. Good
- */
-
-public class PSwingCanvas extends PCanvas {
- public static final String SWING_WRAPPER_KEY = "Swing Wrapper";
- private static PSwingRepaintManager pSwingRepaintManager = new PSwingRepaintManager();
-
- private SwingWrapper swingWrapper;
- private PSwingEventHandler swingEventHandler;
-
- /**
- * Construct a new PSwingCanvas.
- */
- public PSwingCanvas() {
- swingWrapper = new SwingWrapper( this );
- add( swingWrapper );
- RepaintManager.setCurrentManager( pSwingRepaintManager );
- pSwingRepaintManager.addPSwingCanvas( this );
-
- swingEventHandler = new PSwingEventHandler( this, getCamera() );//todo or maybe getCameraLayer() or getRoot()?
- swingEventHandler.setActive( true );
- }
-
- JComponent getSwingWrapper() {
- return swingWrapper;
- }
-
- static class SwingWrapper extends JComponent {
- private PSwingCanvas pSwingCanvas;
-
- public SwingWrapper( PSwingCanvas pSwingCanvas ) {
- this.pSwingCanvas = pSwingCanvas;
- setSize( new Dimension( 0, 0 ) );
- setPreferredSize( new Dimension( 0, 0 ) );
- putClientProperty( SWING_WRAPPER_KEY, SWING_WRAPPER_KEY );
- }
-
- public PSwingCanvas getpSwingCanvas() {
- return pSwingCanvas;
- }
- }
-
+/* Copyright 2003-2005, University of Colorado */
+
+/*
+ * CVS Info -
+ * Filename : $Source$
+ * Branch : $Name$
+ * Modified by : $Author: samreid $
+ * Revision : $Revision: 13998 $
+ * Date modified : $Date: 2007-03-22 17:51:34 -0600 (Thu, 22 Mar 2007) $
+ */
+package edu.umd.cs.piccolox.pswing;
+
+import edu.umd.cs.piccolo.PCanvas;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * The PSwingCanvas is a PCanvas that can display Swing components with the PSwing adapter.
+ *
+ * @author Benjamin B. Bederson
+ * @author Sam R. Reid
+ * @author Lance E. Good
+ */
+
+public class PSwingCanvas extends PCanvas {
+ public static final String SWING_WRAPPER_KEY = "Swing Wrapper";
+ private static PSwingRepaintManager pSwingRepaintManager = new PSwingRepaintManager();
+
+ private SwingWrapper swingWrapper;
+ private PSwingEventHandler swingEventHandler;
+
+ /**
+ * Construct a new PSwingCanvas.
+ */
+ public PSwingCanvas() {
+ swingWrapper = new SwingWrapper( this );
+ add( swingWrapper );
+ RepaintManager.setCurrentManager( pSwingRepaintManager );
+ pSwingRepaintManager.addPSwingCanvas( this );
+
+ swingEventHandler = new PSwingEventHandler( this, getCamera() );//todo or maybe getCameraLayer() or getRoot()?
+ swingEventHandler.setActive( true );
+ }
+
+ JComponent getSwingWrapper() {
+ return swingWrapper;
+ }
+
+ public void addPSwing( PSwing pSwing ) {
+ swingWrapper.add( pSwing.getComponent() );
+ }
+
+ public void removePSwing( PSwing pSwing ) {
+ swingWrapper.remove( pSwing.getComponent() );
+ }
+
+ private static class SwingWrapper extends JComponent {
+ private PSwingCanvas pSwingCanvas;
+
+ public SwingWrapper( PSwingCanvas pSwingCanvas ) {
+ this.pSwingCanvas = pSwingCanvas;
+ setSize( new Dimension( 0, 0 ) );
+ setPreferredSize( new Dimension( 0, 0 ) );
+ putClientProperty( SWING_WRAPPER_KEY, SWING_WRAPPER_KEY );
+ }
+
+ public PSwingCanvas getpSwingCanvas() {
+ return pSwingCanvas;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwing.java b/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwing.java
index becd62a..6bc08e1 100644
--- a/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwing.java
+++ b/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwing.java
@@ -1,134 +1,134 @@
-package edu.umd.cs.piccolox.pswing.tests;
-
-import edu.umd.cs.piccolo.PNode;
-import edu.umd.cs.piccolo.event.PZoomEventHandler;
-import edu.umd.cs.piccolo.nodes.PText;
-import edu.umd.cs.piccolox.pswing.PComboBox;
-import edu.umd.cs.piccolox.pswing.PSwing;
-import edu.umd.cs.piccolox.pswing.PSwingCanvas;
-
-import javax.swing.*;
-import javax.swing.border.LineBorder;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-/**
- * User: Sam Reid
- * Date: Jul 11, 2005
- * Time: 12:15:55 PM
- * Copyright (c) Jul 11, 2005 by Sam Reid
- */
-
-public class TestPSwing {
- public static void main( String[] args ) {
- PSwingCanvas pCanvas = new PSwingCanvas();
- final PText pText = new PText( "PText" );
- pCanvas.getLayer().addChild( pText );
- JFrame frame = new JFrame( "Test Piccolo" );
-
- frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
- frame.setContentPane( pCanvas );
- frame.setSize( 600, 800 );
- frame.setVisible( true );
-
- PText text2 = new PText( "Text2" );
- text2.setFont( new Font( "Lucida Sans", Font.BOLD, 18 ) );
- pCanvas.getLayer().addChild( text2 );
- text2.translate( 100, 100 );
- text2.addInputEventListener( new PZoomEventHandler() );
-
- pCanvas.removeInputEventListener( pCanvas.getPanEventHandler() );
-
- JButton jButton = new JButton( "MyButton!" );
- jButton.addActionListener( new ActionListener() {
- public void actionPerformed( ActionEvent e ) {
- System.out.println( "TestZSwing.actionPerformed!!!!!!!!!!!!!!*********************" );
- }
- } );
- final PSwing pSwing = new PSwing( pCanvas, jButton );
- pCanvas.getLayer().addChild( pSwing );
- pSwing.repaint();
-
- JSpinner jSpinner = new JSpinner();
- jSpinner.setPreferredSize( new Dimension( 100, jSpinner.getPreferredSize().height ) );
- PSwing pSpinner = new PSwing( pCanvas, jSpinner );
- pCanvas.getLayer().addChild( pSpinner );
- pSpinner.translate( 0, 150 );
-
- JCheckBox jcb = new JCheckBox( "CheckBox", true );
- jcb.addActionListener( new ActionListener() {
- public void actionPerformed( ActionEvent e ) {
- System.out.println( "TestZSwing.JCheckBox.actionPerformed" );
- }
- } );
- jcb.addChangeListener( new ChangeListener() {
- public void stateChanged( ChangeEvent e ) {
- System.out.println( "TestPSwing.JChekbox.stateChanged@" + System.currentTimeMillis() );
- }
- } );
- PSwing pCheckBox = new PSwing( pCanvas, jcb );
- pCanvas.getLayer().addChild( pCheckBox );
- pCheckBox.translate( 100, 0 );
-
- // Growable JTextArea
- JTextArea textArea = new JTextArea( "This is a growable TextArea.\nTry it out!" );
- textArea.setBorder( new LineBorder( Color.blue, 3 ) );
- PSwing swing = new PSwing( pCanvas, textArea );
- swing.translate( 150, 150 );
- pCanvas.getLayer().addChild( swing );
-
- // A Slider
- JSlider slider = new JSlider();
- PSwing pSlider = new PSwing( pCanvas, slider );
- pSlider.translate( 200, 200 );
- pCanvas.getLayer().addChild( pSlider );
-
- // A Scrollable JTree
- JTree tree = new JTree();
- tree.setEditable( true );
- JScrollPane p = new JScrollPane( tree );
- p.setPreferredSize( new Dimension( 150, 150 ) );
- PSwing pTree = new PSwing( pCanvas, p );
- pCanvas.getLayer().addChild( pTree );
- pTree.translate( 0, 250 );
-
- // A JColorChooser - also demonstrates JTabbedPane
- JColorChooser chooser = new JColorChooser();
- PSwing pChooser = new PSwing( pCanvas, chooser );
- pCanvas.getLayer().addChild( pChooser );
- pChooser.translate( 100, 300 );
-
- JPanel myPanel = new JPanel();
- myPanel.setBorder( BorderFactory.createTitledBorder( "Titled Border" ) );
- myPanel.add( new JCheckBox( "CheckBox" ) );
- PSwing panelSwing = new PSwing( pCanvas, myPanel );
- pCanvas.getLayer().addChild( panelSwing );
- panelSwing.translate( 400, 50 );
-
- // A Slider
- JSlider slider2 = new JSlider();
- PSwing pSlider2 = new PSwing( pCanvas, slider2 );
- pSlider2.translate( 200, 200 );
- PNode root = new PNode();
- root.addChild( pSlider2 );
- root.scale( 1.5 );
- root.rotate( Math.PI / 4 );
- root.translate( 300, 200 );
- pCanvas.getLayer().addChild( root );
-
- String[] listItems = {"Summer Teeth", "Mermaid Avenue", "Being There", "A.M."};
- PComboBox box = new PComboBox( listItems );
- swing = new PSwing( pCanvas, box );
- swing.translate( 200, 250 );
- pCanvas.getLayer().addChild( swing );
- box.setEnvironment( swing, pCanvas );//has to be done manually at present
-
- // Revalidate and repaint
- pCanvas.revalidate();
- pCanvas.repaint();
- }
-
-}
+package edu.umd.cs.piccolox.pswing.tests;
+
+import edu.umd.cs.piccolo.PNode;
+import edu.umd.cs.piccolo.event.PZoomEventHandler;
+import edu.umd.cs.piccolo.nodes.PText;
+import edu.umd.cs.piccolox.pswing.PComboBox;
+import edu.umd.cs.piccolox.pswing.PSwing;
+import edu.umd.cs.piccolox.pswing.PSwingCanvas;
+
+import javax.swing.*;
+import javax.swing.border.LineBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * User: Sam Reid
+ * Date: Jul 11, 2005
+ * Time: 12:15:55 PM
+ * Copyright (c) Jul 11, 2005 by Sam Reid
+ */
+
+public class TestPSwing {
+ public static void main( String[] args ) {
+ PSwingCanvas pCanvas = new PSwingCanvas();
+ final PText pText = new PText( "PText" );
+ pCanvas.getLayer().addChild( pText );
+ JFrame frame = new JFrame( "Test Piccolo" );
+
+ frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
+ frame.setContentPane( pCanvas );
+ frame.setSize( 600, 800 );
+ frame.setVisible( true );
+
+ PText text2 = new PText( "Text2" );
+ text2.setFont( new Font( "Lucida Sans", Font.BOLD, 18 ) );
+ pCanvas.getLayer().addChild( text2 );
+ text2.translate( 100, 100 );
+ text2.addInputEventListener( new PZoomEventHandler() );
+
+ pCanvas.removeInputEventListener( pCanvas.getPanEventHandler() );
+
+ JButton jButton = new JButton( "MyButton!" );
+ jButton.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e ) {
+ System.out.println( "TestZSwing.actionPerformed!!!!!!!!!!!!!!*********************" );
+ }
+ } );
+ final PSwing pSwing = new PSwing(jButton );
+ pCanvas.getLayer().addChild( pSwing );
+ pSwing.repaint();
+
+ JSpinner jSpinner = new JSpinner();
+ jSpinner.setPreferredSize( new Dimension( 100, jSpinner.getPreferredSize().height ) );
+ PSwing pSpinner = new PSwing(jSpinner );
+ pCanvas.getLayer().addChild( pSpinner );
+ pSpinner.translate( 0, 150 );
+
+ JCheckBox jcb = new JCheckBox( "CheckBox", true );
+ jcb.addActionListener( new ActionListener() {
+ public void actionPerformed( ActionEvent e ) {
+ System.out.println( "TestZSwing.JCheckBox.actionPerformed" );
+ }
+ } );
+ jcb.addChangeListener( new ChangeListener() {
+ public void stateChanged( ChangeEvent e ) {
+ System.out.println( "TestPSwing.JChekbox.stateChanged@" + System.currentTimeMillis() );
+ }
+ } );
+ PSwing pCheckBox = new PSwing(jcb );
+ pCanvas.getLayer().addChild( pCheckBox );
+ pCheckBox.translate( 100, 0 );
+
+ // Growable JTextArea
+ JTextArea textArea = new JTextArea( "This is a growable TextArea.\nTry it out!" );
+ textArea.setBorder( new LineBorder( Color.blue, 3 ) );
+ PSwing swing = new PSwing(textArea );
+ swing.translate( 150, 150 );
+ pCanvas.getLayer().addChild( swing );
+
+ // A Slider
+ JSlider slider = new JSlider();
+ PSwing pSlider = new PSwing(slider );
+ pSlider.translate( 200, 200 );
+ pCanvas.getLayer().addChild( pSlider );
+
+ // A Scrollable JTree
+ JTree tree = new JTree();
+ tree.setEditable( true );
+ JScrollPane p = new JScrollPane( tree );
+ p.setPreferredSize( new Dimension( 150, 150 ) );
+ PSwing pTree = new PSwing(p );
+ pCanvas.getLayer().addChild( pTree );
+ pTree.translate( 0, 250 );
+
+ // A JColorChooser - also demonstrates JTabbedPane
+ JColorChooser chooser = new JColorChooser();
+ PSwing pChooser = new PSwing(chooser );
+ pCanvas.getLayer().addChild( pChooser );
+ pChooser.translate( 100, 300 );
+
+ JPanel myPanel = new JPanel();
+ myPanel.setBorder( BorderFactory.createTitledBorder( "Titled Border" ) );
+ myPanel.add( new JCheckBox( "CheckBox" ) );
+ PSwing panelSwing = new PSwing(myPanel );
+ pCanvas.getLayer().addChild( panelSwing );
+ panelSwing.translate( 400, 50 );
+
+ // A Slider
+ JSlider slider2 = new JSlider();
+ PSwing pSlider2 = new PSwing(slider2 );
+ pSlider2.translate( 200, 200 );
+ PNode root = new PNode();
+ root.addChild( pSlider2 );
+ root.scale( 1.5 );
+ root.rotate( Math.PI / 4 );
+ root.translate( 300, 200 );
+ pCanvas.getLayer().addChild( root );
+
+ String[] listItems = {"Summer Teeth", "Mermaid Avenue", "Being There", "A.M."};
+ PComboBox box = new PComboBox( listItems );
+ swing = new PSwing(box );
+ swing.translate( 200, 250 );
+ pCanvas.getLayer().addChild( swing );
+ box.setEnvironment( swing, pCanvas );//has to be done manually at present
+
+ // Revalidate and repaint
+ pCanvas.revalidate();
+ pCanvas.repaint();
+ }
+
+}
diff --git a/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwingFull.java b/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwingFull.java
index b13408c..81768e8 100644
--- a/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwingFull.java
+++ b/extras/edu/umd/cs/piccolox/pswing/tests/TestPSwingFull.java
@@ -1,416 +1,416 @@
-package edu.umd.cs.piccolox.pswing.tests;
-
-import edu.umd.cs.piccolo.PNode;
-import edu.umd.cs.piccolox.pswing.PSwing;
-import edu.umd.cs.piccolox.pswing.PSwingCanvas;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.EtchedBorder;
-import javax.swing.border.LineBorder;
-import javax.swing.border.TitledBorder;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-import javax.swing.table.TableColumn;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.io.IOException;
-import java.util.Vector;
-
-/**
- * User: Sam Reid
- * Date: Jul 11, 2005
- * Time: 12:15:55 PM
- * Copyright (c) Jul 11, 2005 by Sam Reid
- */
-
-public class TestPSwingFull extends JFrame {
- public TestPSwingFull() {
- setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
- ClassLoader loader;
- PSwingCanvas canvas;
-
- // Set up basic frame
- setBounds( 50, 50, 750, 750 );
- setResizable( true );
- setBackground( null );
- setVisible( true );
- canvas = new PSwingCanvas();
- canvas.setPanEventHandler( null );
- getContentPane().add( canvas );
- validate();
- loader = getClass().getClassLoader();
-
- ZVisualLeaf leaf;
- PNode transform;
- PSwing swing;
- PSwing swing2;
-
- // JButton
- JButton button = new JButton( "Button" );
- button.setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
- swing = new PSwing( canvas, button );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -500, -500 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // JButton
- JSpinner spinner = new JSpinner( new SpinnerNumberModel( 0, 0, 10, 1 ) );
- spinner.setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
- swing = new PSwing( canvas, spinner );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -800, -500 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // 2nd Copy of JButton
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -450, -450 );
- transform.rotate( Math.PI / 2 );
- transform.scale( 0.5 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // Growable JTextArea
- JTextArea textArea = new JTextArea( "This is a growable TextArea.\nTry it out!" );
- textArea.setBorder( new LineBorder( Color.blue, 3 ) );
- swing = new PSwing( canvas, textArea );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -250, -500 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // Growable JTextField
- JTextField textField = new JTextField( "A growable text field" );
- swing = new PSwing( canvas, textField );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 0, -500 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // A Slider
- JSlider slider = new JSlider();
- swing = new PSwing( canvas, slider );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 250, -500 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // A Scrollable JTree
- JTree tree = new JTree();
- tree.setEditable( true );
- JScrollPane p = new JScrollPane( tree );
- p.setPreferredSize( new Dimension( 150, 150 ) );
- swing = new PSwing( canvas, p );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -500, -250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // A Scrollable JTextArea
- JScrollPane pane = new JScrollPane( new JTextArea( "A Scrollable Text Area\nTry it out!" ) );
- pane.setPreferredSize( new Dimension( 150, 150 ) );
- swing = new PSwing( canvas, pane );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -250, -250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
- swing2 = swing;
-
- // A non-scrollable JTextField
- // A panel MUST be created with double buffering off
- JPanel panel = new JPanel( false );
- textField = new JTextField( "A fixed-size text field" );
- panel.setLayout( new BorderLayout() );
- panel.add( textField );
- swing = new PSwing( canvas, panel );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 0, -250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
-// // A JComboBox
-// String[] listItems = {"Summer Teeth", "Mermaid Avenue", "Being There", "A.M."};
-// ZComboBox box = new ZComboBox( listItems );
-// swing = new PSwing( canvas, box );
-// leaf = new ZVisualLeaf( swing );
-// transform = new PNode();
-// transform.translate( 0, -150 );
-// transform.addChild( leaf );
-// canvas.getLayer().addChild( transform );
-
- // A panel with TitledBorder and JList
- panel = new JPanel( false );
- panel.setBackground( Color.lightGray );
- panel.setLayout( new BorderLayout() );
- panel.setBorder( new TitledBorder( new EtchedBorder( EtchedBorder.RAISED ), "A JList", TitledBorder.LEFT, TitledBorder.TOP ) );
- panel.setPreferredSize( new Dimension( 200, 200 ) );
- Vector data = new Vector();
- data.addElement( "Choice 1" );
- data.addElement( "Choice 2" );
- data.addElement( "Choice 3" );
- data.addElement( "Choice 4" );
- data.addElement( "Choice 5" );
- JList list = new JList( data );
- list.setBackground( Color.lightGray );
- panel.add( list );
- swing = new PSwing( canvas, panel );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 250, -250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // A JLabel
- JLabel label = new JLabel( "A JLabel", SwingConstants.CENTER );
-
- swing = new PSwing( canvas, label );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -500, 0 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // Rotated copy of the Scrollable JTextArea
- leaf = new ZVisualLeaf( swing2 );
- transform = new PNode();
- transform.translate( -100, 0 );
- transform.rotate( Math.PI / 2 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // A panel with layout
- // A panel MUST be created with double buffering off
- panel = new JPanel( false );
- panel.setLayout( new BorderLayout() );
- JButton button1 = new JButton( "Button 1" );
- JButton button2 = new JButton( "Button 2" );
- label = new JLabel( "A Panel with Layout" );
- label.setHorizontalAlignment( SwingConstants.CENTER );
- label.setForeground( Color.white );
- panel.setBackground( Color.red );
- panel.setPreferredSize( new Dimension( 150, 150 ) );
- panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
- panel.add( button1, "North" );
- panel.add( button2, "South" );
- panel.add( label, "Center" );
- panel.revalidate();
- swing = new PSwing( canvas, panel );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 0, 0 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // JTable Example
- Vector columns = new Vector();
- columns.addElement( "Check Number" );
- columns.addElement( "Description" );
- columns.addElement( "Amount" );
- Vector rows = new Vector();
- Vector row = new Vector();
- row.addElement( "101" );
- row.addElement( "Sandwich" );
- row.addElement( "$20.00" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "102" );
- row.addElement( "Monkey Wrench" );
- row.addElement( "$100.00" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "214" );
- row.addElement( "Ant farm" );
- row.addElement( "$55.00" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "215" );
- row.addElement( "Self-esteem tapes" );
- row.addElement( "$37.99" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "216" );
- row.addElement( "Tube Socks" );
- row.addElement( "$7.45" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "220" );
- row.addElement( "Ab Excerciser" );
- row.addElement( "$56.95" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "319" );
- row.addElement( "Y2K Supplies" );
- row.addElement( "$4624.33" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "332" );
- row.addElement( "Tie Rack" );
- row.addElement( "$15.20" );
- rows.addElement( row );
- row = new Vector();
- row.addElement( "344" );
- row.addElement( "Swing Set" );
- row.addElement( "$146.59" );
- rows.addElement( row );
- JTable table = new JTable( rows, columns );
- table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
- table.setRowHeight( 30 );
- TableColumn c = table.getColumn( table.getColumnName( 0 ) );
- c.setPreferredWidth( 150 );
- c = table.getColumn( table.getColumnName( 1 ) );
- c.setPreferredWidth( 150 );
- c = table.getColumn( table.getColumnName( 2 ) );
- c.setPreferredWidth( 150 );
- pane = new JScrollPane( table );
- pane.setPreferredSize( new Dimension( 200, 200 ) );
- table.setDoubleBuffered( false );
- swing = new PSwing( canvas, pane );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 250, 0 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // JEditorPane - HTML example
- try {
-
-
- final JEditorPane editorPane = new JEditorPane( loader.getResource( "csdept.html" ) );
- editorPane.setDoubleBuffered( false );
- editorPane.setEditable( false );
- pane = new JScrollPane( editorPane );
- pane.setDoubleBuffered( false );
- pane.setPreferredSize( new Dimension( 400, 400 ) );
- editorPane.addHyperlinkListener( new HyperlinkListener() {
- public void hyperlinkUpdate( HyperlinkEvent e ) {
- if( e.getEventType() == HyperlinkEvent.EventType.ACTIVATED ) {
- try {
- editorPane.setPage( e.getURL() );
- }
- catch( IOException ioe ) {
- System.out.println( "Couldn't Load Web Page" );
- }
- }
- }
- } );
- swing = new PSwing( canvas, pane );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -500, 250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- }
- catch( IOException ioe ) {
- System.out.println( "Couldn't Load Web Page" );
- }
-
- // A JInternalFrame with a JSplitPane - a JOptionPane - and a
- // JToolBar
- JInternalFrame iframe = new JInternalFrame( "JInternalFrame" );
- iframe.getRootPane().setDoubleBuffered( false );
- ( (JComponent)iframe.getContentPane() ).setDoubleBuffered( false );
- iframe.setPreferredSize( new Dimension( 500, 500 ) );
- JTabbedPane tabby = new JTabbedPane();
- tabby.setDoubleBuffered( false );
- iframe.getContentPane().setLayout( new BorderLayout() );
- JOptionPane options = new JOptionPane( "This is a JOptionPane!",
- JOptionPane.INFORMATION_MESSAGE,
- JOptionPane.DEFAULT_OPTION );
- options.setDoubleBuffered( false );
- options.setMinimumSize( new Dimension( 50, 50 ) );
- options.setPreferredSize( new Dimension( 225, 225 ) );
- JPanel tools = new JPanel( false );
- tools.setMinimumSize( new Dimension( 150, 150 ) );
- tools.setPreferredSize( new Dimension( 225, 225 ) );
- JToolBar bar = new JToolBar();
- Action letter = new AbstractAction( "Big A!" ) {
-
- public void actionPerformed( ActionEvent e ) {
- }
- };
-
- Action hand = new AbstractAction( "Hi!" ) {
- public void actionPerformed( ActionEvent e ) {
- }
- };
- Action select = new AbstractAction( "There!" ) {
- public void actionPerformed( ActionEvent e ) {
- }
- };
-
- label = new JLabel( "A Panel with a JToolBar" );
- label.setHorizontalAlignment( SwingConstants.CENTER );
- bar.add( letter );
- bar.add( hand );
- bar.add( select );
- bar.setFloatable( false );
- bar.setBorder( new LineBorder( Color.black, 2 ) );
- tools.setLayout( new BorderLayout() );
- tools.add( bar, "North" );
- tools.add( label, "Center" );
-
- JSplitPane split = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, options, tools );
- split.setDoubleBuffered( false );
- iframe.getContentPane().add( split );
- swing = new PSwing( canvas, iframe );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( 0, 250 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
-// JMenuBar menuBar = new JMenuBar();
-// ZMenu menu = new ZMenu( "File" );
-// ZMenu sub = new ZMenu( "Export" );
-// JMenuItem gif = new JMenuItem( "Funds" );
-// sub.add( gif );
-// menu.add( sub );
-// menuBar.add( menu );
-// iframe.setJMenuBar( menuBar );
-
- iframe.setVisible( true );
-
- // A JColorChooser - also demonstrates JTabbedPane
-// JColorChooser chooser = new JColorChooser();
- JCheckBox chooser = new JCheckBox( "Check Box" );
- swing = new PSwing( canvas, chooser );
- leaf = new ZVisualLeaf( swing );
- transform = new PNode();
- transform.translate( -250, 850 );
- transform.addChild( leaf );
- canvas.getLayer().addChild( transform );
-
- // Revalidate and repaint
- canvas.revalidate();
- canvas.repaint();
-
- PSwing message = new PSwing( canvas, new JTextArea( "Click-drag to zoom in and out." ) );
- message.translate( 0, -50 );
- canvas.getLayer().addChild( message );
-
- canvas.getCamera().animateViewToCenterBounds( message.getFullBounds(), false, 1200 );
- }
-
- public static void main( String[] args ) {
- new TestPSwingFull().setVisible( true );
- }
-
- public static class ZVisualLeaf extends PNode {
- public ZVisualLeaf( PNode node ) {
- addChild( node );
- }
- }
-
-}
+package edu.umd.cs.piccolox.pswing.tests;
+
+import edu.umd.cs.piccolo.PNode;
+import edu.umd.cs.piccolox.pswing.PSwing;
+import edu.umd.cs.piccolox.pswing.PSwingCanvas;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.table.TableColumn;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * User: Sam Reid
+ * Date: Jul 11, 2005
+ * Time: 12:15:55 PM
+ * Copyright (c) Jul 11, 2005 by Sam Reid
+ */
+
+public class TestPSwingFull extends JFrame {
+ public TestPSwingFull() {
+ setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
+ ClassLoader loader;
+ PSwingCanvas canvas;
+
+ // Set up basic frame
+ setBounds( 50, 50, 750, 750 );
+ setResizable( true );
+ setBackground( null );
+ setVisible( true );
+ canvas = new PSwingCanvas();
+ canvas.setPanEventHandler( null );
+ getContentPane().add( canvas );
+ validate();
+ loader = getClass().getClassLoader();
+
+ ZVisualLeaf leaf;
+ PNode transform;
+ PSwing swing;
+ PSwing swing2;
+
+ // JButton
+ JButton button = new JButton( "Button" );
+ button.setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
+ swing = new PSwing(button );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -500, -500 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // JButton
+ JSpinner spinner = new JSpinner( new SpinnerNumberModel( 0, 0, 10, 1 ) );
+ spinner.setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
+ swing = new PSwing(spinner );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -800, -500 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // 2nd Copy of JButton
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -450, -450 );
+ transform.rotate( Math.PI / 2 );
+ transform.scale( 0.5 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // Growable JTextArea
+ JTextArea textArea = new JTextArea( "This is a growable TextArea.\nTry it out!" );
+ textArea.setBorder( new LineBorder( Color.blue, 3 ) );
+ swing = new PSwing(textArea );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -250, -500 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // Growable JTextField
+ JTextField textField = new JTextField( "A growable text field" );
+ swing = new PSwing(textField );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 0, -500 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // A Slider
+ JSlider slider = new JSlider();
+ swing = new PSwing(slider );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 250, -500 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // A Scrollable JTree
+ JTree tree = new JTree();
+ tree.setEditable( true );
+ JScrollPane p = new JScrollPane( tree );
+ p.setPreferredSize( new Dimension( 150, 150 ) );
+ swing = new PSwing(p );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -500, -250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // A Scrollable JTextArea
+ JScrollPane pane = new JScrollPane( new JTextArea( "A Scrollable Text Area\nTry it out!" ) );
+ pane.setPreferredSize( new Dimension( 150, 150 ) );
+ swing = new PSwing(pane );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -250, -250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+ swing2 = swing;
+
+ // A non-scrollable JTextField
+ // A panel MUST be created with double buffering off
+ JPanel panel = new JPanel( false );
+ textField = new JTextField( "A fixed-size text field" );
+ panel.setLayout( new BorderLayout() );
+ panel.add( textField );
+ swing = new PSwing(panel );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 0, -250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+// // A JComboBox
+// String[] listItems = {"Summer Teeth", "Mermaid Avenue", "Being There", "A.M."};
+// ZComboBox box = new ZComboBox( listItems );
+// swing = new PSwing( canvas, box );
+// leaf = new ZVisualLeaf( swing );
+// transform = new PNode();
+// transform.translate( 0, -150 );
+// transform.addChild( leaf );
+// canvas.getLayer().addChild( transform );
+
+ // A panel with TitledBorder and JList
+ panel = new JPanel( false );
+ panel.setBackground( Color.lightGray );
+ panel.setLayout( new BorderLayout() );
+ panel.setBorder( new TitledBorder( new EtchedBorder( EtchedBorder.RAISED ), "A JList", TitledBorder.LEFT, TitledBorder.TOP ) );
+ panel.setPreferredSize( new Dimension( 200, 200 ) );
+ Vector data = new Vector();
+ data.addElement( "Choice 1" );
+ data.addElement( "Choice 2" );
+ data.addElement( "Choice 3" );
+ data.addElement( "Choice 4" );
+ data.addElement( "Choice 5" );
+ JList list = new JList( data );
+ list.setBackground( Color.lightGray );
+ panel.add( list );
+ swing = new PSwing(panel );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 250, -250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // A JLabel
+ JLabel label = new JLabel( "A JLabel", SwingConstants.CENTER );
+
+ swing = new PSwing(label );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -500, 0 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // Rotated copy of the Scrollable JTextArea
+ leaf = new ZVisualLeaf( swing2 );
+ transform = new PNode();
+ transform.translate( -100, 0 );
+ transform.rotate( Math.PI / 2 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // A panel with layout
+ // A panel MUST be created with double buffering off
+ panel = new JPanel( false );
+ panel.setLayout( new BorderLayout() );
+ JButton button1 = new JButton( "Button 1" );
+ JButton button2 = new JButton( "Button 2" );
+ label = new JLabel( "A Panel with Layout" );
+ label.setHorizontalAlignment( SwingConstants.CENTER );
+ label.setForeground( Color.white );
+ panel.setBackground( Color.red );
+ panel.setPreferredSize( new Dimension( 150, 150 ) );
+ panel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
+ panel.add( button1, "North" );
+ panel.add( button2, "South" );
+ panel.add( label, "Center" );
+ panel.revalidate();
+ swing = new PSwing(panel );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 0, 0 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // JTable Example
+ Vector columns = new Vector();
+ columns.addElement( "Check Number" );
+ columns.addElement( "Description" );
+ columns.addElement( "Amount" );
+ Vector rows = new Vector();
+ Vector row = new Vector();
+ row.addElement( "101" );
+ row.addElement( "Sandwich" );
+ row.addElement( "$20.00" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "102" );
+ row.addElement( "Monkey Wrench" );
+ row.addElement( "$100.00" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "214" );
+ row.addElement( "Ant farm" );
+ row.addElement( "$55.00" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "215" );
+ row.addElement( "Self-esteem tapes" );
+ row.addElement( "$37.99" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "216" );
+ row.addElement( "Tube Socks" );
+ row.addElement( "$7.45" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "220" );
+ row.addElement( "Ab Excerciser" );
+ row.addElement( "$56.95" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "319" );
+ row.addElement( "Y2K Supplies" );
+ row.addElement( "$4624.33" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "332" );
+ row.addElement( "Tie Rack" );
+ row.addElement( "$15.20" );
+ rows.addElement( row );
+ row = new Vector();
+ row.addElement( "344" );
+ row.addElement( "Swing Set" );
+ row.addElement( "$146.59" );
+ rows.addElement( row );
+ JTable table = new JTable( rows, columns );
+ table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
+ table.setRowHeight( 30 );
+ TableColumn c = table.getColumn( table.getColumnName( 0 ) );
+ c.setPreferredWidth( 150 );
+ c = table.getColumn( table.getColumnName( 1 ) );
+ c.setPreferredWidth( 150 );
+ c = table.getColumn( table.getColumnName( 2 ) );
+ c.setPreferredWidth( 150 );
+ pane = new JScrollPane( table );
+ pane.setPreferredSize( new Dimension( 200, 200 ) );
+ table.setDoubleBuffered( false );
+ swing = new PSwing(pane );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 250, 0 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // JEditorPane - HTML example
+ try {
+
+
+ final JEditorPane editorPane = new JEditorPane( loader.getResource( "csdept.html" ) );
+ editorPane.setDoubleBuffered( false );
+ editorPane.setEditable( false );
+ pane = new JScrollPane( editorPane );
+ pane.setDoubleBuffered( false );
+ pane.setPreferredSize( new Dimension( 400, 400 ) );
+ editorPane.addHyperlinkListener( new HyperlinkListener() {
+ public void hyperlinkUpdate( HyperlinkEvent e ) {
+ if( e.getEventType() == HyperlinkEvent.EventType.ACTIVATED ) {
+ try {
+ editorPane.setPage( e.getURL() );
+ }
+ catch( IOException ioe ) {
+ System.out.println( "Couldn't Load Web Page" );
+ }
+ }
+ }
+ } );
+ swing = new PSwing(pane );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -500, 250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ }
+ catch( IOException ioe ) {
+ System.out.println( "Couldn't Load Web Page" );
+ }
+
+ // A JInternalFrame with a JSplitPane - a JOptionPane - and a
+ // JToolBar
+ JInternalFrame iframe = new JInternalFrame( "JInternalFrame" );
+ iframe.getRootPane().setDoubleBuffered( false );
+ ( (JComponent)iframe.getContentPane() ).setDoubleBuffered( false );
+ iframe.setPreferredSize( new Dimension( 500, 500 ) );
+ JTabbedPane tabby = new JTabbedPane();
+ tabby.setDoubleBuffered( false );
+ iframe.getContentPane().setLayout( new BorderLayout() );
+ JOptionPane options = new JOptionPane( "This is a JOptionPane!",
+ JOptionPane.INFORMATION_MESSAGE,
+ JOptionPane.DEFAULT_OPTION );
+ options.setDoubleBuffered( false );
+ options.setMinimumSize( new Dimension( 50, 50 ) );
+ options.setPreferredSize( new Dimension( 225, 225 ) );
+ JPanel tools = new JPanel( false );
+ tools.setMinimumSize( new Dimension( 150, 150 ) );
+ tools.setPreferredSize( new Dimension( 225, 225 ) );
+ JToolBar bar = new JToolBar();
+ Action letter = new AbstractAction( "Big A!" ) {
+
+ public void actionPerformed( ActionEvent e ) {
+ }
+ };
+
+ Action hand = new AbstractAction( "Hi!" ) {
+ public void actionPerformed( ActionEvent e ) {
+ }
+ };
+ Action select = new AbstractAction( "There!" ) {
+ public void actionPerformed( ActionEvent e ) {
+ }
+ };
+
+ label = new JLabel( "A Panel with a JToolBar" );
+ label.setHorizontalAlignment( SwingConstants.CENTER );
+ bar.add( letter );
+ bar.add( hand );
+ bar.add( select );
+ bar.setFloatable( false );
+ bar.setBorder( new LineBorder( Color.black, 2 ) );
+ tools.setLayout( new BorderLayout() );
+ tools.add( bar, "North" );
+ tools.add( label, "Center" );
+
+ JSplitPane split = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, options, tools );
+ split.setDoubleBuffered( false );
+ iframe.getContentPane().add( split );
+ swing = new PSwing(iframe );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( 0, 250 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+// JMenuBar menuBar = new JMenuBar();
+// ZMenu menu = new ZMenu( "File" );
+// ZMenu sub = new ZMenu( "Export" );
+// JMenuItem gif = new JMenuItem( "Funds" );
+// sub.add( gif );
+// menu.add( sub );
+// menuBar.add( menu );
+// iframe.setJMenuBar( menuBar );
+
+ iframe.setVisible( true );
+
+ // A JColorChooser - also demonstrates JTabbedPane
+// JColorChooser chooser = new JColorChooser();
+ JCheckBox chooser = new JCheckBox( "Check Box" );
+ swing = new PSwing(chooser );
+ leaf = new ZVisualLeaf( swing );
+ transform = new PNode();
+ transform.translate( -250, 850 );
+ transform.addChild( leaf );
+ canvas.getLayer().addChild( transform );
+
+ // Revalidate and repaint
+ canvas.revalidate();
+ canvas.repaint();
+
+ PSwing message = new PSwing(new JTextArea( "Click-drag to zoom in and out." ) );
+ message.translate( 0, -50 );
+ canvas.getLayer().addChild( message );
+
+ canvas.getCamera().animateViewToCenterBounds( message.getFullBounds(), false, 1200 );
+ }
+
+ public static void main( String[] args ) {
+ new TestPSwingFull().setVisible( true );
+ }
+
+ public static class ZVisualLeaf extends PNode {
+ public ZVisualLeaf( PNode node ) {
+ addChild( node );
+ }
+ }
+
+}