[英]Updating GUI from a runnable
I'm building a Swing application and one part of the functionality should be to process and output some text visually and audibly (using Mary TTS). 我正在构建一个Swing应用程序,其中一部分功能应该是直观地和可听地处理和输出一些文本(使用Mary TTS)。 I need some advice on the best way for the GUI and text processing classes to communicate. 我需要一些关于GUI和文本处理类进行通信的最佳方法的建议。
The GUI class is a subclass of JPanel. GUI类是JPanel的子类。 Within that I have a class implementing Runnable, called LineProcesser, which prepares the text to be dispatched to an audio player. 在其中我有一个实现Runnable的类,名为LineProcesser,它准备将文本分派给音频播放器。 I'm using a thread executor to keep this off the EDT (that may not be the best way but it seems to achieve the result I'm after). 我正在使用一个线程执行器来阻止它离开EDT(这可能不是最好的方式,但它似乎达到了我所追求的结果)。
My intention is for LineProcessor to run through all the text and update a JTextArea at the end of each line. 我的目的是让LineProcessor运行所有文本并在每行的末尾更新JTextArea。 Additionally it will need to halt and wait for user input at certain points. 此外,它需要停止并等待某些点的用户输入。 After the user input has been completed the GUI class should tell it to resume processing. 用户输入完成后,GUI类应该告诉它继续处理。
The following code illustrates what I currently have: 以下代码说明了我目前拥有的内容:
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");
}
}
}
How can LineProcessor notify GUI components that they need to change and how can it be paused and restarted from within the GUI? LineProcessor如何通知他们需要更改的GUI组件以及如何从GUI中暂停和重新启动它们? I'm confused as to whether I need a Swing Worker, property/event listeners or something else? 我对是否需要Swing Worker,属性/事件监听器或其他东西感到困惑? The examples I've read sort of make sense but I can't see how I can apply them to the code I have here. 我读过的例子很有意义,但我看不出如何将它们应用到我这里的代码中。
All you need to do is wrap any Swing calls in a Runnable, and queue it on the EDT via SwingUtilities.invokeLater(myRunnable);
您需要做的就是在Runnable中包装任何Swing调用,并通过SwingUtilities.invokeLater(myRunnable);
将其排在EDT上SwingUtilities.invokeLater(myRunnable);
. 。 That's it. 而已。 No need for a SwingWorker. 不需要SwingWorker。
eg, 例如,
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 ***
}
});
}
}
You will have to use both SwingWorker and Event methodology. 您必须同时使用SwingWorker和Event方法。
What you are looking for is a SwingWorker
. 您正在寻找的是SwingWorker
。 This class allows to perform the work on a worker thread, having periodical updates on the EDT, and in the end update the EDT as well. 该类允许在工作线程上执行工作,在EDT上定期更新,最后也更新EDT。
Several examples are available on SO and in the Swing tutorials. 有关SO和Swing教程的几个示例。 Just a few links 只是几个链接
SwingWorker
'Swurrency in Swing'教程,如果你从SwingWorker
开始必须阅读 SwingWorker
javadoc SwingWorker
javadoc Reporting progress can be done with the publish
method, these results will be passed to the process
method in which you can update the UI. 可以使用publish
方法完成报告进度,这些结果将传递给您可以更新UI的process
方法。 At the end, the done
method is called allowing you to perform some final UI updates. 最后,调用done
方法,允许您执行一些最终的UI更新。
For the pause/restart functionality ... you can use an invokeAndWait
in the doInBackground
method with a blocking method call (for example showing a JOptionPane
asking for user input). 对于暂停/重启功能...您可以在doInBackground
方法中使用invokeAndWait
和阻塞方法调用(例如,显示要求用户输入的JOptionPane
)。 But if you start using invokeAndWait
in the doInBackground
it might be overkill to use the SwingWorker
and you can simply opt for the approach @Hovercraft Full Of Eels suggested 但是如果你开始在doInBackground
使用invokeAndWait
,使用SwingWorker
可能会doInBackground
过分,你可以简单地选择@Hovercraft Full Of Eels建议的方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.