单击最后一个按钮 + n 秒后重置计数器

Reset counter after last button click + n of seconds

我有一个计算按钮点击次数的简单代码

btn1.addActionListener(new ActionListener() {
    private int counter = 0;
    public void actionPerformed(ActionEvent e) {
        counter++;
        textOutput.setText(String.valueOf(counter));
    }
}

我想在点击最后一个按钮后 n 时间(即 1 秒)后实现计数器重置功能。

感谢您的任何想法。

我会让你为此编写自己的代码,但步骤很简单:

  • 创建一个 Swing Timer 并在其 ActionListener 中将计数重置为 0,并将其显示在 textOutput 组件中。
  • 在 Timer 的构造函数中,传入计时器延迟 int -- 无论您希望在重新设置计数之前为用户提供多长时间,以及上面的 ActionListener。
  • 通过调用 setRepeats(false) 使计时器不可重复。
  • 在按钮的 ActionListener 中,只需在设置 textOutput 的文本后在计数器上调用 restart()
  • 请注意,您不能在执行此操作时在 JButton 的 ActionListener 中声明计数器字段,因为这会过多地限制其范围,除非 按钮的 ActionListener 还具有 getter 和 setter 定时器的 ActionListener 可以调用的值的字段。

我不打算展示代码,但既然有人这样做了,我有点义务。请参阅解释代码中的注释。

Key 是 Timer 的 ActionListener。它所做的只是重置计数器

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            setCounter(0);  // this is all the timer does
        }
    }

请注意,在我的代码中,setCounter(int counter) 方法设置了 int 计数器值 并将其显示在 JLabel:

// method that sets counter value **and** displays value in JLabel
public void setCounter(int counter) {
    this.counter = counter;
    counterLabel.setText(String.valueOf(counter));
}

JButton 的 ActionListener 实际上是一个 AbstractAction class,有点像 ActionListener "on steroids"。它可以完成 ActionListener 所做的所有工作,还可以设置按钮的文本并为按钮提供助记键,并且还可以做更多的事情。它所做的只是推进计数器并在计时器上调用 restart(),就是这样:

    // ActionListener (and more) for the button
    private class ButtonPressAction extends AbstractAction {
        public ButtonPressAction(String name, int mnemonic) {
            super(name);  // text to show in button
            putValue(MNEMONIC_KEY, mnemonic);  // alt-key mnemonic key for button
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setCounter(counter + 1);  // re-sets the counter and displays it
            timer.restart();   // re-sets and runs the timer
        }
    }

整个程序:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;    
import javax.swing.*;

@SuppressWarnings("serial")
public class ResetCounter extends JPanel {
    private static final int TIMER_DELAY = 1000; // 1 second delay
    private int counter = 0;  // our counter field
    private JLabel counterLabel = new JLabel("   0   ", SwingConstants.CENTER); // label to display counter value
    private JButton button = new JButton(new ButtonPressAction("Click Me", KeyEvent.VK_C));  // our button with its AbstractAction
    private Timer timer = new Timer(TIMER_DELAY, new TimerListener()); // the Swing Timer loaded with its delay and ActionListener

    public ResetCounter() {
        // make sure timer does not repeat
        timer.setRepeats(false);

        // create JPanel to hold JLabels that give counter information
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Count:"));
        topPanel.add(counterLabel);

        // JPanel to hold the button
        JPanel midPanel = new JPanel();
        midPanel.add(button);
        int ebGap = 15; // make mid panel bigger
        midPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));

        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(midPanel, BorderLayout.CENTER);
    }

    // method that sets counter value **and** displays value in JLabel
    public void setCounter(int counter) {
        this.counter = counter;
        counterLabel.setText(String.valueOf(counter));
    }

    // ActionListener (and more) for the button
    private class ButtonPressAction extends AbstractAction {
        public ButtonPressAction(String name, int mnemonic) {
            super(name);  // text to show in button
            putValue(MNEMONIC_KEY, mnemonic);  // alt-key mnemonic key for button
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setCounter(counter + 1);  // re-sets the counter and displays it
            timer.restart();   // re-sets and runs the timer
        }
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            setCounter(0);  // this is all the timer does
        }
    }

    private static void createAndShowGui() {
        ResetCounter mainPanel = new ResetCounter();

        JFrame frame = new JFrame("ResetCounter");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGui();
        });
    }

}

Reset counter after last button click + n of seconds

如果您想自己掌握时间,可以使用Swing.Timer:

演示中,点击次数每5秒重置为0

我以大约每 1 秒的间隔为 "tick" 创建了计时器。只有在单击按钮时才会触发计时器,经过的时间 (variable int time) 将开始计时。当经过的时间等于延迟 (variable int delayInSeconds) 时,它将重置点击次数 (variable int clicks) 的计数并停止计时器。

当用户再次点击按钮时,整个过程将重复。

class MainPanel extends JPanel
{
    private Timer timer;
    private JButton btn;
    private JLabel lblTime, lblClicks;  
    private int clicks, time, delayInSeconds;

    public MainPanel(){
        setPreferredSize(new Dimension(100, 100));
        initComponents();
        addComponents();    
    }

    private void initComponents(){
        time = 0;           //elapsed time in seconds
        clicks = 0;         //clicks accumulated
        delayInSeconds = 5; //delay to reset click count

        btn = new JButton("Click me");
        btn.addActionListener(new ButtonHandler());
        lblTime = new JLabel("Elapsed time: " + time);
        lblClicks = new JLabel("Num of Clicks:" + clicks);          
        timer = new Timer(1000, new ActionListener(){  
            @Override
            public void actionPerformed(ActionEvent e){             
                time ++;                
                if(time >= delayInSeconds){
                    clicks = 0;
                    time = 0;                   
                    timer.stop();                   
                }
                updateDisplay();                
            }               
        });                     
    }

    private void addComponents(){
        add(lblTime);
        add(lblClicks);
        add(btn);                   
    }

    private void updateDisplay(){
        lblClicks.setText("Num of Clicks: " + clicks);
        lblTime.setText("Elapsed time: " + time);
    }

    private class ButtonHandler implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e){
            clicks ++;  //gather clicks
            time = 0;   //reset time count
            timer.start();
            updateDisplay();
        }
    }
}

跑者class 驱动代码:

class ClickCounter{
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                JFrame frame = new JFrame("Click Counter");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new MainPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);             
            }
        });
    }
}

注意:如果你打算用这个来检测双击或三次点击。 Swing 已经为您实现了这个特性。你可以只使用 e.getClickCount():

@Override
public void mouseClicked(MouseEvent e){
    if(e.getClickCount() == 2)      
        System.out.println(“double click”);
}