0

I have the following Java Code which adds a JRadioButton to a JPanel and handles its mouse click event

    JRadioButton offline  = new JRadioButton();
    offline.setText("Offline Mode");

    modePanel.add(offline);

    modePanel.setLayout(new GridLayout(2,1));
    offline.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    offlineClicked(evt);
                }
            });

The function offlineClicked takes roughly around 1 min to be executed completely. And until its execution is completed no other actions performed are handled.

All actions performed thereafter seem to go to a Eventqueue and handled FIFO when the offlineClicked has completed execution.

Due to this the UI seems to have gone into a hung state.

What can be done to make swing handle events concurrently and not wait till the last is executed completely.

Sangeet Menon
  • 9,555
  • 8
  • 40
  • 58
  • 3
    The standard technique is to NEVER do application work on the event thread. Always run application work on a separate processing thread so that the UI can remain responsive. There are entire books and tutorials available on this subject, do some Google searches. Start with Oracle's tutorials. – Jim Garrison Feb 13 '17 at 07:43
  • 2
    You're looking for `SwingWorker` and `ActionListener` for the button; [for example (of `SwingWorker`)](http://stackoverflow.com/questions/20944719/how-to-use-swingworker/20945255#20945255) – MadProgrammer Feb 13 '17 at 07:47
  • Is it essential that every click is processed? Or do you want clicks to be ignored until the initial process of first click is done? - You will have to take this into account when implementing a concurrent solution (even when using SwingWorker etc.) – Fildor Feb 13 '17 at 08:31
  • @MadProgrammer, `SwingWorker` did the trick thanks. – Sangeet Menon Feb 13 '17 at 08:34

1 Answers1

0

When the mouselistener event is fired it runs on the event dispatch Thread (the swing gui thead that redraws the screen). If you put logic code in the gui thread then your gui would freeze until the logic completes and returns the gui thread back to swing. You can use swingworker or another option is to simply start a new thread and let the gui thread return so it can let other gui events process. In the new thread do your time consuming logic, it's running off of the event loop so swing won't freeze as it's running async. You MUST run all swing code on the dispatch thread so when the logic is done since you are no longer on the dispatch thread you have to add it to the event queue.

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        // you can now safely use swing components
        new frame.setVisible(true);
    }
} );