2012-10-29 30 views
5

データベースからデータを取得し、その時点の既存のデータを変更できないようにする方法が必要でした。モーダルJDialogを安全に開いて閉じる(SwingWorkerを使用)

データベースの更新を行うSwingWorkerと、JProgressBarを使用して何が起こっているのかをユーザーに示すためのモーダルJDialogを作成しました。モーダルダイアログはdefaultCloseOperationがDO_NOTHINGに設定されているので、適切な呼び出しでのみ閉じることができます - 私はsetVisible(false)を使用します。

MySwingWorkerTask myTask = new MySwingWorkerTask(); 
myTask.execute(); 
myModalDialog.setVisible(true); 

SwingWorkerのは、doInBackground(内いくつかのものを行います)し、最後にそれが呼び出されます:

myModalDialog.setVisible(false); 

私の唯一の懸念と私の質問: は、それがsetVisible(true)である前に、SwingWorkerのはsetVisible(false)を実行することを可能です労働者の後の行は産む?

もしそうなら、setVisible(true)は永遠にブロックすることができます(ユーザーはモーダルウィンドウを閉じることができません)。

私のように何かを実装する必要があります:それは実際に閉じてしまいますことを確認する

while (!myModalDialog.isVisible()) { 
    Thread.sleep(150); 
} 
myModalDialog.setVisible(false); 

+1

あなたは 'myModalDialog.setVisible(false)を呼び出す必要があります。代わりに' doInBackground() 'の')( ''で完了です。なぜ 'execute'の前に' setVisible(true) 'を呼び出さないのですか? – assylias

+0

setVisible(true)はブロッキングコールです – user1713059

+0

母 - 非常に良い点があります:-) – assylias

答えて

3

通常、はいです。

私はあなたのdoInBackgroundメソッドでは、SwingUtilities.invokeLaterを使用してダイアログを表示し、doneメソッドでダイアログを非表示にしています。

これは、ダイアログボックスが画面にそれを作るていない場合でも、あなたはマイナーな問題は、あなたが今、合格する必要があるとしているされて

...フロー上で、もう少しコントロールを得ることを意味すべきです労働者への対話、それはそれの制御を取得することができますので...

public class TestSwingWorkerDialog { 

    public static void main(String[] args) { 
     new TestSwingWorkerDialog(); 
    } 
    private JDialog dialog; 

    public TestSwingWorkerDialog() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       MyWorker worker = new MyWorker(); 
       worker.execute(); 

      } 
     }); 
    } 

    public class MyWorker extends SwingWorker<Object, Object> { 

     @Override 
     protected Object doInBackground() throws Exception { 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        getDialog().setVisible(true); 
       } 
      }); 
      Thread.sleep(2000); 

      return null; 
     } 

     @Override 
     protected void done() { 
      System.out.println("now in done..."); 
      JDialog dialog = getDialog(); 
      // Don't care, dismiss the dialog 
      dialog.setVisible(false); 
     } 

    } 

    protected JDialog getDialog() { 
     if (dialog == null) { 

      dialog = new JDialog(); 
      dialog.setModal(true); 
      dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
      dialog.setLayout(new BorderLayout()); 
      dialog.add(new JLabel("Please wait...")); 
      dialog.setSize(200, 200); 
      dialog.setLocationRelativeTo(null); 

     } 

     return dialog; 
    } 

} 
+1

'SwingUtilities.invokeLater'と' EventQueue.invokeLater'の違いは何ですか? – Mordechai

+1

申し訳ありません私の質問がばかげていますが、あなたの例では、それが保証されている場合、invokeLaterの実行メソッドは、作業が完了する前に確実に実行されていますか?私のポストの主な問題が残っているように私には思われます - 大動脈不全の並行性はありますが、私は間違っている可能性があります。 – user1713059

+2

@ M.M。誰もいません。 SwingUtilities.invokeLaterは、この呼び出しをEventQueue.invokeLaterに転送します。 –

関連する問題