Swing Threading в Java - PullRequest
       11

Swing Threading в Java

13 голосов
/ 02 апреля 2010

Насколько я понимаю, если я запускаю другой поток для выполнения каких-либо действий, мне потребуется SwingUtilities.invokeAndWait или SwingUtilities.invokeLater для обновления графического интерфейса, пока я нахожусь в указанном потоке. Пожалуйста, поправьте меня, если я ошибаюсь.

То, что я пытаюсь выполнить, относительно просто: когда пользователь нажимает кнопку «Отправить», я хочу (перед выполнением каких-либо действий) отключить кнопку отправки, выполнить действие и в конце действия снова включить кнопку. , Мой метод выполнения действия обновляет графический интерфейс напрямую (отображает результаты), когда он возвращает результаты.

Это действие в основном запрашивает сервер и возвращает некоторые результаты.

То, что я имею до сих пор:

boolean isRunning = false;

synchronized handleButtonClick() {
  if ( isRunning == false ) {
    button.setEnabled( false );
    isRunning = true;
    doAction();
  }
}

doAction() {
  new Thread() {
    try {
      performAction(); // Concern A
    } catch ( ... ) {
      displayStackTrace( ... ); // Concern B
    } finally {
      SwingUtilities.invokeLater ( /* simple Runnable to enable button */ );
      isRunning = false;
    }
  }
}

Для обеих моих проблем выше, я должен был бы использовать SwingUtilities.invokeAndWait, так как они оба обновят GUI? Все обновления GUI вращаются вокруг обновления JTextPane. Нужно ли мне в своей ветке проверять, нахожусь ли я на EDT, и если да, то я могу вызвать свой код (независимо от того, обновляет ли он графический интерфейс или нет) и НЕ использовать SwingUtilities.invokeAndWait?

РЕДАКТИРОВАТЬ: Вот что я делаю сейчас:

handleButtonClick() {
  if ( isRunning == true )
     return;
  disable button;
  SwingWorker task = new MyTask();
  task.execute();
}

...inside MyTask
doInBackground() {
  return performAction();
}

done() {
  result = get();
  enable button;
  isRunning = false;
  interpret result (do most of the GUI updates here);
}

Пока performAction() делает некоторые обновления графического интерфейса, я завернул их в:

if ( SwingUtil.isEDT() )
  doGUIupdate()
else
  SwingUtil.invokeLater( new Runnable() {
    run() {
      doGUIupdate();
    }
  } );

Надеюсь, это шаг в правильном направлении, пожалуйста, прокомментируйте, если вы считаете, что есть лучшие способы справиться с моей ситуацией.

Ответы [ 3 ]

18 голосов
/ 02 апреля 2010

На мой взгляд, вы почти никогда не должны использовать invokeAndWait(). Если что-то займет некоторое время, это заблокирует ваш пользовательский интерфейс.

Используйте SwingWorker для такого рода вещей. Взгляните на Повышение производительности приложений с помощью SwingWorker в Java SE 6 .

5 голосов
/ 02 апреля 2010

Вам следует рассмотреть возможность использования SwingWorker, поскольку он не будет блокировать поток пользовательского интерфейса, тогда как оба метода SwingUtilities будут выполняться в потоке EDT, таким образом блокируя пользовательский интерфейс.

0 голосов
/ 08 апреля 2016

Я храню простые Thread внутри EventQueue.invokeLater(...), и это работало гладко ...

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run(){

        new Thread(new Runnable(){
            public void run(){

                try{
                    EdgeProgress progress = EdgeProgress.getEdgeProgress();
                    System.out.println("now in traceProgressMonitor...");
                    while(true){
                        // here the swing update
                        if(monitor.getState() == ProgressMonitor.STATE_BUSY){
                            System.out.println(monitor.getPercentDone()/2);
                            progress.setProgress(monitor.getPercentDone()/2);
                        }else{
                            break;
                        }
                        Thread.sleep(5);
                    }
                }catch(InterruptedException ie){}

            }
        }).start();

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