diff --git a/examples/src/main/java/org/piccolo2d/examples/PSwingScaleExample.java b/examples/src/main/java/org/piccolo2d/examples/PSwingScaleExample.java new file mode 100644 index 0000000..d94e05f --- /dev/null +++ b/examples/src/main/java/org/piccolo2d/examples/PSwingScaleExample.java @@ -0,0 +1,61 @@ +package org.piccolo2d.examples; + +import org.piccolo2d.PCamera; +import org.piccolo2d.PLayer; +import org.piccolo2d.PNode; +import org.piccolo2d.extras.PFrame; +import org.piccolo2d.extras.pswing.PSwing; +import org.piccolo2d.extras.pswing.PSwingCanvas; +import org.piccolo2d.util.PBounds; + +import javax.swing.JButton; +import javax.swing.JOptionPane; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Demonstrate that PSwing nodes properly receive events even when they are parented by nodes + * with extreme scales. This is an effective regression test that previously failed before fix + * applied to {@link org.piccolo2d.extras.pswing.PSwingEventHandler}. + */ +public class PSwingScaleExample extends PFrame { + + public static void main(String[] args) { + new PSwingScaleExample(); + } + + public PSwingScaleExample() { + super(PSwingScaleExample.class.getSimpleName(), false, new PSwingCanvas()); + } + + public void initialize() { + final PSwingCanvas canvas = (PSwingCanvas) getCanvas(); + final PLayer layer = canvas.getLayer(); + final PCamera camera = canvas.getCamera(); + + PNode parent = new PNode(); + parent.setPaint(Color.orange); + parent.setBounds(0, 0, 200, 200); + + JButton button = new JButton("Drink Me"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(PSwingScaleExample.this, "Thank You"); + } + }); + final PSwing ps = new PSwing(button); + centerFullBoundsIn(ps, parent.getGlobalFullBounds()); + parent.addChild(ps); + parent.scale(0.001); + + layer.addChild(parent); + + camera.animateViewToCenterBounds(ps.getGlobalFullBounds(), true, 0); + } + + private static void centerFullBoundsIn(PNode centerMe, PBounds bounds) { + centerMe.centerFullBoundsOnPoint(bounds.getCenterX(), bounds.getCenterY()); + } + +} \ No newline at end of file diff --git a/extras/src/main/java/org/piccolo2d/extras/pswing/PSwingEventHandler.java b/extras/src/main/java/org/piccolo2d/extras/pswing/PSwingEventHandler.java index c692d4f..f473f68 100644 --- a/extras/src/main/java/org/piccolo2d/extras/pswing/PSwingEventHandler.java +++ b/extras/src/main/java/org/piccolo2d/extras/pswing/PSwingEventHandler.java @@ -28,6 +28,15 @@ */ package org.piccolo2d.extras.pswing; +import org.piccolo2d.PCamera; +import org.piccolo2d.PLayer; +import org.piccolo2d.PNode; +import org.piccolo2d.event.PInputEvent; +import org.piccolo2d.event.PInputEventListener; +import org.piccolo2d.util.PAffineTransform; +import org.piccolo2d.util.PAffineTransformException; + +import javax.swing.SwingUtilities; import java.awt.Component; import java.awt.Container; import java.awt.Point; @@ -38,16 +47,6 @@ import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; -import javax.swing.SwingUtilities; - -import org.piccolo2d.PCamera; -import org.piccolo2d.PLayer; -import org.piccolo2d.PNode; -import org.piccolo2d.event.PInputEvent; -import org.piccolo2d.event.PInputEventListener; -import org.piccolo2d.util.PAffineTransform; -import org.piccolo2d.util.PAffineTransformException; - /** * Event handler to send MousePressed, MouseReleased, MouseMoved, MouseClicked, @@ -209,9 +208,12 @@ final PSwing swing = (PSwing) currentNode; final PNode grabNode = pickedNode; - point = new Point(mEvent.getX(), mEvent.getY()); - cameraToLocal(pSwingMouseEvent.getPath().getTopCamera(), point, grabNode); - prevPoint = (Point) point.clone(); + // use a floating point object to perform cameraToLocal to survive the transform math + final Point2D.Double p2d = new Point2D.Double(mEvent.getX(), mEvent.getY()); + cameraToLocal(pSwingMouseEvent.getPath().getTopCamera(), p2d, grabNode); + + point = new Point((int) p2d.getX(), (int) p2d.getY()); + prevPoint = (Point2D) p2d.clone(); // This is only partially fixed to find the deepest // component at pt. It needs to do something like