Java,Swing:工具提示和仿射变换问题

时间:2023-02-09 11:12:36

Writing GUI in Java, an interesting problem has appeared. I apologize for a slightly longer code.

用Java编写GUI,出现了一个有趣的问题。我为稍微长一点的代码道歉。

There is class Graphic derived from JPanel which displays uploaded raster. It implements several features with the raster data including the zoom operations. It also supports a mouse click event which stores coordinates of a point and displays it over the raster. The raster is fitted with the affine transformation.

从JPanel派生的类图形显示上传的栅格。它使用包含缩放操作的栅格数据实现了多个功能。它还支持鼠标单击事件,该事件存储点的坐标并将其显示在栅格上。光栅配有仿射变换。

 import java.awt.*;
 import java.awt.event.*;
 import java.awt.geom.*;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.util.Locale;
 import javax.imageio.ImageIO;
 import javax.swing.*;

 public class Graphic extends JPanel{

    private BufferedImage image; 
    private AffineTransform trans;
    Point2D.Double point;

    public Graphic () {
            try {image = ImageIO.read(new File("e:/Work/test.jpg"));}
            catch (Exception e) {}
            trans = new AffineTransform();
            trans.translate(0, 0);
            trans.scale(1, 1);
            point = new Point2D.Double(0,0);
            this.setToolTipText("");

            addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                            point.x = (e.getPoint().getX() - trans.getTranslateX()) / trans.getScaleX();
                            point.y = (e.getPoint().getY() - trans.getTranslateY()) / trans.getScaleY();
                            System.out.println(trans);  //Print affine transformation parameters
                            System.out.println(e.getPoint().getX() + " " + e.getPoint().getY()); //Cursor coordinates
                            repaint();
                    } 
            });
    }

    protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            if (image != null ){    
                    trans = g2d.getTransform();
                    Dimension size = this.getVisibleRect().getSize();
                    double sx = (size.getWidth() - image.getWidth()) / 2;
                    double sy = (size.getHeight() - image.getHeight()) / 2;
                    trans.translate(sx, sy);
                    g2d.setTransform(trans);
                    g2d.drawImage(image, 0, 0, this);        
                    g2d.fillOval((int)point.x - 10, (int)point.y - 10,  20,  20);
                    g2d.dispose();
            }
    }

    @Override
    public String getToolTipText(MouseEvent e) { 
            double x = (e.getX() - trans.getTranslateX()) / trans.getScaleX();
            double y = (e.getY() - trans.getTranslateY()) / trans.getScaleY();
            return String.format(Locale.ROOT, "%2.2f", x) + "  " + String.format(Locale.ROOT, "%3.2f", y); 
    }

    public static void main(String[] args){
            JFrame f = new JFrame();
            f.setSize(800, 600);
            f.add(new Graphic());
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

The class redefines the tool tip method and displays coordinates of the cursor.

该类重新定义了工具提示方法并显示了光标的坐标。

Before a tool tip appears the mouse click into the picture works as expected

在出现工具提示之前,鼠标单击图片可以正常工作

Figure1: mouse click, without tool tip

图1:鼠标点击,没有工具提示

a circle appears at the right location.

一个圆圈出现在正确的位置。

Figure 2: drawn point mark, without tool tip

图2:绘制的点标记,没有工具尖端

Subsequently, let us repeat theses steps after a tool tip appears. The mouse click at the picture

随后,让我们在工具提示出现后重复这些步骤。鼠标点击图片

Figure 3: mouse click, tool tip appears

图3:鼠标单击,出现工具提示

behaves unexpectedly, and the point is drawn far away.

表现出乎意料,而且这一点很遥远。

Figure4: drawn point mark, tool tip appeared

图4:绘制的点标记,工具提示出现

Debugging the code, the following problem has has been found... When a tool tip appears, the shift ratios sx=mo2, sy=m12 in the affine transformation change from

调试代码,已发现以下问题...当出现工具提示时,仿射变换中的移位比sx = mo2,sy = m12从

AffineTransform[[1.0, 0.0, -1927.5], [0.0, 1.0, -1435.1]]
379.0 339.0  //Cursor coordinates xc, yc

to

AffineTransform[[1.0, 0.0, -2303.5], [0.0, 1.0, -1794.5]]
376.0 339.0  //Cursor coordinates xc, yc

To avoid a shift of the entire situation, instead m02 and m12 shifts, the transformed coordinates point.x, point.y should be corrected adding cursor coordinates + something. Is it a bug in the Swing library or a feature :-) ?

为了避免整个情况的移位,而是m02和m12移位,应该校正变换后的坐标point.x,point.y,添加光标坐标+东西。它是Swing库中的一个错误还是一个功能:-)?

Thanks for very much for your comments, help or explanation...

非常感谢您的评论,帮助或解释......

The raster file: test.jpg.

光栅文件:test.jpg。

1 个解决方案

#1


1  

The solution is surprisingly simple...

解决方案非常简单......

It is necessary to call another repaint() before coordinates of a point are stored. Therefore, the mouse press event foregoing the mouse click event is utilized:

在存储点的坐标之前,必须调用另一个repaint()。因此,利用鼠标点击事件之前的鼠标按压事件:

@Override
public void mousePressed(MouseEvent e) {
    repaint();
}

#1


1  

The solution is surprisingly simple...

解决方案非常简单......

It is necessary to call another repaint() before coordinates of a point are stored. Therefore, the mouse press event foregoing the mouse click event is utilized:

在存储点的坐标之前,必须调用另一个repaint()。因此,利用鼠标点击事件之前的鼠标按压事件:

@Override
public void mousePressed(MouseEvent e) {
    repaint();
}