Zoom relative to mouse position



Hi,

I am trying to figure out how to zoom relative to the mouse pointer
position. Below, please find my sample code.

When I initially position the mouse pointer on one corner of the red
rectangle and use the mouse wheel, I am able to zoom in and out as
expected. As soon as I move the pointer position, let's say to another
corner of the red rectangle, and try to zoom in or out, my position
relative to the rectangle shifts around.

I think I may be missing a transform or two. In another attempt, in the
mouseWheelMoved method, I inverted tx from the previous iteration and
transformed the mouse position p with the inverted transform before
recalculating the new transform; but the behavior got more erratic.


Any help is greatly appreciated. What am I missing here?

Thanks.

Here is my code:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

@SuppressWarnings("serial")
public class ZoomDemo extends JPanel {

AffineTransform tx = new AffineTransform();

Rectangle2D.Double rect = new Rectangle2D.Double(100, 100, 20, 30);

public ZoomDemo() {
this.addMouseWheelListener(new ZoomHandler());
}

@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;

Path2D.Double path;
g2.setColor(Color.RED);
path = new Path2D.Double(rect, tx);
g2.draw(path);
}

private class ZoomHandler implements MouseWheelListener {

Point oldPoint = null;

double scale = 1.0;

public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {

scale += (.1 * e.getWheelRotation());
scale = Math.max(0.1, scale);
Point p = e.getPoint();

tx = AffineTransform.getTranslateInstance(p.getX(), p.getY());
tx.scale(scale, scale);
tx.translate(-p.getX(), -p.getY());

ZoomDemo.this.revalidate();
ZoomDemo.this.repaint();
}
}
}

public static void main(String[] args) {

JFrame f = new JFrame("ZoomDemo");
ZoomDemo zoomDemo = new ZoomDemo();
JScrollPane sp = new JScrollPane(zoomDemo);
f.getContentPane().add(sp);
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
.



Relevant Pages

  • Re: Zoom relative to mouse position
    ... I am trying to figure out how to zoom relative to the mouse pointer ... When I initially position the mouse pointer on one corner of the red ... I think I may be missing a transform or two. ... to scale then translate, you have to apply then in reverse order. ...
    (comp.lang.java.programmer)
  • Re: Zoom relative to mouse position
    ... The red rectangle in my code was located at 100,100 point in the initial ... view (Scale 1.0, No Translate). ... Also, where ever I try to zoom, the red ... Now if I move the mouse pointer to the ...
    (comp.lang.java.programmer)
  • Re: C# - getting binary data from .lib
    ... Use Marshal.AllocHGlobal to allocate the memory and pass this IntPtr to the ... int retCode = create(id, scale, ptrImage); ... You now control the pointer returned. ...
    (microsoft.public.dotnet.framework.interop)
  • Re: C# - getting binary data from .lib
    ... then there is a problem with the ptrImage ... int retCode = create(id, scale, ptrImage); ... You now control the pointer returned. ...
    (microsoft.public.dotnet.framework.interop)
  • Odd behavior of Swing components in a zoomable interface
    ... to the JPanel using XYConstraints--since they need to stay exactly ... label (a JComboBox), ... This works great when the zoom level is at 100%. ... being drawn in the new scale, but the editable part is still at the ...
    (comp.lang.java.gui)