Java动作侦听器问题

时间:2014-03-13 11:44:29

标签: java swing jbutton actionlistener

我有一个程序可以在Jpanel中设置动画。我有两个按钮Stop and Go。停止球停止移动并且移动意味着球移动。在我的球类中,我有一个布尔变量,如果它是真的,则球移动,如果是假,则球不移动。因此,当我创建框架并将球类放在面板中时,我想在我的主类中,我可以使用按钮将变量更改为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);
        }
    });

我对代码的问题是按钮实际上并没有改变BallTask​​类中的布尔值。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

使用javax.swing.Timer。你的while循环将阻止EDT不允许调度按钮事件。

请参阅How to use Swing Timers

使用计时器,您可以使用它的方法stopstart来启动和停止计时器。您可以看到示例here


这是一个使用Timer代码的可运行示例。上面链接中的代码使用Ball对象更干净。我只是把这个快速地扔到了一起

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();
            }
        });
    }
}