Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程Jframes中的SwingWorker_Java_Multithreading_Swing_Swingworker - Fatal编程技术网

Java 多线程Jframes中的SwingWorker

Java 多线程Jframes中的SwingWorker,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我正在创建4个线程,每个线程都与一个UI关联。 UI执行长时间运行的任务,为此我使用了SwingWorker。 但出现的问题不是作为多线程应用程序运行,而是在队列中运行 有趣的是,当我删除SwingWorker时,它的行为和运行都是多线程的 我的代码如下: 新阶级 用户界面类 在这种情况下,Swing中的工作线程的替代方案是什么?嗯,不,这不是Swing中多线程的工作方式 有一个单一的UI线程称为事件调度线程,所有的更新和与UI的交互都应该在EDT的上下文中完成,所以做一些事情,比如 @Over

我正在创建4个线程,每个线程都与一个UI关联。 UI执行长时间运行的任务,为此我使用了SwingWorker。 但出现的问题不是作为多线程应用程序运行,而是在队列中运行

有趣的是,当我删除SwingWorker时,它的行为和运行都是多线程的

我的代码如下:

新阶级

用户界面类


在这种情况下,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;
            }

        }

    }

}