SwingUtilities.invokeLater, SwingWorker and gif icon animation issue

237 views Asked by At

I am trying to load a gif icon, while i am doing some expensive work in background. But issue is this, gif(animation) icon is not loading.

If i replace gif icon with png, it works fine.

Here is Test class code

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    JFrame frame = new JFrame();
    frame.setBounds(100, 100, 200, 100);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    frame.getContentPane().add(panel);

    JButton loginButton = new JButton("Login");
    panel.add(loginButton);
    frame.add(panel);
    frame.setVisible(true);

    loginButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            URL urlProcessing = Test.class.getResource("processing.gif");
            //URL urlProcessing = Test.class.getResource("processing.png");
            ImageIcon processingIcon = new ImageIcon(urlProcessing);
            loginButton.setText("Authenticating...");
            loginButton.setIcon(processingIcon);
            loginButton.revalidate();
            loginButton.repaint();


            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {     

                    Worker worker = new Worker(frame);
                    try {
                        worker.doInBackground();                            
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            });

        }
    });

}
}

When user click login button, i change the text of button and put gif icon on it. In

SwingUtilities.invokeLater(new Runnable() {

method i start background expensive task through SwingWorker Thread. Right now, no need publish and process methods of SwingWorker class, because i am not doing any work during background expensive task.

If i remove "SwingUtilities.invokeLater(new Runnable() {" method and call directly SwingWorker class, then both gif and png icons not working(displaying on button).

I tried simple thread to change text and set icon on button, but it did not worked as well.

Here is SwingWorker class code

import javax.swing.JFrame;
import javax.swing.SwingWorker;

public class Worker extends SwingWorker<String, String> implements Runnable {

private JFrame testFrame;
// some public and private properties

public Worker(JFrame frame){
    // doing some assignments

    this.testFrame = frame;
}

@Override
protected void done() {
    // TODO Auto-generated method stub
    super.done();
    System.out.println("Done method called");
}


@Override
protected String doInBackground() throws Exception {
    int i = 0;
    String chunks = null;
    publish(chunks);
    // Doing some very expensive work, HTTP request, DB operations etc...
    while (i < 10) {
        Thread.sleep(1000);
        System.out.println("Value of i: "+i);
        i++;
    }
    this.done();
    testFrame.setVisible(false);
    return null;
}
}

Any Idea? what happening in GUI main thread? Where is the mistake?

1

There are 1 answers

1
sjr On

You shouldn't call doInBackground directly, you should call execute instead. Also you should be able to make that call in the UI thread (i.e. no need to call it inside an invokeLater). In your doInBackground implementation, you should do changes to the UI in the UI thread (i.e. invokeLater should be used there).