Java Graphics2D-鼠标位置缩放

Java Graphics2D-鼠标位置缩放,java,swing,zooming,graphics2d,Java,Swing,Zooming,Graphics2d,我有一张我画的jpanel。我希望能够使用鼠标滚轮进行放大和缩小,但我希望缩放到鼠标的位置,以便鼠标下的点保持不变。我找到了一些,但它们对我不起作用 通过实现所描述的内容,我非常接近于实现我想要的。这是我的密码: public class MyPanel extends JPanel { ... private double zoom = 1; private double zoom_old = 1; private int zoomPointX; private

我有一张我画的jpanel。我希望能够使用鼠标滚轮进行放大和缩小,但我希望缩放到鼠标的位置,以便鼠标下的点保持不变。我找到了一些,但它们对我不起作用

通过实现所描述的内容,我非常接近于实现我想要的。这是我的密码:

public class MyPanel extends JPanel {
...
    private double zoom = 1;
    private double zoom_old = 1;
    private int zoomPointX;
    private int zoomPointY;
...

   class CustomMouseWheelListener implements MouseWheelListener {
        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            zoomPointX = e.getX();
            zoomPointY = e.getY();
            if (e.getPreciseWheelRotation() < 0) {
                zoom -= 0.1;
            } else {
                zoom += 0.1;
            }
            if (zoom < 0.01) {
                zoom = 0.01;
            }
            repaint();
        }
    }
...
    protected void paintComponent(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        super.paintComponent(g2D);
        if (zoom != zoom_old) {
            double scalechange = zoom - zoom_old;
            zoom_old = zoom;
            double offsetX = -(zoomPointX * scalechange);
            double offsetY = -(zoomPointY * scalechange) ;
            AffineTransform at = new AffineTransform();
            at.scale(zoom, zoom);
            at.translate(offsetX, offsetY);
            g2D.setTransform(at);
        }
        a_different_class_where_i_do_some_drawing.draw(g2D);
    }

}
公共类MyPanel扩展了JPanel{
...
私人双变焦=1;
私人双变焦_old=1;
私有整数zoomPointX;
私家动物园;
...
类CustomMouseWheelListener实现MouseWheelListener{
@凌驾
已移动公共无效鼠标滚轮(鼠标滚轮事件e){
zoomPointX=e.getX();
zoomPointY=e.getY();
如果(如GetPreciseHeelRotation()<0){
缩放-=0.1;
}否则{
缩放+=0.1;
}
如果(缩放<0.01){
缩放=0.01;
}
重新油漆();
}
}
...
受保护组件(图形g){
Graphics2D g2D=(Graphics2D)g;
超级油漆组件(g2D);
如果(缩放!=缩放旧){
双缩放更改=缩放-缩放旧;
zoom_old=缩放;
双偏移量x=-(zoomPointX*scalechange);
双偏移量=-(zoomPointY*scalechange);
AffineTransform at=新的AffineTransform();
缩放(缩放、缩放);
at.translate(offsetX,offsetY);
g2D.setTransform(at);
}
一个不同的类,在这个类中,我画一些图;
}
}
这几乎是我想要的。如果我尝试缩放,我注意到鼠标的位置会被考虑在内,因此,例如,如果我将鼠标放在面板的左侧,它将在左侧大致放大。但是,它不会精确地缩放到鼠标上,因此鼠标下的点仍然会发生变化

有人能帮我修一下吗

编辑: 下面是上面代码的一张图片:我从蓝色方块上的鼠标开始,然后用鼠标滚轮滚动。如您所见,更改鼠标位置时:

我通过实现所描述的内容解决了这个问题

以下是更新的代码:

public class MyPanel extends JPanel {
...
    private double zoom = 1;
    private int zoomPointX;
    private int zoomPointY;
...

   class CustomMouseWheelListener implements MouseWheelListener {
        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            zoomPointX = e.getX();
            zoomPointY = e.getY();
            if (e.getPreciseWheelRotation() < 0) {
                zoom -= 0.1;
            } else {
                zoom += 0.1;
            }
            if (zoom < 0.01) {
                zoom = 0.01;
            }
            repaint();
        }
    }
...
    protected void paintComponent(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        super.paintComponent(g2D);
        AffineTransform at = g2D.getTransform();
        at.translate(zoomPointX, zoomPointY);
        at.scale(zoom, zoom);
        at.translate(-zoomPointX, -zoomPointY);
        g2D.setTransform(at);
        a_different_class_where_i_do_some_drawing.draw(g2D);
    }

}
公共类MyPanel扩展了JPanel{
...
私人双变焦=1;
私有整数zoomPointX;
私家动物园;
...
类CustomMouseWheelListener实现MouseWheelListener{
@凌驾
已移动公共无效鼠标滚轮(鼠标滚轮事件e){
zoomPointX=e.getX();
zoomPointY=e.getY();
如果(如GetPreciseHeelRotation()<0){
缩放-=0.1;
}否则{
缩放+=0.1;
}
如果(缩放<0.01){
缩放=0.01;
}
重新油漆();
}
}
...
受保护组件(图形g){
Graphics2D g2D=(Graphics2D)g;
超级油漆组件(g2D);
仿射变换at=g2D.getTransform();
at.translate(zoomPointX,zoomPointY);
缩放(缩放、缩放);
at.translate(-zoomPointX,-zoomPointY);
g2D.setTransform(at);
一个不同的类,在这个类中,我画一些图;
}
}