Java Swing Progress Monitor для создания GUI (EDT)


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

Создание диалога выполняется в потоке диспетчера событий. В зависимости от клиентской системы это может занять до 10 секунд.

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

Проблема в том, что progressmonitor всегда зависает до тех пор, пока диалог не будет запущен. Когда запуск диалога закончен, progressmonitor реагирует и показывает текущее состояние.

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

final CVProgressMonitorDialog progressMonitor = new CVProgressMonitorDialog();
progressMonitor.startPollingThread();
SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
         try {
                startComplexDialog();
            }
            finally {
                close(progressMonitor);
            }
        }
    });

CVProgressMonitorDialog в основном представляет собой ProgressMonitor, поставляемый с Swing.

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

final CVProgressMonitorDialog progressMonitor = new CVProgressMonitorDialog();
progressMonitor.startPollingThread();
    new Thread() {

        @Override
        public void run() {
            try {
                startComplexDialog();
            }
            finally {
                close(progressMonitor);
            }
        }
    }.start();

Вызывает ли использование второго решения потенциальные проблемы, поскольку Swing не является потокобезопасным?
Существует ли общее решение задачи мониторинга в EDT?


person user3614951    schedule 08.05.2014    source источник
comment
Да, второе решение небезопасно. Один из способов решить эту проблему — разделить инициализацию диалога на разные задачи и запустить их как разные блоки в EDT, а между ними соответствующим образом обновить монитор выполнения (также в EDT). Также проверьте, можете ли вы перенести часть работы за пределы EDT, если вы читаете данные или создаете внутренние структуры, не связанные с Swing.   -  person DSquare    schedule 08.05.2014


Ответы (2)


Вы заявляете:

Создание диалога выполняется в потоке диспетчера событий. Это может занять до 10 секунд, в зависимости от клиентской системы.

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

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

Опять же, выполняйте свою работу в фоновом потоке, производном от SwingWorker, обновляя свойство progress SwingWorker по мере выполнения создания и используя PropertyChangeListener, добавленный в ваш SwingWorker, для отслеживания и отображения изменений в ходе выполнения.

person Hovercraft Full Of Eels    schedule 08.05.2014

Как указано в другом ответе, вам не следует выполнять длительные операции в EDT. Но если вы спешите, я справился с подобной ситуацией, используя модальный JDialog. Когда модальный диалог становится видимым, он блокирует поток, выполняющий вызов setVisible(true), и получает собственный поток отправки. Его можно обновлять независимо от EDT. Сделайте свой индикатор выполнения в одном из них, и все должно быть в порядке.

person schmop    schedule 08.05.2014