简体   繁体   English

Java动作侦听器问题

[英]Java Action Listener Issues

I have a program that animates a ball in a Jpanel. 我有一个程序可以在Jpanel中激活一个球。 I have two buttons Stop and Go. 我有两个按钮Stop and Go。 Stop stops the ball moving and go is meant for the ball to move around. 停止球停止移动并且移动意味着球移动。 In my ball class I have a boolean variable that if it is true the ball moves and if it is false the ball doesn't move. 在我的球类中,我有一个布尔变量,如果它是真的,则球移动,如果是假,则球不移动。 So I thought in my main class when I create the frame and put the ball class in the panel I could use the buttons to change the variable to false or true depending on the button press. 因此,当我创建框架并将球类放在面板中时,我想在我的主类中,我可以使用按钮将变量更改为false或true,具体取决于按下按钮。

public class BallTask extends JPanel implements ActionListener{


public static boolean run = false;

public BallTask(){
    this.setPreferredSize(new Dimension(width, height));
    Thread gameThread = new Thread() {
        public void run() {
            while (run) {

             .... working code


public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {

            JFrame window = new JFrame();
            window.setLayout(new BorderLayout());
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            window.add(new BallTask());
            JPanel buttons = new JPanel();
            JButton stop = new JButton("STOP");
            stop.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    run = false;
                }
            });
            JButton go = new JButton("GO");
            go.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    run = true;
                }
            });
            buttons.add(go);
            buttons.add(stop);
            window.add(buttons,BorderLayout.SOUTH);
            window.pack();
            window.setVisible(true);
        }
    });

The problem I have with the code is that the buttons don't actually change the boolean value in the BallTask class. 我对代码的问题是按钮实际上并没有改变BallTask​​类中的布尔值。 Any ideas? 有任何想法吗?

Look into using a javax.swing.Timer . 查看使用javax.swing.Timer Your while loop will block the EDT not allowing the button events to be dispatched. 你的while循环将阻止EDT不允许调度按钮事件。

See How to use Swing Timers . 请参见如何使用Swing Timers

With the timer, you can just use it's methods stop and start to, well, start and stop the timer. 使用计时器,您可以使用它的方法stopstart ,以及启动和停止计时器。 You can see an example here 你可以在这里看到一个例子


Here's a runnable example using a Timer with your code. 这是一个使用Timer和代码的可运行示例。 The code in the link above is cleaner, using a Ball object. 使用Ball对象,上面链接中的代码更干净。 I just threw this one together really quick 我只是把这个快速地扔到了一起

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class BallTask {

    public static boolean run = false;
    private Timer timer;
    private BallPanel ballPanel = new BallPanel();

    public BallTask() {
        timer = new Timer(30, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (ballPanel.x < 0 || ballPanel.x > ballPanel.getWidth()) {
                    ballPanel.dx = -ballPanel.dx;
                }
                if (ballPanel.y < 0 || ballPanel.y > ballPanel.getHeight()) {
                    ballPanel.dy = -ballPanel.dy;
                }
                // Adjust ball position
                ballPanel.x += ballPanel.dx;
                ballPanel.y += ballPanel.dy;
                ballPanel.repaint();
            }
        });
        JPanel buttons = new JPanel();
        JButton stop = new JButton("STOP");
        buttons.add(stop);
        stop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.stop();
            }
        });
        JButton go = new JButton("GO");
        buttons.add(go);
        go.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.start();
            }
        });

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(ballPanel);
        mainPanel.add(buttons, BorderLayout.SOUTH);

        JFrame window = new JFrame();
        window.add(mainPanel);
        window.pack();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationRelativeTo(null);
        window.setVisible(true);

    }

    private class BallPanel extends JPanel {

        private int x;
        private int y;
        int dx = 4; // Increment on ball's x-coordinate
        int dy = 4; // Increment on ball's y-coordinate
        int radius = 15; // Ball radius

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.fillOval(x, y, 30, 30);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 300);
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new BallTask();
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM