Threading Model in Swing with SwingWorker - Java Swing

Java examples for Swing:Swing Thread

Description

Threading Model in Swing with SwingWorker

Demo Code

import java.awt.BorderLayout;
import java.awt.Container;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

class SwingWorkerProcessor extends SwingWorker<Integer, Integer> {
  private final Main frame;
  private int iteration;
  private int intervalInMillis;

  public SwingWorkerProcessor(Main frame, int iteration,
      int intervalInMillis) {
    this.frame = frame;
    this.iteration = iteration;
    if (this.iteration <= 0) {
      this.iteration = 10;
    }//from   ww w. j a v  a2  s  .c  o  m

    this.intervalInMillis = intervalInMillis;

    if (this.intervalInMillis <= 0) {
      this.intervalInMillis = 1000;
    }
  }

  @Override
  protected Integer doInBackground() throws Exception {
    int sum = 0;
    for (int counter = 1; counter <= iteration; counter++) {
      sum = sum + counter;
      this.publish(counter);
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
      if (this.isCancelled()) {
        break;
      }
      Thread.sleep(intervalInMillis);
    }
    return sum;
  }

  @Override
  protected void process(List<Integer> data) {
    for (int counter : data) {
      frame.updateStatus(counter, iteration);
    }
  }

  @Override
  public void done() {
    frame.doneProcessing();
  }
}

public class Main extends JFrame {
  String startMessage = "Please click the start button...";
  JLabel statusLabel = new JLabel(startMessage);
  JButton startButton = new JButton("Start");
  JButton cancelButton = new JButton("Cancel");
  SwingWorkerProcessor processor;

  public Main(String title) {
    super(title);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    Container contentPane = this.getContentPane();
    cancelButton.setEnabled(false);

    contentPane.add(statusLabel, BorderLayout.NORTH);
    contentPane.add(startButton, BorderLayout.WEST);
    contentPane.add(cancelButton, BorderLayout.EAST);

    startButton.addActionListener(e -> startProcessing());
    cancelButton.addActionListener(e -> cancelProcessing());
  }

  public void setButtonStatus(boolean canStart) {
    if (canStart) {
      startButton.setEnabled(true);
      cancelButton.setEnabled(false);
    } else {
      startButton.setEnabled(false);
      cancelButton.setEnabled(true);
    }
  }

  public void startProcessing() {
    setButtonStatus(false);
    processor = new SwingWorkerProcessor(this, 10, 1000);
    processor.execute();
  }

  public void cancelProcessing() {
    processor.cancel(true);
    setButtonStatus(true);
  }

  public void updateStatus(int counter, int total) {
    String msg = "Processing " + counter + " of " + total;
    statusLabel.setText(msg);
  }

  public void doneProcessing() {
    if (processor.isCancelled()) {
      statusLabel.setText("Process cancelled ...");
    } else {
      try {
        int sum = processor.get();
        statusLabel.setText("Process completed. Sum is " + sum);
      } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
      }
    }
    setButtonStatus(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
      Main frame = new Main("SwingWorker Frame");
      frame.pack();
      frame.setVisible(true);
    });
  }
}

Related Tutorials