javaswingtimerawtedt

How to discard/coalesce repeated AWT events?


When a user does some action (such as click a button), I need to display the status in the JLabel. This status needs to disappear after 2 seconds. I use the following for that.

Timer timer = new Timer(2000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
                label.setVisible(false);
        }
    });

However, it is possible that the user clicks the button many times and this timer is triggered multiple times. This has an undesirable effect. When a button is clicked 3 times for instances.

0th second: 1st click : label disppear at 2nd second

1st second: 2nd click : label disppear at 3rd second

2nd second: 3rd click : label disppear at 4th second

Here, the label needs to disappear after the 4th second but will disappear after 2nd second. Therefore, I want this label to be hidden with a delay of 2s after only the last event

To handle this, I use an atomic counter.

AtomicInteger counter = new AtomicInteger(0);

Each task is given a unique 'taskCounter' using counter.incrementAndGet()

.

  Timer timer = new Timer(5000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (counter.get() == taskCounter) {
                infoLabel.setVisible(false);
            }
        }
    });
    timer.start();

The above is only executed if it is the last event that has been triggered. Ensuring that, my label stays visible at least 2 seconds after the last event.

Is there a better way of dealing with this problem?


Solution

  • Given two instances of java.swing.Timer, let t1 fire at some some nominal rate that is less than two seconds. Let the ActionListener for t1 update the label and invoke restart() on t2, which should have an initial delay of two seconds. Let the ActionListener for t2 stop() itself and invoke label.setVisible(false).