Java: как запустить диалог пользовательского интерфейса из другого потока, например, для Authenticator - PullRequest
0 голосов
/ 23 мая 2011

Моя проблема в двух словах: мое приложение с графическим интерфейсом должно выполнять длительную сетевую загрузку.Загрузка обрабатывается в отдельном потоке.Возможно, что удаленному сайту потребуется аутентификация, поэтому я хочу определить Authenticator, который открывает диалоговое окно «введите ваше имя пользователя и пароль».Я понимаю, что этот диалог нужно запустить из потока пользовательского интерфейса.

Я уверен, что я не первый, кто делает это.Какова лучшая практика для того, чтобы фоновый поток запускал диалоговое окно в потоке пользовательского интерфейса и блокировал его до тех пор, пока этот диалог не был закрыт?из сети.Другими словами, на данный момент, вероятно, нецелесообразно конвертировать его в SwingWorker, и в любом случае, я не уверен, как бы я решил эту проблему с помощью SwingWorker.

Ответы [ 3 ]

2 голосов
/ 23 мая 2011

Эдвард Фальк написал Actually, it looks like invokeLater() will also do what I want

нет, это неправильно, потому что вы должны вычислить, что EDT существует, и SwingUtilites.invokeLater () работает, если там работает EDT, если нет, то SwingUtilites.invokeLater () ничего не уведомляет, любое всплывающее окно будет отображаться, может быть, просто пустой прямоугольник

1 / создать EDT с помощью java.swing.Action

2 / отладить эту идею trashgod Я думаю, что эта логика верна и лучше всего для этого

2 голосов
/ 24 мая 2011

Кстати, вот мое окончательное решение, основанное на ответе Эндрю:

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;
            }
        }
    };
2 голосов
/ 23 мая 2011

вам нужно 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...