トップ 差分 一覧 ソース 置換 検索 ヘルプ PDF RSS ログイン

時間のかかる処理を行う

 Thread を使う

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  public void actionPerformed(ActionEvent e){
    final JDialog dialog = new JDialog(frame,true);
    // dialog の処理化色々
    
    Thread th = new Thread(){
      public void run(){
        while(true){
          try {
            if (dialog.isVisible()){
              break;
            }
            Thread.sleep(100);
          } catch (Exception e){
          }
        }
        
        
        try {
          // 何か処理
          
          
          runInEventDispatchThread(new Runnable(){
              public void  run(){
                // イベントディスパッチャでの処理
                JOptionPane.showMessageDialog(null,"処理完了");
              }
          });
        } catch (Exception e){
          // エラー処理
          
          runInEventDispatchThread(new Runnable(){
              public void  run(){
                // イベントディスパッチャでの処理
                JOptionPane.showMessageDialog(null,"エラー");
              }
          });
          
        } finally {
          runInEventDispatchThread(new Runnable(){
              public void  run(){
                dialog.dispose();
              }
          });
        }
      }
    };
    th.start();
    dialog.setVisible(true);
  }
  
  public static void runInEventDispatchThread(Runnable run)  {
    if(SwingUtilities.isEventDispatchThread()){
      run.run();
    } else {
      try {
        SwingUtilities.invokeAndWait(run);
      } catch (Exception e){
        showMessage(null,e);
      }
    }
  }

 SwingWorker を使う

SwingWorker を使ったイベント処理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public void actionPerformed(ActionEvent e){
    final JDialog dialog = new JDialog(frame,true);
    // dialog の処理化色々
    
    SwingWorker sw = new SwingWorker<Boolean,Object>(){
      @Override
      public Boolean doInBackground(){
        // dialog が表示されるまで待つ処理は不要かも
        while (true){
          try {
            if (dialog.isVisible()){
              break;
            }
            Thread.sleep(100);
          } catch (Exception e){
          }
        }
        
        try {
          // 何か処理
        } catch (Exception e){
          // エラー処理
          
          throw e;
        }
        
        return Boolean.TRUE;
      }
      
      @Override
      public void done(){
        try {
          get();
          JOptionPane.showMessageDialog(null,"処理完了");
        } catch (Exception e){
          JOptionPane.showMessageDialog(null,"エラー");
        } finally {
          dialog.dispose();
        }
      }
    };
    sw.execute();
    dialog.setVisible(true);
  }

 SwingWorker を使う2

Dialog を表示しつつ、処理をするクラスを作る

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  /**
  * Dialog を表示しながら SwingWorker の処理を行う 
  */
  abstract class DialogWorker<T,V> extends SwingWorker<T,V> {
    
    /**
    * executeWithDialog で実行された場合に、
    * doInBackground メソッドの実行完了後で、
    * dialog が dispose された後に呼ばれる
    * 
    */
    public void doneAfterDispose(){
      
    }
    
    /**
    * SwingWorker を実行中に dialog を表示し、SwingWorker の終了後に dialogを終了します。
    * dialog がモーダルの場合は、dialogが閉じられるまで
    * 呼び出しは戻りません。
    * 
    *@param  dialog  run を実行中に表示するDialog
    */
    public void executeWithDialog(final JDialog dialog){
      final SwingWorker invoker = new SwingWorker(){
        
        @Override
        public Boolean doInBackground() {
          // Dialogが表示されるまで待つ
          while (true){
            try {
              if (dialog.isVisible()){
                break;
              }
              Thread.sleep(100);
            } catch (Exception e){
            }
          }
          
          DialogWorker.this.execute();
          try {
            DialogWorker.this.get();
          } catch (Exception e){
          }
          return Boolean.TRUE;
        }
        
        @Override
        public void done(){
          dialog.dispose();
          DialogWorker.this.doneAfterDispose();
        }
      };
      invoker.execute();
      dialog.setVisible(true);
    }
  }

呼び出し

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final JDialog dialog = new JDialog((Frame)null, true);
    final DialogWorker dw = new DialogWorker<Boolean,Object>(){
      
      @Override
      public Boolean doInBackground() throws Exception{
        // 何か処理
        
        return Boolean.TRUE;
      }
      
      @Override
      public void doneAfterDispose(){
        try {
          get();
          JOptionPane.showMessageDialog(null,"処理完了");
        } catch (Exception e){
          JOptionPane.showMessageDialog(null,"エラー");
        } finally {
          dialog.dispose();
        }
      }
    };
    dw.executeWithDialog(dialog);

 注意

JDK1.6.0_20 までは、SwingWorker にバグがあるので注意。
Update21 で修正された。
バグの内容としては、SwingWorkerの終了を正確に取得できないことがある。


[カテゴリ: プログラミング言語 > Java]

[通知用URL]



  • Hatenaブックマークに追加
  • livedoorクリップに追加
  • del.icio.usに追加
  • FC2ブックマークに追加

最終更新時間:2013年04月30日 20時59分45秒