Java SwingUtilities.invokeLater

2.2k views Asked by At
.addActionListener(new ActionListener(){
        public void actionPerformed (ActionEvent e){
            try{
                ta.append("Searching Initiated at: "+datetime()+"\n");
                gui.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                task.execute();
                javax.swing.SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        gui.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                    }
                });
                //Enable the next stage in the YD process and disable the previously executed functions
                clusAn.setEnabled(true);
                open.setEnabled(false);
                statCl.setEnabled(false);
            }catch (Exception IOE){
                }
        }
    });

Hi there, having a bit of a pain with the last stage of this application I've designed.

Basically, when the user clicks the button, I'd like it so the cursor becomes a 'waiting' version and then once the background process (task.execute) has completed, the cursor returns to normal.

The task.execute isn't in the same class so I can't just do a straight call of the "gui.setCursor" because it doesn't recognise GUI as the variable.

Not sure what to do so any advice would be great

Thanks :D

3

There are 3 answers

1
JB Nizet On BEST ANSWER

Modify the task's class so that it takes your GUI as a constructor argument. This way, when the task is completed, it can invoke the setCursor method.

You should use a SwingWorker for this kind of thing.

EDIT :

Here's how the code of the task should be :

public class MySwingWorker extends SwingWorker<Void, Void> {

    /**
     * The frame which must have the default cursor set 
     * at the end of the background task
     */
    private JFrame gui;

    public MySwingWorker(JFrame gui) {
        this.gui = gui;
    }

    // ...

    @Override
    protected void done() {
        // the done method is called in the EDT. 
        // No need for SwingUtilities.invokeLater here
        gui.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }
}
0
jzd On

When you create your task pass it an interface that has some sort of "completed" method. Make your task call that method when it is finished then have your gui class implement that interface and change the cursor on that method call.

0
Kurtt.Lin On

Maybe you can try to make gui final.

final JComponent guiFinal = gui;
javax.swing.SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        guiFinal .setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                    }
                });