Java 多线程Jframes中的SwingWorker
我正在创建4个线程,每个线程都与一个UI关联。 UI执行长时间运行的任务,为此我使用了SwingWorker。 但出现的问题不是作为多线程应用程序运行,而是在队列中运行 有趣的是,当我删除SwingWorker时,它的行为和运行都是多线程的 我的代码如下: 新阶级 用户界面类Java 多线程Jframes中的SwingWorker,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我正在创建4个线程,每个线程都与一个UI关联。 UI执行长时间运行的任务,为此我使用了SwingWorker。 但出现的问题不是作为多线程应用程序运行,而是在队列中运行 有趣的是,当我删除SwingWorker时,它的行为和运行都是多线程的 我的代码如下: 新阶级 用户界面类 在这种情况下,Swing中的工作线程的替代方案是什么?嗯,不,这不是Swing中多线程的工作方式 有一个单一的UI线程称为事件调度线程,所有的更新和与UI的交互都应该在EDT的上下文中完成,所以做一些事情,比如 @Over
在这种情况下,Swing中的工作线程的替代方案是什么?嗯,不,这不是Swing中多线程的工作方式 有一个单一的UI线程称为事件调度线程,所有的更新和与UI的交互都应该在EDT的上下文中完成,所以做一些事情,比如
@Override
public void run()
{
try
{
UI ui = new UI();
ui.startThread();
}
catch(Exception ae)
{
ae.printStackTrace();
}
}
而且
@Override
protected Integer doInBackground() throws Exception
{
for(int i=0; i<10;i++)
{
jTextArea1.append(""+i);
Thread.sleep(3000);
}
return 0;
}
嗯,不,这不是多线程在Swing中的工作方式 有一个单一的UI线程称为事件调度线程,所有的更新和与UI的交互都应该在EDT的上下文中完成,所以做一些事情,比如
@Override
public void run()
{
try
{
UI ui = new UI();
ui.startThread();
}
catch(Exception ae)
{
ae.printStackTrace();
}
}
而且
@Override
protected Integer doInBackground() throws Exception
{
for(int i=0; i<10;i++)
{
jTextArea1.append(""+i);
Thread.sleep(3000);
}
return 0;
}
要求多个独立的SwingWorker线程,每个线程分配给自己的进程并同时更新UI。是的,这正是示例所做的。您不能做的是从事件调度线程外部更新UI您的示例正是按照我在示例中解释的那样进行的。每个辅助线程只在一次更新其父UI并阻止其他辅助线程。其他线程仅在第一次完成时运行。好的,问题是。这就是它的工作方式。Swing是一个单线程框架。对ui的所有交互和修改必须在EDT上下文中进行。当每个SwingWorker独立执行时,当UI更新时,所有更新都会同步回EDT。这就是它的工作原理,没有其他方法可以做到这一点。其他任何事情都会导致最糟糕的图形瑕疵、不同步更新和更糟糕的线程死锁。要求多个独立的SwingWorker线程,每个线程分配给自己的进程并同时更新UI。是的,这正是示例所做的。您不能做的是从事件调度线程外部更新UI您的示例正是按照我在示例中解释的那样进行的。每个辅助线程只在一次更新其父UI并阻止其他辅助线程。其他线程仅在第一次完成时运行。好的,问题是。这就是它的工作方式。Swing是一个单线程框架。对ui的所有交互和修改必须在EDT上下文中进行。当每个SwingWorker独立执行时,当UI更新时,所有更新都会同步回EDT。这就是它的工作原理,没有其他方法可以做到这一点。任何其他的事情都会导致奇怪的图形瑕疵、不同步的更新以及更糟糕的线程死锁。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MultiThreadedUI {
public static void main(String[] args) {
new MultiThreadedUI();
}
public MultiThreadedUI() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
final List<TestPane> panes = new ArrayList<>(5);
for (int index = 0; index < 5; index++) {
panes.add(new TestPane(Integer.toString(index)));
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1));
for (TestPane pane : panes) {
frame.add(pane);
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (TestPane pane : panes) {
pane.makeItSo();
}
}
});
}
});
}
public class TestPane extends JPanel {
private JTextArea textArea;
private JProgressBar pb;
private String name;
public TestPane(String name) {
this.name = name;
textArea = new JTextArea(10, 5);
pb = new JProgressBar();
setLayout(new BorderLayout());
add(new JScrollPane(textArea));
add(pb, BorderLayout.SOUTH);
}
public void makeItSo() {
BackgroundWorker worker = new BackgroundWorker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
pb.setValue((Integer)evt.getNewValue());
}
}
});
worker.execute();
}
protected class BackgroundWorker extends SwingWorker<Integer, Integer> {
@Override
protected void process(List<Integer> chunks) {
for (Integer value : chunks) {
textArea.append(name + ": " + value + "\n");
}
}
@Override
protected Integer doInBackground() throws Exception {
int delay = (int)(Math.random() * 3000);
for (int i = 0; i < 10; i++) {
publish(i);
setProgress((int) (Math.round(((double) i / (double) 9) * 100)));
Thread.sleep(delay);
}
return 0;
}
}
}
}