javax.swing.SwingWorker 中的问题
我已经制作了一个 swings 应用程序,但有一个问题如下:
我从事件调度线程启动了一个名为“Thread-Main”的 SwingWorker 线程,并将 GUI 的 JLabel 引用传递给了“Thread-Main” ”。
现在我已经从“Thread-Main”启动了 10 个线程。
现在我希望所有 10 个线程都应该更新 JLabel。
我怎样才能做到这一点?
有人告诉我,我可以通过首先将 SwingWorker 的所有 10 个线程子类化,然后调用publish("") 方法并在该“publish”方法中传递字符串,然后通过以下方法收集所有已发布的字符串来做到这一点: “Thread-Main”
@Override
protected void process(List<String> labelStrings) {
String count = labelStrings.get(labelStrings.size() - 1);
label.setText(count); // label is a reference to a label in the GUI
}
- 上面的做法是否正确呢?
- 这 10 个线程应该是 SwingWorker 的子类吗?
- 还有其他方法可以做到这一点吗?
I have made a swings application but there is one problem in that which is as follow:
I have initiated a SwingWorker thread named "Thread-Main" from the Event Dispatch Thread and have passed a JLabel reference of the GUI to the "Thread-Main".
Now I have started 10 threads from the "Thread-Main".
Now I want that all the 10 threads should update the JLabel.
How can I do that?
Someone told me that I can do this by first making all the 10 threads subclasses of SwingWorker and then calling the publish("") method and passing the string in that "publish" method and then collecting all the published strings by the following method in "Thread-Main"
@Override
protected void process(List<String> labelStrings) {
String count = labelStrings.get(labelStrings.size() - 1);
label.setText(count); // label is a reference to a label in the GUI
}
- Is the above approach is correct to do that?
- Should the 10 threads be subclasses of SwingWorker?
- Is there any other way to do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许更简单的方法是将更新 GUI 的代码包装在 SwingUtilities.invokeLater(...) 方法中。
编辑:在您的个人线程中,每当您想要更新标签时,您都会执行以下操作:
Maybe an easier approach is to wrap the code that updates the GUI in a SwingUtilities.invokeLater(...) method.
Edit: In your individual threads whenever you want to update the label you do:
SwingWorker
代码,您会发现它使用内部最多包含 10 个线程的ThreadPoolExecutor
。如果您同时启动多个SwingWorker
,它们都将使用此执行器运行。但是,您无法直接控制后台线程是否并行执行。我推荐的解决方案是:
SwingWorker
。doInBackground()
方法中直接或通过使用ExecutorService
启动 10 个线程。CountDownLatch
或CompletionService
在主线程(即SwingWorker
后台线程)和工作线程之间进行同步。示例
定义要调用的工作线程数并声明要更新的 JLabel。
将我们希望执行的工作单元定义为 Callable。
String
结果将用于更新JLabel
。现在启动一个
SwingWorker
,它将依次启动多个并行工作线程来执行任何处理。工作线程不会通过调用done()
返回结果(因此是Void
类型),但将编组中间String< /code> 通过调用
process(String... chunks)
将结果返回到 Swing 线程。定义
doInBackground()
以启动工作线程并使用CompletionService
阻止每个结果。现在我们实现 process(String... chunks) 来在调用时简单地更新 JLabel 。
最后,我们重写
done()
将任何异常编组回 Swing 线程。SwingWorker
code you'll see that it uses aThreadPoolExecutor
internally containing a maximum of 10 threads. If you kick off a number ofSwingWorker
's concurrently they will all run using this executor. However, you have no direct control over whether the background threads are executed in parallel.My recommended solution would be:
SwingWorker
.doInBackground()
method kick off 10 threads either directly or by using anExecutorService
.CountDownLatch
orCompletionService
to synchronize between your master thread (i.e.SwingWorker
background thread) and worker threads.Example
Define the number of worker threads to invoke and declare the JLabel to be updated.
Define the unit of work we wish to execute as a
Callable<String>
. TheString
result will be used to update theJLabel
.Now kick off a
SwingWorker
, which will in turn kick off multiple parallel workers to do any processing. The worker will not return a result via the call todone()
(hence theVoid
type) but will marshall intermediateString
results back onto the Swing thread by callingprocess(String... chunks)
.Define
doInBackground()
to kick off the worker threads and block for each result using aCompletionService
.Now we implement
process(String... chunks)
to simply update theJLabel
when called.Finally we override
done()
to marshall any exceptions back onto the Swing thread.为什么需要10个线程?为什么不用一根额外的线程呢?
真正的问题:你想要解决的问题是什么?
回答您的直接问题:
1)是的,这是正确的方法
2) 是的,线程应该是 SwingWorkers(如果您使用的是 netbeans,您也可以使用 Tasks,它也是 SwingWorker 的子类)
3) 如果您想拥有与 edt 分开的线程;那么你需要使用摇摆工人;这就是做到这一点的方式。
祝你好运!
why do you need 10 threads? why won't one extra thread do?
the real question: what is the problem you are trying to solve?
to answer your direct questions:
1) yes, that is the correct approach
2) yes, the threads should be SwingWorkers (if you are using netbeans, you can also use Tasks, which are subclasses of SwingWorker as well)
3) if you want to have a separate thread from the edt; then you need to use a swingworker; so that is the way to do it.
good luck!