2010-12-03 2 views
2

У меня есть панель, которая отображает текст. Я хочу, чтобы панель меняла свой текст, а затем приостанавливала приложение, прежде чем что-либо еще произойдет. Я использую Thread.sleep (1000). По какой-то причине приложение не заканчивает рисовать панель перед вызовом Thread.sleep (текст не изменяется). Я также пробовал это:Thread.sleep и перекраска

board.invalidate(); 
board.setLeftMessage("Not"); 
board.setRightMessage("Here"); 
board.revalidate(); 
Date current = new Date(); 
long timeNow = current.getTime(); 
Date newDate = new Date(timeNow + 1000); 
while (current.before(newDate)) 
    current = new Date(); 

, но не повезло и там. У кого-нибудь есть предложение? Большое спасибо.

+4

Не блокируйте основной нить. – EboMike 2010-12-03 19:10:33

ответ

8

Вы блокируете поток отправки событий AWT (EDT). EDT обрабатывает перерисовку и ввод событий, поэтому ваш код не должен быть многопоточным (что было бы практически невозможно). Используйте javax.swing.Timer, чтобы отправить событие позже на EDT. (Не путайте javax.swing.Timer с java.util.Timer!)

+0

Ничего себе - хотя вы сказали - «не путайте», мне все же удалось это сделать. Должен был сделать это полужирным;) – javamonkey79 2010-12-03 19:31:46

+1

@ javamonkey79 Я действительно добавил этот бит после того, как увидел ваш ответ. (Stack Overflow дает пятиминутное окно, в котором изменения не отображаются в истории.) – 2010-12-03 20:18:20

3

Посмотрите на javax.swing.Timer - Я думаю, что это то, что вам нужно для этого.

EDIT # 1: Документация Sun \ Oracle на самом деле предполагает использование таймеров Swing от here.

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

РЕДАКТИРОВАТЬ # 2: Похоже, что есть некоторые основные базовые учебные пособия here.

EDIT # 3: Убрано предложение использования TimerTask - в данном случае это была бы плохая идея.

+0

Если вы используете `TimerTask`, вы будете находиться вне EDT и, следовательно, в опасности. – 2010-12-03 19:11:16

+0

@Tom - как так? Можете ли вы уточнить? – javamonkey79 2010-12-03 19:15:03

1

Вы не должны обновлять компоненты графического интерфейса из основного потока. Используйте SwingUtilities.invokeLater запланировать обновление на потоке событий:

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
    board.invalidate(); 
    board.setLeftMessage("Not"); 
    board.setRightMessage("Here"); 
    board.revalidate(); 
    } 
}; 
2

Ваш «давно работает задача» должна работать в отдельном потоке. Затем, когда вы хотите обновить GUI, вам нужен код для запуска в потоке отправки событий (EDT). Затем вы можете попросить отдельную тему спать, и это не повлияет на картину GUI.

Для этого вы должны использовать SwingWorker. Прочтите раздел из руководства Swing по телефону Concurrency для получения дополнительной информации.

Если вам не нравится использование SwingWorker, вам необходимо создать свой собственный поток и обернуть код, обновляющий GUI в SwingUtilities.invokeLater().

1

Thread.sleep - долго работающая задача. Когда вы выполняете такую ​​задачу в EDT, она блокирует выполнение всех запросов на перерисовку. Все запросы на перерисовку, которые ожидаются и которые были отправлены во время фазы сна, поставлены в очередь для дальнейшей обработки.

В результате, когда EDT выходит из фазы sleep, он объединяет все такие запросы на перерисовку (если коалесцирование включено, которое является свойством по умолчанию) в одну перерисовку, которая выполняется. Если коалесцирование не включено, все запросы в очередь выполняются последовательно без какого-либо промежутка времени между ними. В результате кажется, что пользовательский интерфейс не обновлялся.

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

Смежные вопросы