Java CountDownLatch используется для ожидания удаления JFrame - PullRequest
0 голосов
/ 30 мая 2010

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

Фон: mainFrame создает новый фрейм с именем dataEntryFrame. При нажатии кнопки «Отправить» dataEntryFrame запись добавляется в базу данных и удаляется dataEntryFrame. На этом этапе mainFrame должен очистить и перезагрузить jList, который показывает все записи.

Проблема: при загрузке dataEntryFrame, зависании java, компоненты dataEntryFrame никогда не загружаются. Я не могу пройти эту часть ... затем в DataEntryFrame значение CountDownLatch должно уменьшаться только после нажатия кнопки отправки, успешно добавляет запись в таблицу базы данных и удаляет себя. Или когда пользователь нажимает кнопку отмены ...

Код: из основного блока

clearList();
CountDownLatch dataEntryDone = new CountDownLatch(1);
DataEntryFrame f = new DataEntryFrame(dataEntryDone);
Thread newThread = new Thread(f);
newThread.start();
dataEntryDone.await();
reLoadList();

Код: из DataEntryFrame

public void run(){
initComponents();
loadOtherData();
this.setVisible(true);
}
void submit(){
addRecord();
this.dispose()
dataEntryDone.countDown();
}

1 Ответ

2 голосов
/ 31 мая 2010

Использование нового потока для dataEntryFrame и блокирование mainFrame идут против модели потоков Swing. В Swing все вызовы компонентов пользовательского интерфейса в Swing должны выполняться в потоке диспетчеризации событий. Чтобы убедиться, что это происходит во время разработки, вы можете установить менеджер перерисовок, который выдает исключение, если обнаруживает, что компоненты пользовательского интерфейса используются из другого потока. См. FEST - Проверка того, что доступ к компонентам графического интерфейса выполняется в EDT . Чтобы убедиться, что что-то происходит с EDT, вы используете SwingUtilities.invokeAndWait / invokeLater.

Ваш основной фрейм не должен (и не должен!) Ждать, пока фрейм ввода данных, а не CountDownLatch, заставит ваш фрейм ввода данных отправлять событие в MainFrame, когда это будет сделано, чтобы MainFrame может предпринять соответствующие действия, такие как обновление списка.

Просто чтобы еще больше запутать воду, сохранение данных в базу данных и выборку данных для списка в идеале не должно выполняться в потоке диспетчеризации событий. Вместо этого используйте SwingWorker для выполнения этих операций в своем собственном потоке. Однако, в отличие от правила, согласно которому все компоненты пользовательского интерфейса должны быть доступны из EDT, это правило фоновой обработки не является жестким и быстрым, но рекомендуется поддерживать отзывчивый пользовательский интерфейс - если передача данных в / из БД занимает какое-то время и это делается в потоке пользовательского интерфейса (EDT), после чего пользовательский интерфейс останавливается.

См.

...