Alex Rivera | Logout

Disable JButton, while background job, to avoid multiple clicks

Asked 2011-12-08T09:34:24.680
8

I need to stop user making multiple clicks on a JButton while the first click still execute.

I was able to came with a solution for this issue but I do not completelly understand why it's working.

Bellow I posted the code (trimmed to a minimum) that works and the one that does not work.

In first example (good) if you run it and click the button multiple times only one action is considered as for the second example (bad) if you click the mouse multiple times you get action executed at least twice.

The second (bad) example simply does not use invokeLater() method.

Where the difference in behaviour cames from?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class TestButtonTask {

    public static void main(String[] args) {

        final JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        final JButton task = new JButton("Test");

        task.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                long t = System.currentTimeMillis();
                System.out.println("Action received");

                task.setText("Working...");
                task.setEnabled(false);

                SwingUtilities.invokeLater(new Thread() {

                    @Override
                    public void run() {
                        try {
                            sleep(2 * 1000);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(TestButtonTask.class.getName()).log(Level.SEVERE, null, ex);
                        }

                        SwingUtilities.invokeLater(new Runnable() {

                            public void run() {
                              
Edit
Report

1 Answer

1

There are two more ways.

You can define a flag. Set it when action start and reset back after the end. Check the flags in the actionPerformed. If inProgress==true just do nothing.

Another way is to remove the listener and assign it back after the action ends.

answered 2011-12-08T09:39:23.003

Your Answer