Проблемы с анимацией значков SwingUtilities.invokeLater, SwingWorker и gif
Я пытаюсь загрузить значок GIF, в то время как я делаю дорогую работу в фоновом режиме. Но проблема в том, что значок gif(анимации) не загружается.
Если я заменю значок gif на png, он будет работать нормально.
Вот код теста класса
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();
}
}
});
}
});
}
}
Когда пользователь нажимает кнопку "Войти", я меняю текст кнопки и помещаю на нее иконку GIF. В
SwingUtilities.invokeLater(new Runnable() {
метод я запускаю фоновую дорогую задачу через поток SwingWorker. Прямо сейчас, нет необходимости публиковать и обрабатывать методы класса SwingWorker, потому что я не делаю никакой работы во время фоновых дорогостоящих задач.
Если я удаляю SwingUtilities.invokeLater (новый метод Runnable () {) и вызываю напрямую класс SwingWorker, то значки gif и png не работают (отображаются на кнопке).
Я пробовал простой поток, чтобы изменить текст и установить значок на кнопку, но это не сработало.
Вот код класса SwingWorker
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;
}
}
Любая идея? что происходит в основном потоке графического интерфейса? Где ошибка?
1 ответ
Ты не должен звонить doInBackground
напрямую, вы должны позвонить execute
вместо. Кроме того, вы должны иметь возможность сделать этот вызов в потоке пользовательского интерфейса (то есть нет необходимости вызывать его внутри invokeLater
). В вашем doInBackground
реализации, вы должны внести изменения в пользовательский интерфейс в потоке пользовательского интерфейса (т.е. invokeLater
следует использовать там).