2013-09-11 5 views
0

Предположим, что у меня есть функция refresh(), которая вызывает две другие функции, одна из которых - это функция longData(), которая должна быть запущена с EDT и other - это быстрая функция repaint(), которая запускается в EDT и которая копирует компоненты GUI.Java-потоки: пусть функция EDT ожидает долговременной работы от EDT

refresh() 
{ 
    clearData(); //off the EDT function 
    repaint(); //in the EDT function 
} 

Что такое надлежащий способ обработки перерисовки, когда требуется выполнить более длительную операцию, например clearData(). Позволяет ли поток clearData запускать repaint() после того, как он будет закончен надлежащим образом? Как это может быть сделано?

ответ

0
refresh() { 
    new Runnable(){ 
     clearData(); 
     SwingUtilities.invokeLater(new Runnable() { 
      repaint(); 
     }); 
    }.run(); 
} 

Обратите внимание, что перекрасить будет зарегистрирован, который будет вызван после того, как clearData(); вернулся, так, это гарантировано, что repaint() будет выполняться после того, как clearData().

0

Да, запустите repaint() после завершения clearData(). Вы можете использовать SwingUtilties.invokeLater() или аналогично, чтобы получить repaint() для запуска по EDT.

Возможная реализация

final Runnable CLEAR_THEN_REPAINT = new Runnable() { 
    public void run() { 
     clearData(); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { repaint(); } 
     }); 
    } 
}; 

void refresh() { 
    if (SwingUtilities.isEventDispatchThread()) { 
     new Thread(CLEAR_THEN_REPAINT).start(); 
    } else { 
     CLEAR_THEN_REPAINT.run(); 
    } 
} 
+0

SwingUtilities.invokeLater позволит перерисовать() запустить до или после clearData, в то время как я хочу, чтобы repaint() всегда вызывался после, однако я не хочу, чтобы он блокировал ожидание clearData(), иначе GUI замерзнет. Для этого недостаточно invokeLater и invokeAndWait. – dendini

+0

@dendini: Как я уже сказал, запустите repaint() после завершения clearData(). " Я только упомянул 'invokeLater()' как способ запустить 'repaint()' на EDT. Ответ Анаса - это именно то, что я предлагал, в форме кода (хотя его внешний «Runnable» кажется посторонним, поскольку он не запускается в другом потоке, как написано в настоящее время). –