Проблемы с анимацией значков 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 следует использовать там).

Другие вопросы по тегам