MouseListener не дает точное местоположение мыши - PullRequest
0 голосов
/ 11 мая 2019

Я пытаюсь, чтобы на экране появился круг и следовал за мышью.(В конце концов я собираюсь превратить это в игру с приведением лучей) Я использую 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);
    }
}

1 Ответ

1 голос
/ 11 мая 2019

Ваш код намного сложнее, чем нужно.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);
            }
        });
    }
}
...