Вопрос по concurrency, swing, java – Обновление GUI из запускаемого

2

Я создаю приложение Swing, и одна часть его функциональности должна заключаться в том, чтобы обрабатывать и выводить некоторый текст визуально и на слух (используя Mary TTS). Мне нужно несколько советов о том, как лучше общаться с графическим интерфейсом и классами обработки текста.

Класс GUI является подклассом JPanel. В этом у меня есть класс, реализующий Runnable, называемый LineProcesser, который подготавливает текст для отправки на аудиоплеер. Я использую потоковый исполнитель, чтобы скрыть это от EDT (это может быть не лучшим способом, но, похоже, он достигнет результата, который я получу после).

Я намерен, чтобы LineProcessor пропустил весь текст и обновил JTextArea в конце каждой строки. Кроме того, он должен будет остановить и ждать ввода пользователя в определенных точках. После того, как пользовательский ввод был завершен, класс GUI должен сказать ему, чтобы он возобновил обработку.

Следующий код иллюстрирует то, что у меня сейчас есть:

<code>public class MyPanel extends JPanel {
    ExecutorService lineExecutor = Executors.newSingleThreadExecutor();
    Runnable lineProcessor = new LineProcessor();

    public class LineProcessor implements Runnable {

        private int currentLineNo = 0;

            public LineProcessor() {
            //  ...
            }

            @Override
            public void run() {
                // call getText();  
                // call playAudio();
                currentLineNo++;
            }
        }
    }

    private JButton statusLbl = new JLabel();       
    private JButton mainControlBtn = new JButton();

    private void mainControlBtnActionPerformed(ActionEvent evt) {

        if (mainControlBtn.getText().equals("Start")) {
                          lineExecutor.submit(lineProcessor);
                          mainControlBtn.setText("Running");
        }
    }
}
</code>

Как LineProcessor может уведомлять компоненты GUI о том, что они должны измениться, и как его можно приостановить и перезапустить из GUI? Я не совсем понимаю, нужен ли мне Swing Worker, слушатели свойства / события или что-то еще? Примеры, которые я читал, имеют смысл, но я не вижу, как их можно применить к коду, который у меня здесь есть.

Ваш Ответ

3   ответа
6

Все, что вам нужно сделать, это обернуть любые вызовы Swing в Runnable и поставить его в очередь на EDT черезSwingUtilities.invokeLater(myRunnable);, Вот и все. Нет необходимости в SwingWorker.

например.,

public class LineProcessor implements Runnable {
  private int currentLineNo = 0;
  Runnable LineProcessor = new LineProcessor();  // won't this cause infinite recursion?

  public LineProcessor() {
     // ...
  }

  @Override
  public void run() {
     // call getText();
     // call playAudio();
     currentLineNo++;

     SwingUtilities.invokeLater(new Runnable() {
        public void run() {
           // *** Swing code can go here ***
        }
     });
  }
}
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededinvokeLaterError: User Rate Limit ExceededinvokeAndWaitError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededCountDownLatchError: User Rate Limit Exceeded sonicdeathmonkey
3

Place your long running code in Swing Worker. Create new property change Event, listener, manager In your SwingWorker, when the change event occurs, call PropertyChangeManager to notify all the liseners. All GUI components which wants to be notified with the event should register themselves with the PropertyChangeManager. Your PropertyChangeManager will call customProperyChange method of the PropertyChangeListener and will pass the properyChangeEvent
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

SwingWorker, Этот класс позволяет выполнять работу над рабочим потоком, периодически обновляя EDT, а также обновляя EDT.

Несколько примеров доступны на SO и в учебниках по Swing. Всего несколько ссылок

The 'How to use progress bars tutorial', which happens to update a text area as well The 'Concurrency in Swing' tutorial, a must-read if you start with SwingWorker The SwingWorker javadoc

Отчет о прогрессе может быть сделан сpublish метод, эти результаты будут переданыprocess метод, в котором вы можете обновить пользовательский интерфейс. В конце концов,done вызывается метод, позволяющий выполнить некоторые окончательные обновления пользовательского интерфейса.

Для функции паузы / перезапуска ... вы можете использоватьinvokeAndWait вdoInBackground метод с вызовом метода блокировки (например, показываяJOptionPane запрашивая ввод пользователя). Но если вы начнете использоватьinvokeAndWait вdoInBackground было бы излишне использоватьSwingWorker и вы можете просто выбрать подход @Hovercraft Full Of Eels предложил

Error: User Rate Limit Exceeded sonicdeathmonkey
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededCountDownLatchError: User Rate Limit ExceededinvokeAndWaitError: User Rate Limit Exceeded sonicdeathmonkey
Error: User Rate Limit Exceeded

Похожие вопросы