2011-01-25 15 views
0

this tutorial(ただしわずかに変更されています)からインスピレーションを受けたMVCパターンを使用してデスクトップアプリケーションを設計しました。このアプリケーションが必要とするのは、ディレクトリから別のディレクトリにファイルのリストをコピーすることです。私がしたいのは、基本的にすべてのファイルがコピーされた後にGUIを更新することです。GUIが情報を更新しないときにSWINGを使用したGUIの処理

まずはコードを教えてください。

@Override 
    public void modelPropertyChange(PropertyChangeEvent evt) { 
     // ....... 


     else if(evt.getPropertyName().equals(DefaultController.BACKUP_DUMMY)){ 
      System.out.println("WHAT?"); 
      this.dummy.setText(evt.getNewValue().toString()); 
     } 

    } 

あなたが想像できるように:私はこれを持って私の見解では

public void dummyMethod(Integer k) throws InterruptedException{ 
    for(int i=0;i<10;i++){ 
     System.out.println(i); 
    Thread.sleep(1000); 
     this.firePropertyChange(DefaultController.BACKUP_DUMMY, i-1, i); 
    } 
} 

:私のモデルで 私はこのダミー方法(ない本当の方法が、それは同じであるの背後にあるロジックを)持っていますは毎回印刷されますが、ループが終了するまでGUIは更新されません。 これはSWINGとそのEDTと一緒に作業しているときの古典的な問題です。私はこのオラクルサイトでこのarticle/tutorialを読んだことがありますが、私はSwingWorkerを使う必要はないと思います。 GUI上で単一のコンポーネントを更新するだけでいいです。

+0

"しかし、私はSwingWorkerを使う必要はないと思っています。GUI上の単一のコンポーネントを更新するだけです。"次に、SwingWorkersとEDTを読んで、なぜこれがあなたの悪い決定であるのかを知ることができます。必要なツールを避けています。 –

答えて

1

長時間実行する操作にイベントディスパッチスレッドを使用しないでください。ファイルのコピーなど、長時間実行する操作のために別のスレッドを開始する必要があります。ワーカースレッドからguiを更新する必要がある場合は、SwingUtilities.invokeLaterメソッドまたはSwingUtilities.invokeAndWaitメソッドを使用する必要があります。

例として、

final JLabel label = new JLabel(); 
JButton button = new JButton(); 
button.addActionListener(new ActionListener() { 
    public void actioPerformed(ActionEvent ev) { 
     Thread workerThread = new Thread() { 
       public void run() { 
        //do long running job then update ui 
        SwingUtilities.invokeLater(new Runnable() { 
          public void run(){ 
           label.setText("Operation has finished"); 
          } 
        }); 

       } 
     }.start();  
    } 
}); 
+0

待ちます。何をしていますか?私が必要とするのは、ファイルをロードし、GUIに通知することです:ロードされた各ファイルについてです。あなたは、GUIの中でファイルのロード操作を行うことを提案していますか?それはMVCに対するものです。 – dierre

+1

これは示唆されたものではありません。ファイル操作は別のスレッド上にあります。 GUIコンポーネントの更新はEDT上にあるため、invokeLater()メソッドが必要です。 – camickr

+0

私はちょうどコードのスクリプトを与えます..あなたのコントローラにworkerThreadを実装することができます.. –

3

が、ループが終了するまでGUIが更新されないものです。

これは、すべてのコードがEDT上で実行されているため、ループ全体が終了するまでGUIが再描画できないことを示しています。

しかし、私はSwingWorkerを使う必要はないと思います。

これはおそらく最も簡単な解決策です。メインループを別のスレッドで実行し、各ファイルの処理時に結果を「公開」します。

また、Gurselの提案する手法を使用してください。長時間実行されるコードは別のスレッドで実行されており、プロパティ変更イベントの発生はEDTにのみ発生します。つまり、GUIはEDTで再描画できます。

関連する問題