Java:如何从另一个线程启动UI对话框,例如Authenticator



简而言之,我的问题是:我的GUI应用程序需要执行长时间的网络下载。下载是在一个单独的线程中处理的。远程站点可能需要身份验证,所以我想定义一个弹出"输入用户名和密码"对话框的Authenticator。我意识到这个对话框需要从UI线程运行。

我确信我不是第一个这样做的人。让后台线程在UI线程中启动一个对话框,并阻止该对话框直到该对话框被关闭,这里的最佳做法是什么?

p.s.后台线程非常大,所做的工作远不止从网上下载一个文件。换句话说,在这一点上,将其转换为SwingWorker可能是不现实的,无论如何,我也不确定如何从SwingWorkers解决这个问题。

您需要SwingUtlities.invokeLater来显示对话框,并需要一个同步/通知对象来"暂停"并等待用户响应。

基本上在您的工作线程(非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
}
Edward Falk编写了Actually, it looks like invokeLater() will also do what I want

不,这是错误的,因为你必须计算EDT存在,并且SwingUtilites.invokeLater()在有运行EDT的情况下工作,如果没有,则SwingUtilits.invokeLater()没有任何通知,任何弹出窗口都将被显示,可能只是空矩形

1/使用java.swing.Action 创建EDT

2/通过垃圾神调试这个想法我认为这个逻辑是正确的,最适合

这里是我的最终解决方案,基于Andrew的答案:

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

最新更新