What's Wrong with This Code? Java Swing and Threading - ' Race Condition' (
Page 4 of 5 )
: The Code">
Race Condition: The Code
For the second example, I created another class that extends JFrame.
ADVERTISEMENT
This time, however, I put in two JButtons and a JProgressBar. One of the buttons starts a background timer that updates the progress bar, and the second button stops the background timer. The error in this code is quite a bit more subtle than the first.
See if you can spot the issues with it. Again: do your best to identify the problem before you peek at the answer!
package com.zarrastudios.example;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.*;
public class FrameExample2 extends JFrame {
private JButton activate, shutdown;
private JProgressBar progressBar;
private Ticker ticker;
public FrameExample2() {
super("Frame Example 2");
initAndLayoutComponents();
initListeners();
pack();
}
private void initListeners() {
activate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
ticker = new Ticker();
ticker.start();
activate.setEnabled(false);
shutdown.setEnabled(true);
}
});
shutdown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
ticker.shutdown();
activate.setEnabled(true);
shutdown.setEnabled(false);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
System.exit(0);
}
});
}
private void initAndLayoutComponents() {
JPanel main = new JPanel(new BorderLayout());
JPanel north = new JPanel(new FlowLayout());
JPanel south = new JPanel(new FlowLayout());
activate = new JButton("Activate");
shutdown = new JButton("Shutdown");
shutdown.setEnabled(false);
progressBar = new JProgressBar();
north.add(activate);
north.add(shutdown);
south.add(progressBar);
main.add(north, BorderLayout.NORTH);
main.add(south, BorderLayout.SOUTH);
setContentPane(main);
}
public static void main(String args[]) {
FrameExample2 fe2 = new FrameExample2();
fe2.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
System.exit(0);
}
});
fe2.setVisible(true);
}
class Ticker extends Thread {
private boolean running = true;
public void shutdown() {
running = false;
interrupt();
}
public void run() {
System.out.println("Starting counter");
for (int counter = 1; counter <= 10; counter++) {
if (!running) break;
progressBar.setValue(counter * 10);
try {
Thread.sleep(1000);
} catch (Exception e) {
//Expected exception
System.out.println("Sleep interrupted");
}
}
System.out.println("Counter is finished");
}
}
}