SwingWorker not responding

后端 未结 3 1868
攒了一身酷
攒了一身酷 2020-11-28 16:35

What I am trying to do ?

At the click of the Start JButton, the SwingWorker will execute. Inside the doInBackground(

相关标签:
3条回答
  • 2020-11-28 17:02

    comments

    • @kleopatra that's a documentation bug, fixed in jdk7 at least :-), please which of JDKs those bugs are shown as from carousel ....,

    • wait/notify is for thread, SwingWorker is Future, very bad implemented, means without notifiers, you put something to the tube and waiting on another side,

    • seems like as nothing betweens one and second side of this tube, this reason why I tried to invoke Thread, Runnable, Executor(Runnable) from doInBackground, and to ignore publish, process, setProcess

    • another funny issue is to get() and exception(s) all exception, not only 1st. from one and second side of this tube

    • there are two ways how to use SwingWokrer

      1. try to avoid to use SwingWorker

      2. use doInBackground as bridge for workers thread, for output to use publish, process, setProcess, wait for done(), and use done() as notifier for get an exception, notifier that SwingWorker ended

    0 讨论(0)
  • 2020-11-28 17:06

    if I add Thread.sleep(...), it does work, though, it throws a InterruptedException

    The code that apparently produces the exception (copied from OP's edit):

    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++;
    }
    

    The reason, though, is the code that cancels the worker (in the actionListener):

    backgroundTask.cancel(true);
    

    which explicitly tells the worker to cancel by .. interrupting the thread. From its api doc:

    mayInterruptIfRunning - true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete

    As an aside: catching the exception and doing nothing (thereby effectively ignoring the interrupt) is not the best of ideas. Probably not too damaging in this case - due to checking the cancelled status. Typical worker implementations either catch and return, after doing some internal cleanup if needed, or don't handle it at all.

    0 讨论(0)
  • 2020-11-28 17:12

    Amplifying on the other answers, don't update the GUI from your background thread, which blocks the EDT, and don't try to avoid the problem with invokeLater(). Instead, publish() the desired result and update both statusLabel and tArea in process(), as suggested below. For testing, Thread.sleep(100) simulates a small latency, but you can use Thread.yield(), as shown here. You can also update the GUI in a PropertyChangeListener, as shown here.

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题