【问题标题】:MouseListener not giving accurate mouse locationMouseListener 没有给出准确的鼠标位置
【发布时间】:2019-09-28 22:47:06
【问题描述】:

我试图在屏幕上显示一个圆圈并跟随鼠标移动。 (最终我将把它变成一个带有光线投射的游戏)我正在使用 MouseMotionListener 并尝试使用 mouseMoved 方法在我的 JPanel 中获取准确的鼠标位置。问题是,我将鼠标在屏幕上移动得越远,它变得越不准确。当我的鼠标到达底部时,它正在上方约 20 像素处绘制圆圈。这不是一个落后的东西,因为它永远不会赶上,它总是比它应该在的位置高几个像素。

我尝试过使用从 MouseEvents 调用的不同方法,也尝试过使用 MousePointerInfo,但没有一个能正常工作。当我将 JFrame 设置为未装饰时,它似乎确实有效,但显然这对于​​程序来说看起来并不好,因此我想避免这种情况。

public class Driver {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Moonlight");
        frame.setSize(700, 700);
        frame.setLocation(350, 50);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new MoonlightPanel());
        frame.setVisible(true);
    }
}


public class Panel extends JPanel {
    private BufferedImage myImage;
    private Graphics myBuffer;
    private Timer t;
    public Panel () {
        myImage = new BufferedImage(700, 700, BufferedImage.TYPE_INT_RGB);
        myBuffer = myImage.getGraphics();
        t = new Timer(0, new Listener());
        t.start();
        addMouseMotionListener(new Mouse());
    }

    private class Listener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            drawBackground();

            /*try {
                Point pos = getMousePosition();
                myBuffer.setColor(Color.WHITE);
                myBuffer.fillOval(pos.x - 10, pos.y - 10, 20, 20);
            }
            catch(NullPointerException en) {}*/

            repaint();
        }
    }

    private class Mouse implements MouseMotionListener {
        public void mouseMoved(MouseEvent e) {
            Point pos = new Point(e.getX(), e.getY());
            System.out.println(pos);
            myBuffer.setColor(Color.BLUE);
            myBuffer.fillOval(pos.x - 10, pos.y - 10, 20, 20);
        }
        public void mouseDragged(MouseEvent e) {}
    }

    public void drawBackground() {
        setBackground(Color.BLACK);
    }

    public void paintComponent(Graphics g) {
        g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);
    }
}

【问题讨论】:

  • 我认为您发布的代码有误。 public class Panel extends JPanel。不应该是public class MoonlightPanel extends JPanel 吗?
  • 你的期望和现实不匹配,你移动鼠标的速度越快,你得到的事件越少,点的距离就越远。更好的解决方案可能是跟踪列表中的所有点,并在每个点之间按顺序画一条线

标签: java mouselistener mousemotionlistener


【解决方案1】:

您的代码比它需要的复杂得多。 Panel 类成员是不必要的。您需要做的就是将鼠标位置保存在mouseMoved() 方法中——在一个类成员变量中——并在paintComponent() 方法中引用它来绘制你的蓝色圆圈。下面的代码是一个精简版,它在屏幕上显示一个跟随鼠标指针的蓝色圆圈。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

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

public class MoonLite extends JPanel implements MouseMotionListener {
    private Point pt;

    public MoonLite() {
        setBackground(Color.BLACK);
        setForeground(Color.BLUE);
        addMouseMotionListener(this);
    }

    public void mouseMoved(MouseEvent e) {
        pt = e.getPoint();
        repaint();
    }

    public void mouseDragged(MouseEvent e) {
        // Do nothing.
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (pt != null) {
            g.fillOval(pt.x - 10, pt.y - 10, 20, 20);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Moonlight");
                frame.setSize(700, 700);
                frame.setLocation(350, 50);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(new MoonLite());
                frame.setVisible(true);
            }
        });
    }
}

【讨论】:

  • 这将绘制一个移动的点,而不是一行 do,这似乎是 op 试图实现的目标
  • 问题说明:我试图在屏幕上出现一个圆圈并跟随鼠标移动,这给我的印象是OP的意图是不是 有一行点。
  • 好吧,这让我摸不着头脑,为什么他们应该使用不会被清除的 BufferedImage。如果这是操作的预期结果,那么 ? 给你 ?
  • OP贴出的原始代码给我的印象是他在试验和猜测,以得到想要的结果。这就是为什么我提供了一个精简的版本,而不是调整原始代码。我认为我们需要等待他确认我的假设。
  • 建议的精简代码可以按我的意愿工作。当我第一次学习 Java 时,我被教导使用 BufferedImage。 EventQueue 和 run 方法的意义何在?我取出了它的实现,但留下了 JFrame,它仍然有效。
猜你喜欢
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2016-06-26
  • 2022-01-27
相关资源
最近更新 更多