1

私はバックグラウンドで高価な作業をしていますが、gifアイコンをロードしようとしています。しかし、これは問題です、gif(アニメーション)アイコンが読み込まれていません。SwingUtilities.invokeLater、SwingWorker、gif icon animation issue

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を(新しいRunnableを(){

方法私はSwingWorkerのスレッドを通じて背景高価なタスクを開始します。私は致しておりませんので、今、必要は、SwingWorkerのクラスのメソッドを公開していないとプロセス背景高価なタスク中のすべての作業。

i「はSwingUtilities.invokeLaterを(新しいRunnableを(){」メソッドを削除して)ボタンに表示(両方GIFおよびPNGアイコンが機能していない、その後、直接SwingWorkerのクラスを呼び出す場合。

私は、テキストを変更してボタン上のアイコンを設定するために単純なスレッドを試みましたが、うまく機能しませんでした。ここで

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; 
} 
} 

は、任意のアイデアですか? GUIのメインスレッドではどうなりますか?間違いはどこですか?

答えて

1

doInBackgroundに直接電話するのではなく、executeに電話する必要があります。また、UIスレッドでその呼び出しを行うことができます(つまり、invokeLaterの内部で呼び出す必要はありません)。 doInBackground実装では、UIスレッドのUIに変更を加える必要があります(つまり、invokeLaterをそこに使用する必要があります)。

+0

幸いです:) – sjr