2016-04-05 2 views
1

У меня есть поток, который я запускаю, когда нажимаю кнопку запуска. То, что я хочу сделать, - это перекрасить ярлыки, чтобы они содержали информацию, которую вносит мой поток. Единственная проблема, с которой я сталкиваюсь, заключается в том, что jLabels перерисовываются только после того, как поток выполняется. Может ли кто-нибудь дать мне какие-либо предложения по поводу того, как я могу перерисовать его, когда поток запущен? Благодарю.Перерисовать компонент качания во время работы нитка

Вот отрывок из моего кода:

Store m = new Store(); //Store extends Thread 
private void startActionPerformed(java.awt.event.ActionEvent evt) {  
    .... 
    //I get the simulation time of the store from a textbox 
    //the thread runs for this number of seconds 
    //when it is done, the store is closed(the open variable is set to false) 
    .... 

    m.start(); 

    while (m.isOpen()) { 
     queue0.setText(String.valueOf(m.clientiCasai(0))); 
     //here I will have more queues 
     .... 
     noOfClients.repaint(); //this is the label that should show the number of clients in queue 0 
    } 
} 
+0

Не запускайте этот цикл while на EDT, но пусть ваш поток запускает события перерисовки, которые должны произойти, если поток вызывает 'noOfClients.setText (что угодно)'. – Thomas

+3

Не блокируйте нить качания. Перекраска вызывается только после выполнения вашего действия. 'repaint()' не выполняет перекраски, а только сообщает swing, что компонент должен быть перекрашен позже. Для получения дополнительной информации о [Concurency in Swing] (https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) –

+0

Оберните в setText() в SwingUtilities.invokeAndWait() – StanislavL

ответ

1

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

Ваш noOfClients.repaint() вызов должен быть сделан на EDT, но и ваша установка нового значения queue0 этикетке вызов должен быть EDT.

Для упрощения. Если у вас есть queue0.setText() звоните в EDT, перекраска будет сделана для вас, чтобы вы могли ее удалить.

Это может быть достигнуто путем вызова:

SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      queue0.setText("<text>"); 
     } 
    }); 

Чтобы решить проблему можно либо передать ссылку на экземпляр проведения метод startActionPerformed() к вашему магазину и вызвать его оттуда при необходимости или вы можете запустить другой поток, который контролирует ход магазина и распространяет его на Swing EDT.

+1

'm.start() ; 'вызывается из' startActionPerformed'. Другими словами, он запускает поток в 'startActionPerformed', поэтому' startActionPerformed' работает в EDT. – Oebele

1

Проблема в том, что фактическая живопись также выполняется во время цикла событий EDT; ваш цикл while() в основном предотвращает продолжение EDT. Возможным обходным путем было бы иметь дополнительный поток, который позаботился бы об обновлении метки.

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