import java.awt.*; import java.applet.*; import java.net.*; public class SlideShow extends Applet { private Image[] images; private String[] text; private Label captions; private volatile int curFrame; private Thread timerThread; private volatile boolean noStopRequested; private boolean paused; private final Object pauseLock = new Object(); private void printThreadName(String prefix) { String name = Thread.currentThread().getName(); System.out.println(prefix + name); } public void init() { images = new Image[3]; text = new String[3]; captions = new Label(); setLayout(new BorderLayout()); add(BorderLayout.SOUTH, captions); Label name = new Label("by Claude Monet"); name.setAlignment(Label.CENTER); add(BorderLayout.EAST, name); URL fig = null; try { fig = new URL("http://developer.java.sun.com:8080/" + "developer/technicalArticles/Threads/applet/"); } catch (java.net.MalformedURLException ex) { System.out.println("Bad URL"); return; } images[0] = getImage(fig, "bordighera.jpg"); images[1] = getImage(fig, "etretat.jpg"); images[2] = getImage(fig, "leyden.jpg"); text[0] = "Garden in Bordighera"; text[1] = "Rock Arch West of Etretat"; text[2] = "Bulbfield and Windmill near Leyden"; printThreadName("init is "); startThread(); } private void startThread() { paused = true; noStopRequested = true; // Use this inner class to hide the public run method Runnable r = new Runnable() { public void run() { runWork(); } }; timerThread = new Thread(r, "Timer"); timerThread.start(); printThreadName("startThread is "); } private void stopThread() { noStopRequested = false; timerThread.interrupt(); printThreadName("stopThread is "); } private void runWork() { // note that this is private printThreadName("run is "); curFrame = 0; try { while ( noStopRequested ) { waitWhilePaused(); curFrame = ( curFrame + 1 ) % images.length; repaint(); Thread.sleep(3000); } } catch ( InterruptedException x ) { // reassert interrupt Thread.currentThread().interrupt(); System.out.println("interrupt and return from run"); } } private void setPaused(boolean newPauseState) { synchronized ( pauseLock ) { if ( paused != newPauseState ) { paused = newPauseState; pauseLock.notifyAll(); } } } private void waitWhilePaused() throws InterruptedException { synchronized ( pauseLock ) { while ( paused ) { pauseLock.wait(); } } } public void paint(Graphics g) { update(g); printThreadName("paint is "); } public void update(Graphics g) { g.drawImage(images[curFrame], 0, 0, this); captions.setText(text[curFrame]); printThreadName("update is "); } public void start() { setPaused(false); printThreadName("start is "); } public void stop() { setPaused(true); printThreadName("stop is "); } public void destroy() { stopThread(); for (int i = 0; i < images.length; i++) { images[i].flush(); images[i] = null; text[i] = null; } images = null; text = null; printThreadName("destroy is "); } }