一个按钮,用于计算一分钟内单击的次数

时间:2014-07-28 11:05:04

标签: java swing

嘿,我正在尝试使用swing构建一个程序。我已经创建了一个按钮,我想计算它在一分钟内被点击的次数。但问题是,一旦我按下按钮它就不会被释放,并且计数器继续自行增加。 代码:

    while ((System.currentTimeMillis()-startTime)< 1*60*1000)
    {   
        if(eee.getSource()==b)
            {
                counter++;  

            }
        System.out.println(counter);
    }

1 个答案:

答案 0 :(得分:2)

让我们从基础开始......

Swing是一个单线程环境,任何阻止Event Dispatching Thread运行的东西都会阻止它更新UI或响应其他事件。同样,您应该只在Event Dispatching Thread的上下文中修改UI组件的状态。

有关详细信息,请查看Concurrency in Swing

举一个简单的例子,这只是让你点击按钮,每次点击它确定是否已经过了一分钟,如果它还没有更新按钮的状态

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SmackMe {

    public static void main(String[] args) {
        new SmackMe();
    }

    public static final long ONE_MINUTE = 1000 * 60;

    private long startTime = -1;
    private int count = 0;

    public SmackMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JButton button = new JButton("Smack me");
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (startTime < 0) {
                            startTime = System.currentTimeMillis();
                        }
                        long diff = System.currentTimeMillis() - startTime;
                        System.out.println((diff / 1000));
                        if (diff >= ONE_MINUTE) {
                            startTime = -1;
                            button.setEnabled(false);
                        } else {
                            count++;
                        }
                        button.setText(Integer.toString(count));
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(button);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

问题在于,它是响应式的,它需要点击按钮才能执行时间检查,更好的解决方案会有某种后台进程,可以在一分钟后禁用按钮... < / p>

这是javax.swing.Timer ...

的完美用例
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SmackMe {

    public static void main(String[] args) {
        new SmackMe();
    }

    public static final int ONE_MINUTE = 1000 * 60;

    private int count = 0;
    private Timer timer;
    private JButton button;

    public SmackMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                button = new JButton("Smack me");
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (!timer.isRunning()) {
                            timer.start();
                        }
                        count++;
                        button.setText(Integer.toString(count));
                    }
                });

                timer = new Timer(ONE_MINUTE, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        button.setEnabled(false);
                    }
                });
                timer.setRepeats(false);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(button);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

请查看How to use Swing Timers了解更多详情......