Java SwingWorker没有响应

Java SwingWorker没有响应,java,swing,format,swingworker,Java,Swing,Format,Swingworker,我想做什么? 单击Start jb按钮,将执行SwingWorker。在doInBackground()方法中,我将arrNames的每个索引传递给publish()方法,以便它可以显示在JTextArea中 发生了什么事? 如果我不保留行系统输出格式(“计数器:%d%n”,计数器)作为注释,在SwingWorker的我的doInBackground()方法中,那么SwingWorker就按照预期工作了。虽然如果我注释掉它,那么SwingWorker停止响应 我做错什么了吗? Java版本:

我想做什么?

单击
Start jb按钮
,将执行
SwingWorker
。在
doInBackground()
方法中,我将
arrNames
的每个索引传递给
publish()
方法,以便它可以显示在
JTextArea

发生了什么事?

如果我保留行
系统输出格式(“计数器:%d%n”,计数器)
作为注释,在
SwingWorker
的我的
doInBackground()
方法中,那么
SwingWorker
就按照预期工作了。虽然如果我注释掉它,那么
SwingWorker
停止响应

我做错什么了吗?


Java版本: 以下是我正在使用的代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SwingWorkerExample1
{
    private JLabel statusLabel;
    private JTextArea tArea;
    private JButton startButton;
    private JButton stopButton;

    private BackgroundTask backgroundTask;

    private ActionListener buttonActions =
                            new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent ae)
        {
            JButton source = (JButton) ae.getSource();
            if (source == startButton)
            {
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                backgroundTask = new BackgroundTask();
                backgroundTask.execute();
            }
            else if (source == stopButton)
            {
                backgroundTask.cancel(true);
                stopButton.setEnabled(false);
                startButton.setEnabled(true);
            }
        }
    };

    private void displayGUI()
    {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setBorder(
            BorderFactory.createEmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(5, 5));

        statusLabel = new JLabel("Status Bar", JLabel.CENTER);

        tArea = new JTextArea(20, 20);
        tArea.setWrapStyleWord(true);
        tArea.setLineWrap(true);        
        JScrollPane textScroller = new JScrollPane();
        textScroller.setBorder(
            BorderFactory.createTitledBorder("Textual OUTPUT : "));
        textScroller.setViewportView(tArea);

        startButton = new JButton("Start");
        startButton.addActionListener(buttonActions);
        stopButton = new JButton("Stop");
        stopButton.setEnabled(false);
        stopButton.addActionListener(buttonActions);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);

        contentPane.add(statusLabel, BorderLayout.PAGE_START);
        contentPane.add(textScroller, BorderLayout.CENTER);
        contentPane.add(buttonPanel, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class BackgroundTask extends SwingWorker<Void, String>
    {
        private int counter = 0;

        private String[] arrNames = { "US Rates Strategy Cash",
            "Pavan Wadhwa(1-212) 844-4597", "Srini Ramaswamy(1-212) 844-4983",
            "Meera Chandan(1-212) 855-4555", "Kimberly Harano(1-212) 823-4996",
            "Feng Deng(1-212) 855-2555", "US Rates Strategy Derivatives",
            "Srini Ramaswamy(1-212) 811-4999",
            "Alberto Iglesias(1-212) 898-5442",
            "Praveen Korapaty(1-212) 812-3444", "Feng Deng(1-212) 812-2456",
            "US Rates Strategy Derivatives", "Srini Ramaswamy(1-212) 822-4999",
            "Alberto Iglesias(1-212) 822-5098",
            "Praveen Korapaty(1-212) 812-3655", "Feng Deng(1-212) 899-2222" };

        public BackgroundTask()
        {
            statusLabel.setText((this.getState()).toString());
            System.out.println(this.getState());
        }

        @Override
        protected Void doInBackground()
        {
            statusLabel.setText((this.getState()).toString());
            System.out.println(this.getState());
            while (!isCancelled())
            {
                counter %= arrNames.length;
                //System.out.format("Counter : %d%n", counter);
                publish(arrNames[counter]);
                counter++;
            }
            statusLabel.setText((this.getState()).toString());
            System.out.println(this.getState());
            return null;
        }

        @Override
        protected void process(java.util.List<String> messages)
        {
            for (String message : messages)
                tArea.append(String.format(message + "%n"));
        }
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new SwingWorkerExample1().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

编辑2: 只有
doInBackground()
发生了更改,引发了上述异常:

@Override
protected Void doInBackground()
{
    Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
            statusLabel.setText((BackgroundTask.this.getState()).toString());
        }
    };
    EventQueue.invokeLater(runnable);

    System.out.println(this.getState());
    while (!isCancelled())
    {
        counter %= arrNames.length;             
        //System.out.format("Counter : %d%n", counter);
        publish(arrNames[counter]);
        try
        {Thread.sleep(30);}
        catch(InterruptedException ie)
        {ie.printStackTrace();}
        counter++;
    }
    runnable = new Runnable()
    {
        @Override
        public void run()
        {
            statusLabel.setText((BackgroundTask.this.getState()).toString());
        }
    };
    EventQueue.invokeLater(runnable);
    System.out.println(this.getState());
    return null;
}
评论

  • @kleopatra这是一个文档错误,至少在jdk7中已修复:-),请确定哪些JDK中的错误显示为来自carousel

  • wait/notify是线程,SwingWorker是未来的,实现得非常糟糕,意味着没有通知程序,你就把东西放到管道里,在另一边等待

  • 这条管道的第一面和第二面之间似乎什么都没有,这就是为什么我试图从doInBackground调用Thread,Runnable,Executor(Runnable),并忽略publish,process,setProcess的原因

  • 另一个有趣的问题是get()和exception(s)all exception,而不仅仅是1st。从这根管子的一边和另一边

  • 有两种方法可以使用Swingwoker

  • 尽量避免使用SwingWorker

  • 使用doInBackground作为workers线程的桥接器,使用publish、process、setProcess、wait for done()作为输出,使用done()作为获取异常的通知程序,即SwingWorker结束的通知程序

如果我添加Thread.sleep(…),它确实可以工作,但是,它会抛出一个 中断异常

显然产生异常的代码(从OP的编辑中复制):

但是,原因是取消工作进程的代码(在actionListener中):

它明确地告诉工作者通过..取消。。中断线程。从其api文档:

MayInterruptFrunning-如果执行此任务的线程应被中断,则为true;否则,允许完成正在进行的任务


顺便说一句:捕捉异常而不做任何事情(从而有效地忽略中断)不是最好的主意。在这种情况下,可能不会造成太大损害-因为检查了取消状态。典型的工作者实现要么捕获并返回,如果需要,在执行一些内部清理之后,要么根本不处理它

在其他答案的基础上,不要从后台线程更新GUI,这会阻止EDT,也不要试图避免
invokeLater()
的问题。相反,
publish()
生成所需结果,并更新
process()
中的
statusLabel
tArea
,如下所示。对于测试,
Thread.sleep(100)
模拟了一个小的延迟,但是您可以使用
Thread.yield()
,如图所示。您还可以在
PropertyChangeListener
中更新GUI,如图所示

导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.event.*;
导入javax.swing.*;
公共类SwingWorkerExample1{
专用JLabel状态标签;
私人区;
私有JButton开始按钮;
私人按钮停止按钮;
私人背景任务背景任务;
私有ActionListener按钮操作=新建ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
JButton source=(JButton)ae.getSource();
如果(源==开始按钮){
startButton.setEnabled(错误);
stopButton.setEnabled(真);
backgroundTask=新的backgroundTask();
backgroundTask.execute();
}else if(source==停止按钮){
backgroundTask.cancel(true);
stopButton.setEnabled(错误);
startButton.setEnabled(真);
}
}
};
私有void displayGUI(){
JFrame=新JFrame(“Swing Worker示例”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane=新的JPanel();
contentPane.setOrder(
createEmptyByOrder(5,5,5,5));
setLayout(新的BorderLayout(5,5));
statusLabel=新的JLabel(“状态栏”,JLabel.CENTER);
tArea=新的JTextArea(20,20);
tArea.setWrapStyleWord(真);
跗跖线包裹(真);
JScrollPane textcroller=新的JScrollPane();
textScroller.setOrder(
createTitleBorder(“文本输出:”);
textScroller.setViewportView(tArea);
startButton=新的JButton(“开始”);
addActionListener(按钮操作);
stopButton=新按钮(“停止”);
stopButton.setEnabled(错误);
stopButton.addActionListener(按钮操作);
JPanel buttonPanel=新的JPanel();
按钮面板添加(开始按钮);
按钮面板。添加(停止按钮);
contentPane.add(statusLabel,BorderLayout.PAGE_START);
添加(textScroller、BorderLayout.CENTER);
contentPane.add(按钮面板,边框布局,页面结束);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
私有类BackgroundTask扩展SwingWorker{
专用整数计数器=0;
私有字符串[]arrNames={“美国利率策略现金”,
“帕万瓦
C:\Mine\JAVA\J2SE\classes>java SwingWorkerExample1
PENDING
STARTED
java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:108)
        at SwingWorkerExample1$BackgroundTask.doInBackground(SwingWorkerExample1.java:76)
        at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)
        at javax.swing.SwingWorker.run(SwingWorker.java:335)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)
DONE
@Override
protected Void doInBackground()
{
    Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
            statusLabel.setText((BackgroundTask.this.getState()).toString());
        }
    };
    EventQueue.invokeLater(runnable);

    System.out.println(this.getState());
    while (!isCancelled())
    {
        counter %= arrNames.length;             
        //System.out.format("Counter : %d%n", counter);
        publish(arrNames[counter]);
        try
        {Thread.sleep(30);}
        catch(InterruptedException ie)
        {ie.printStackTrace();}
        counter++;
    }
    runnable = new Runnable()
    {
        @Override
        public void run()
        {
            statusLabel.setText((BackgroundTask.this.getState()).toString());
        }
    };
    EventQueue.invokeLater(runnable);
    System.out.println(this.getState());
    return null;
}
while (!isCancelled()) {
    counter %= arrNames.length;
    // System.out.format("Counter : %d%n", counter);
    publish(arrNames[counter]);
    try {
        Thread.sleep(30); // throws
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
    counter++;
}
backgroundTask.cancel(true);
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;

public class SwingWorkerExample1 {

    private JLabel statusLabel;
    private JTextArea tArea;
    private JButton startButton;
    private JButton stopButton;
    private BackgroundTask backgroundTask;
    private ActionListener buttonActions = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            JButton source = (JButton) ae.getSource();
            if (source == startButton) {
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                backgroundTask = new BackgroundTask();
                backgroundTask.execute();
            } else if (source == stopButton) {
                backgroundTask.cancel(true);
                stopButton.setEnabled(false);
                startButton.setEnabled(true);
            }
        }
    };

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setBorder(
            BorderFactory.createEmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(5, 5));

        statusLabel = new JLabel("Status Bar", JLabel.CENTER);

        tArea = new JTextArea(20, 20);
        tArea.setWrapStyleWord(true);
        tArea.setLineWrap(true);
        JScrollPane textScroller = new JScrollPane();
        textScroller.setBorder(
            BorderFactory.createTitledBorder("Textual OUTPUT : "));
        textScroller.setViewportView(tArea);

        startButton = new JButton("Start");
        startButton.addActionListener(buttonActions);
        stopButton = new JButton("Stop");
        stopButton.setEnabled(false);
        stopButton.addActionListener(buttonActions);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);

        contentPane.add(statusLabel, BorderLayout.PAGE_START);
        contentPane.add(textScroller, BorderLayout.CENTER);
        contentPane.add(buttonPanel, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class BackgroundTask extends SwingWorker<Void, String> {

        private int counter = 0;
        private String[] arrNames = {"US Rates Strategy Cash",
            "Pavan Wadhwa(1-212) 844-4597", "Srini Ramaswamy(1-212) 844-4983",
            "Meera Chandan(1-212) 855-4555", "Kimberly Harano(1-212) 823-4996",
            "Feng Deng(1-212) 855-2555", "US Rates Strategy Derivatives",
            "Srini Ramaswamy(1-212) 811-4999",
            "Alberto Iglesias(1-212) 898-5442",
            "Praveen Korapaty(1-212) 812-3444", "Feng Deng(1-212) 812-2456",
            "US Rates Strategy Derivatives", "Srini Ramaswamy(1-212) 822-4999",
            "Alberto Iglesias(1-212) 822-5098",
            "Praveen Korapaty(1-212) 812-3655", "Feng Deng(1-212) 899-2222"};

        public BackgroundTask() {
            statusLabel.setText((this.getState()).toString());
        }

        @Override
        protected Void doInBackground() {
            while (!isCancelled()) {
                counter %= arrNames.length;
                publish(arrNames[counter]);
                counter++;
                try {
                    Thread.sleep(100); // simulate latency
                } catch (InterruptedException ex) {
                    publish("Cancelled: " + isCancelled());
                }
            }
            return null;
        }

        @Override
        protected void process(java.util.List<String> messages) {
            statusLabel.setText((this.getState()).toString());
            for (String message : messages) {
                tArea.append(String.format(message + "%n"));
            }
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new SwingWorkerExample1().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}