SwingWorker not responding

format, java, swing, swingworker

Solution

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.

Problem

What I am trying to do ? At the click of the `Start JButton`, the `SwingWorker` will execute. Inside the `doInBackground()` method, I am passing each index of `arrNames`, to the `publish()` method, so that it can be displayed inside the `JTextArea`. What happened ? If I do not keep line `System.out.format("Counter : %d%n", counter);` as a comment, in my `doInBackground()` method of the `SwingWorker`, then the `SwingWorker` is working as expected. Though if I comment it out, then the `SwingWorker` stops responding. Am I doing something wrong ? Java Version : ``` java version "1.7.0_25" Java(TM) SE Runtime Environment (build 1.7.0_25-b16) Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode, sharing) ``` Here is the code I am using : ``` 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); } } ``` EDIT 1 : As suggested, if I add `Thread.sleep(...)`, it does work, though, it throws a `InterruptedException` as shown below. So the trick works. But is this the legitimate way of performing it ? ``` 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 ``` EDIT 2 : Only `doInBackground()` is changed, that raised the above exception : ``` @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; } ```

Original source

Related problems