首页 > 解决方案 > 每次单击时如何随机更改图形位置

问题描述

我制作的代码不会在每次点击球时改变球的坐标。

public class AimTrainerPanel extends JPanel implements MouseListener {
    
    static final int WIDTH = 1300;
    static final int HEIGHT = 750;
    static final int SIZE = 10;
    Random rand;
    JLabel cd;
    int x;
    int y;
    boolean running = false;
    Timer timer;
    
    AimTrainerPanel() {
        rand = new Random();
        this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        this.setBackground(Color.black);
        this.setFocusable(true);
        this.setLayout(null);
        this.addMouseListener(this);
        startGame();
    }
    
    public void startGame() {
        newDot();
        running = true;
        timer = new Timer();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        draw(g);
    }
    
    public void draw(Graphics g) {
        if (running) {
            g.setColor(Color.white);
            g.fillOval(x, y, SIZE, SIZE);
        }
    }
    
    public void newDot() {
        x = rand.nextInt((int)(WIDTH/SIZE)) * SIZE;
        y = rand.nextInt((int)(HEIGHT/SIZE)) * SIZE;
    }
    
    @Override
    public void mouseClicked(MouseEvent e) {
        int mx = e.getX();
        int my = e.getY();
        if (mx >= x && mx <= x + 10) {
            if (my >= y && my <= y + 10) {
                newDot();
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

newDot() 方法假设每次调用时都会创建新坐标,但球不会改变位置。我不知道是因为我写错了什么,还是因为我所做的没有改变坐标,或者我想添加一些东西。

标签: javaswinguser-interfacegraphicsmouse

解决方案


我不确定你的 Timer 应该做什么,但它似乎不是一个 Swing Timer,因为这是一个 Swing GUI,我会摆脱它。

现在解决问题的症结所在:

  • 如果鼠标在按下鼠标和释放鼠标之间稍微移动,则您正在使用mouseClickedwhich 不会被调用,因此通常最好使用or方法而不是mousePressedmouseReleasedmouseClicked
  • repaint()更改程序状态后不要调用。除非您建议,否则 Swing 不会知道需要重新绘制,因此在您的 mouseListener 或由它调用的代码中,您应该在更改 GUI 状态后调用此方法。在这里,您可以在方法结束时调用它,也可以在newDot(...)调用相同方法后在鼠标侦听器中调用它。
  • 您的鼠标侦听器中的 if 块似乎对它们允许侦听器响应鼠标单击的位置非常严格——是不是太严格了?我不知道,因为我不熟悉您的要求,但可能。

推荐阅读