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,属性/事件监听器或其他东西感到困惑?我读过的例子很有意义,但我看不出如何将它们应用到我这里的代码中.
您需要做的就是在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)