I'm fairly new to threads and haven't written Java in a long time so bear with me here. I have a very simple GUI. It has a counter, a status label, and two buttons, start and stop respectively.
What I wanted it to do was update my status label using a counter
thread. When I hit start it supposedly starts the counter at 0 and increments it every second
, and when I choose to hit stop
it should suspend
the current thread and wait
for the start button to be pressed again. However whenever I hit stop it just suspends an waits for a second and resumes the counting. When in reality I want it to stay suspended. I'm not really sure why it's doing that, tried searching it before posting here but got nothing. Also feel free to criticize on anything you'd like.
Here's what I have:
UPDATED AS PER @MadProgrammer's answer.
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class main extends JFrame
{
JLabel countLabel = new JLabel("0");
JLabel statusLabel = new JLabel("Task not completed.");
JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
CounterThread worker = new CounterThread("worker", countLabel, statusLabel);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Main("Counter Demo");
}
});
}
public Main(String title) {
super(title);
setLayout(new GridBagLayout());
countLabel.setFont(new Font("serif", Font.BOLD, 28));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE;
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 1;
add(countLabel, gc);
gc.gridx = 0;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
add(startButton, gc);
gc.gridx = 0;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 1;
add(stopButton, gc);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
worker.start();
//notify();
}
});
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
worker.suspend();
}
});
setSize(200, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public class CounterThread implements Runnable {
public Thread t;
public String threadName;
boolean suspended = false;
JLabel countLabelName;
JLabel statusLabelName;
CounterThread(String name, JLabel cLabel, JLabel sLabel) {
this.threadName = name;
this.countLabelName = cLabel;
this.statusLabelName = sLabel;
}
public void run() {
try {
// Simulate doing something useful.
for (int i = 0; i <= 10; i++) {
synchronized (this) {
if (suspended)
{
wait();
}
}
final int count = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
countLabelName.setText(Integer.toString(count));
}
});
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
statusLabelName.setText("Completed.");
}
});
this.start();
}
public boolean getStatus() {
return t == null;
}
public void start() {
if (getStatus()) {
//t = new Thread(new CounterThread(this.threadName, this.countLabelName, this.statusLabelName));
t = new Thread(this);
t.start();
}
}
public void suspend() {
statusLabelName.setText("Task is paused");
suspended = true;
}
//create an object whose only purpose is to synchronize
synchronized void resume() {
statusLabelName.setText("Task has resumed");
suspended = false;
this.notify();
}
}
}