Обновление GUI другим потоком в Java (качели) - PullRequest
7 голосов
/ 29 августа 2011

У меня есть основная программа, в которой GUI основан на колебании и в зависимости от одного из четырех состояний элементы GUI имеют разные параметры.

public class Frame extends JFrame implements Runnable {
Status status = 1;
...
@Override
public void run() {
    switch (status) {
        case 1:
        ...
        case 2:
        ...
}

public void updateGUI(Status status) {
   this.status = status;
   SwingUtilities.invokeLater(this);
}

И если я хочу обновить GUI, то вызывает только updateGUIс соответствующим параметром, и все в порядке.Но программа также создает дополнительный поток, который после обработки соответствующих данных должен изменить основную программу графического интерфейса.К сожалению, я не могу в этой теме вызвать метод updateGUI (..).

Я знаю, что могу использовать invokeLater или SwingWorker для обновления, но существует более 10 элементов, поэтому я бы предпочел использовать метод udpateGUI ().

Буду благодарен за любую подсказку.

Ответы [ 2 ]

19 голосов
/ 29 августа 2011

Вот небольшой фрагмент, который вы можете добавить к методу, чтобы убедиться, что он выполняется в потоке GUI. Он полагается на isEventDispatchThread().

public void updateGUI(final Status status) {
   if (!SwingUtilities.isEventDispatchThread()) {
     SwingUtilities.invokeLater(new Runnable() {
       @Override
       public void run() {
          updateGUI(status);
       }
     });
     return;
   }
   //Now edit your gui objects
   ...
}
10 голосов
/ 30 августа 2011

Если вы сделаете поток поля status безопасным, то вы можете вызвать setStatus прямо из фонового потока.Чтобы сделать состояние потокобезопасным, внесите изменения в блок синхронизации и сделайте переменную volatile, чтобы обновления в других потоках становились видимыми.

Например,

public class Frame extends JFrame implements Runnable {
private volatile Status status = 1;
...
@Override
public void run() {
    switch (status) {
        case 1:
        ...
        case 2:
        ...
}

public void updateGUI(Status status) {
   setStatus(status);
   SwingUtilities.invokeLater(this);
}

private synchronized void setStatus(Status status) {
   this.status = status;
}

После внесения этих изменений,нормально звонить setStatus из любого потока.

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