Java,Swing:工具提示和仿射变换问题
Java, Swing: tooltip and affine transformation issue
在Java中编写GUI,出现了一个有趣的问题。对于稍微长一点的代码,我深表歉意。
有 class 派生自显示上传光栅的 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);
}
}
class重新定义工具提示方式,显示光标坐标
在工具提示出现之前,鼠标单击图片按预期工作
Figure1: mouse click, without tool tip
一个圆圈出现在正确的位置。
Figure 2: drawn point mark, without tool tip
接下来,让我们在工具提示出现后重复这些步骤。鼠标点击图片
Figure 3: mouse click, tool tip appears
行为异常,点画得很远
Figure4: drawn point mark, tool tip appeared
调试代码,发现如下问题...当出现工具提示时,仿射变换中的位移比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
到
AffineTransform[[1.0, 0.0, -2303.5], [0.0, 1.0, -1794.5]]
376.0 339.0 //Cursor coordinates xc, yc
为了避免整个情况发生偏移,而不是 m02 和 m12 偏移,变换后的坐标 point.x、point.y 应该更正,添加光标坐标 + 一些东西。它是 Swing 库中的错误还是功能:-)?
非常感谢您的评论、帮助或解释...
光栅文件:test.jpg.
解决方案非常简单...
在存储点坐标之前需要调用另一个repaint()。因此,利用了鼠标点击事件之前的鼠标按下事件:
@Override
public void mousePressed(MouseEvent e) {
repaint();
}
在Java中编写GUI,出现了一个有趣的问题。对于稍微长一点的代码,我深表歉意。
有 class 派生自显示上传光栅的 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);
}
}
class重新定义工具提示方式,显示光标坐标
在工具提示出现之前,鼠标单击图片按预期工作
Figure1: mouse click, without tool tip
一个圆圈出现在正确的位置。
Figure 2: drawn point mark, without tool tip
接下来,让我们在工具提示出现后重复这些步骤。鼠标点击图片
Figure 3: mouse click, tool tip appears
行为异常,点画得很远
Figure4: drawn point mark, tool tip appeared
调试代码,发现如下问题...当出现工具提示时,仿射变换中的位移比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
到
AffineTransform[[1.0, 0.0, -2303.5], [0.0, 1.0, -1794.5]]
376.0 339.0 //Cursor coordinates xc, yc
为了避免整个情况发生偏移,而不是 m02 和 m12 偏移,变换后的坐标 point.x、point.y 应该更正,添加光标坐标 + 一些东西。它是 Swing 库中的错误还是功能:-)?
非常感谢您的评论、帮助或解释...
光栅文件:test.jpg.
解决方案非常简单...
在存储点坐标之前需要调用另一个repaint()。因此,利用了鼠标点击事件之前的鼠标按下事件:
@Override
public void mousePressed(MouseEvent e) {
repaint();
}