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?
You shouldn't call
doInBackground
directly, you should callexecute
instead. Also you should be able to make that call in the UI thread (i.e. no need to call it inside aninvokeLater
). In yourdoInBackground
implementation, you should do changes to the UI in the UI thread (i.e.invokeLater
should be used there).