Вопрос

У меня есть пользовательский интерфейс, встроенный внутри JFrame.Одна из кнопок запускает длительный вызов (все еще в рамках того же java-процесса), и во время его выполнения пользовательский интерфейс замораживается.

Я подумал, чтобы было ясно, что все еще запущено, я могу отобразить индикатор выполнения, возможно, во всплывающем окне, чтобы пользователь мог быть в курсе того, что делает программа.

Итак, я создаю новый JDialog, добавляю к нему JProgressBar и обновляю его по мере развития событий.Проблема в том, что содержимое этого диалогового окна не обновляется.Изменения, которые я вношу в его заголовок, отображаются немедленно, и все, что я выводю на консоль, но ничего в самом пользовательском интерфейсе.

Есть ли команда, которую я могу выдать, чтобы принудительно перекрасить?

Вот суть этого раздела:

  killWindow = new JDialog();
  killWindow.setUndecorated(true);
  killWindow.setTitle("stopping tests - 0 of " + numActive);
  killProgress = new JProgressBar(0, numActive);
  killWindow.add(killProgress);
  killProgress.setStringPainted(true);
  killWindow.pack();
  killWindow.setLocationRelativeTo(frame);
  killWindow.setVisible(true);

Затем, по мере нашего продвижения...:

  killProgress.setValue(++killedTests);                    // not seen!
  killProgress.setString("Killing test on " + nickname()); // not seen!
  log("Killed another test, " + killedTests + " so far");  // visible in real time
  killWindow.setTitle("stopping tests - " + killedTests +
                      " of " + killProgress.getMaximum()); // visible in real time

Что я упускаю из виду?Я пробовал гуглить и искать здесь, на SO, и на самом деле не увидел ничего очевидного?

Это было полезно?

Решение

Вы должны выполнить свою длительную задачу в другом потоке.

Существует этот поток, называемый "AWT Event Dispatch Thread", который отвечает за обновление компонентов пользовательского интерфейса.Если он занят выполнением вашей длительной задачи, он не будет обновите пользовательский интерфейс (или обновите диалоговое окно).

Вы можете рассмотреть возможность использования Особенности SwingUtilities или a Качающийся рабочий.

От свингера Документация вот пример

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
   @Override
   public String doInBackground() {
       return findTheMeaningOfLife();
   }

   @Override
   protected void done() {
       try { 
           label.setText(get());
       } catch (Exception ignore) {
       }
   }
}

(new MeaningOfLifeFinder()).execute();

Выполняя свою длинную задачу в другом потоке, вы позволяете потоку отправки событий AWT отображать адаптивный пользовательский интерфейс.

Вы можете взглянуть на это "Урок из руководства по Java" чтобы лучше понять эти концепции.

Другие советы

Похоже, что вы, возможно, выполняете свою длительную задачу в потоке отправки событий (EDT).Взгляните на SwingWorker.Если вы используете 1.6, он встроен:

http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

Если нет, вы можете найти более подробную информацию по адресу:

http://en.wikipedia.org/wiki/SwingWorker

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top