java Swing我需要在鼠标点击的地方画一个字母m

本文探讨了Java Swing中鼠标点击事件获取坐标不准确的问题,并提供了两种解决方案:一是通过重写JPanel的paint方法来修正坐标;二是利用SwingUtilities工具类进行坐标转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 这样做是错误的:
public class TestCatchClickPoint extends JFrame {
    private Point p = new Point();

    public TestCatchClickPoint() {
        setBounds(100, 0, 200, 200);
        setVisible(true);   
        JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.CENTER);

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                p = e.getPoint();
                repaint();
            }
        });

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawString("m", p.x, p.y);
    }

    public static void main(String[] args) {
        new TestCatchClickPoint();
    }
}

结果字母m出现的位置,总比鼠标点击的实际位置差一点。原因是p = e.getPoint();获取的是鼠标相对于panel的位置,但是由于重写的是jframe的paint函数,所以会按照jframe的位置来画。

  • 方案1:重写panle控件。
class MyJPanel extends JPanel{
    private Point p = new Point();

    public MyJPanel(){
        super();
    }

    public void SetP(Point p){
        this.p = p;
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawString("m", p.x, p.y);
    }
}
//事件部分依然写在外部。原因:panel本身不应该有捕获鼠标位置的行为,而是交由jframe来控制。
panel.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        p = e.getPoint();
        panel.SetP(p);
        repaint();
    }
});
  • 方案2:组件坐标转换

    方案1的做法没有灵活性。假如将JPanel换成JLabel则又得重写label。所以需要一种更简单的方法。
    此外,在那个组件中重写public void paint(Graphics g),则将坐标转化到那个组件。下文中的jframe只是个例子,可以替换成任意组件。

    1. 根据组件与窗体的相对位置来计算

      //先获取窗体的位置
      private Point winLocation = this.getLocationOnScreen();
      //捕获鼠标在屏幕上的位置
      mouseP = new Point(e.getXOnScreen(),e.getYOnScreen());
      
      //最终的位置
      p.x = mouseP.x - winLocation.x;
      p.y = mouseP.y - winLocation.y;
    2. 根据现有函数来做:javax.swing.SwingUtilities

      //将JPanel捕获的坐标转化到JFrame中的坐标
      Component source = panel;
      aPoint = e.getPoint();//鼠标在panel中的位置
      destination = jframe;
      p = SwingUtilities.convertPoint(source,aPoint,destination);
      
      //将屏幕坐标转化成JFrame中的坐标
      p = new Point(e.getXOnScreen(),e.getYOnScreen());
      SwingUtilities.convertPointFromScreen(p, jf);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值