0

一言で言えば私の問題:私のGUIアプリは長いネットワークダウンロードを実行する必要があります。ダウンロードは別のスレッドで処理されます。リモートサイトで認証が必要になる可能性があるため、「ユーザー名とパスワードの入力」ダイアログをポップアップするオーセンティケーターを定義したいと思います。このダイアログはUIスレッドから実行する必要があることに気づきました。

私はこれを行う最初の人ではないと確信しています。バックグラウンドスレッドがUIスレッドでダイアログを起動し、そのダイアログが閉じられるまでブロックするためのここでのベストプラクティスは何ですか?

psバックグラウンドスレッドは非常に大きく、ネットからファイルをダウンロードするだけではありません。言い換えれば、現時点ではSwingWorkerに変換することはおそらく実用的ではなく、とにかく、SwingWorkerからこれをどのように解決するかはわかりません。

4

3 に答える 3

2

ダイアログを表示するにはSwingUtlities.invokeLaterが必要であり、同期/通知オブジェクトを「一時停止」してユーザーが応答するのを待つ必要があります。

基本的にあなたのworker(非GUI)スレッドで:

final Object obj = new Object() ; // or something to receive your dialog's answer(s)
Runnable r = new Runnable() {

   void run() {
     Dialog d = new Dialog() ;

     Button b = new JButton("ok") ;
     b.addActionListener(new ActionListener() {
         void actionPerformed(ActionEvent e) {
             synchronize(obj) { // can lock when worker thread releases with wait
                obj.notify() ; // signals wait
             }
         }
     }) ;

   }
} ;

synchronize( obj ) {
   SwingUtilites.invokeLater(r) ; // executs r's run method on the swing thread
   obj.wait() ; // releases obj until worker thread notifies
}
于 2011-05-23T18:06:10.060 に答える
2

エドワードフォークは書いたActually, it looks like invokeLater() will also do what I want

いいえ、それは間違っています。EDTが存在することを計算する必要があり、EDTが実行されている場合はSwingUtilites.invokeLater()が機能し、そうでない場合はSwingUtilites.invokeLater()は何も通知されず、ポップアップは表示されません。

1/ java.swing.Actionを使用してEDTを作成します

2 / trashgodでこのアイデアをデバッグするこのロジックは正しく、そのために最適だと思います

于 2011-05-23T19:19:54.943 に答える
2

記録のために、アンドリューの答えに基づいた私の最終的な解決策は次のとおりです。

final Authenticator authenticator =
   new Authenticator() {
        @Override
        public PasswordAuthentication getPasswordAuthentication() {
            try {
                SwingUtilities.invokeAndWait(new Runnable() {
                    public void run() {
                        // Launch the GUI dialog
                        queryUsernamePassword(getRequestingHost(), getRequestingPrompt());
                    }
                });
                if (username == null)
                    return null;
                return new PasswordAuthentication(username,
                            password.toCharArray());
            } catch (Exception e) {
                return null;
            }
        }
    };
于 2011-05-23T22:49:33.497 に答える