从runnable更新GUI

son*_*key 2 java concurrency user-interface swing event-dispatch-thread

我正在构建一个Swing应用程序,其中一部分功能应该是直观地和可听地处理和输出一些文本(使用Mary TTS).我需要一些关于GUI和文本处理类进行通信的最佳方法的建议.

GUI类是JPanel的子类.在其中我有一个实现Runnable的类,名为LineProcesser,它准备将文本分派给音频播放器.我正在使用一个线程执行器来阻止它离开EDT(这可能不是最好的方式,但它似乎达到了我所追求的结果).

我的目的是让LineProcessor运行所有文本并在每行的末尾更新JTextArea.此外,它需要停止并等待某些点的用户输入.用户输入完成后,GUI类应该告诉它继续处理.

以下代码说明了我目前拥有的内容:

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

LineProcessor如何通知他们需要更改的GUI组件以及如何从GUI中暂停和重新启动它们?我对是否需要Swing Worker,属性/事件监听器或其他东西感到困惑?我读过的例子很有意义,但我看不出如何将它们应用到我这里的代码中.

Hov*_*els 6

您需要做的就是在Runnable中包装任何Swing调用,并在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 ***
        }
     });
  }
}
Run Code Online (Sandbox Code Playgroud)