0

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

我敢肯定我不是第一个这样做的人。让后台线程在 UI 线程中启动对话框并阻塞直到该对话框被解除的最佳实践是什么?

ps后台线程非常大,并且不仅仅是从网上下载文件。换句话说,此时将其转换为 SwingWorker 可能不切实际,而且无论如何,我也不确定如何从 SwingWorker 解决这个问题。

4

3 回答 3

2

您需要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
}
于 2011-05-23T18:06:10.060 回答
2

爱德华福尔克写道Actually, it looks like invokeLater() will also do what I want

不,那是错误的,因为您必须计算 EDT 存在,并且 SwingUtilites.invokeLater() 如果有运行 EDT 则有效,如果没有,则 SwingUtilites.invokeLater() 没有任何通知,任何弹出窗口都会被显示,也许只是空的 Rectangle

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

2 / 由垃圾神调试这个想法我认为这个逻辑是正确的并且最适合那个

于 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 回答