Home » Java Basics » 07 - A Simple GUI Application with Thread Management
7

The slideRunner Thread

How the slideRunner thread works

The slideRunner thread is instantiated in the startSlideRunner function in the init() method of the applet. This thread executes the 'runwork' method.

  private void startSlideRunner() {
keepRunning = true;
Runnable r = new Runnable() {
public void run() {
try {
runWork();
} catch (Exception x) {
x.printStackTrace();
}
}
};
 
slideRunner = new Thread(r, "SlideShow");
slideRunner.start();
}

Two boolean variables: 'keepRunning' and 'paused' are used to manage the slideRunner thread that executes runWork().

  1. The keepRunning variable is set to 'true' in the init() method. It is set to false only when the user closes the application - thus, keepRunning is true from the time it is set in the init() method until the destroy() method is invoked at the very end of the life cycle of ShowFruits.
  2. The paused variable's value is set to 'false' when the start() method for ShowFruits is initially invoked. The notifyAll() function is used to apprise the slideRunner thread of this value of the paused variable.
   synchronized(this) {
paused = false;
notifyAll();
}
  1. The paused variable's value is set to 'true' when the user selects 'stop' from the applet's pull down menu (i.e., in the stop() method) and the slideRunner() thread is apprised of this using 'notifyAll'. This makes the sideRunner thread wait until the user starts the slide show again by selecting 'Start' from the Applet pull down menu (this causes start() to be invoked; pause is once again set to false, notifyAll() apprises slideRunner of the change; slideRunner exits wait() and resumes execution).

In stop():

   synchronized(this) {
paused = true;
notifyAll();
}

Within runWork():

  while (keepRunning) {
try {
synchronized (this)    {
if (paused)
wait();
}
  1. Note that wait() and notifyAll() are called within a synchronized block on the ShowFruits Object (synchronized(this)).
  2. When pause is set to false, the slideRunner thread suspends execution for 1 second (sleep(1000)). This is the time interval between the slides. Afterwards, the next element in the ArrayList is accessed (or the first slide if the end of the ArrayList has been reached) and used to reset the values of the property labels and the imagePanel. Note that only the imagePanel Component is rendered using repaint; the setText() function resets the value of the JLabels. This 'while' loop executes until the application is closed. Invoking stop() (user clicking on Stop in the menu) causes the slideRunner thread to suspend execution on the ShowFruits object until a notifyAll() is received from an invocation to start() (through a user click on 'Start in the applet menu)
 while (keepRunning) {
.
.
.
Thread.sleep(1000);
 
//Get next element or first element when end is reached
currSlide = (currSlide + 1) % myFruits.size();
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage(this.imagePath  + "\\" +
myFruits.get(currSlide).image);
imagePanel.setImage(image);
fruitName.setText(myFruits.get(currSlide).name);
fruitColor.setText(getColorString(myFruits.get(currSlide).color));
fruitCalories.setText(String.valueOf(myFruits.get(currSlide).calories));
imagePanel.repaint();
.
.
.
}
  1. All methods in ShowFruits print a message containing the name of the current thread. The following output shows the thread that executes each method:
Init Runs on: thread applet-ShowFruits.class
Slide Show Runs On: SlideShow
Start Runs on: thread applet-ShowFruits.class
Paint Runs on: AWT-EventQueue-1
Stop Runs on: thread applet-ShowFruits.class
Start Runs on: thread applet-ShowFruits.class
Destroy Runs on: thread applet-ShowFruits.class