This example illustrates two aspects of persistence: automatic persistence and restoring transient state. The animation "rate" and the boolean "stopped" indicating whether the Juggler is juggling or not are both automatically stored and read. "Thread" and "Image" are explicitly stored and restored.
package sunw.demo.juggler; /** * A simple JavaBean demonstration class that displays an animation * of Duke juggling a couple of coffee beans. The Juggler class * is a good simple example of how to write readObject/writeObject * serialization methods that restore transient state. In this case * the transient state is an array of images and a Thread. */ import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.net.URL; //To make non transient/static fields automatically persistent, simply //define your class to implement java.io.Serializable. //Juggler extends Applet and therefore implements Serializable. public class Juggler extends Applet implements Runnable { private transient Image[] images = new Image[5]; private transient Thread animationThread; private int rate = 125; private transient int loop; private boolean stopped = true; /** * Applet method: start the Juggler applet. */ public synchronized void start() { startJuggling(); } /** * Applet method: stop the Juggler applet. */ public synchronized void stop() { stopJuggling(); } /** * Applet method: Initialize the Juggler applet. */ public void init() { // Load the image resources: images = new Image[5]; for (int i = 0; i < 5; i++) { String imageName = "sunw/demo/juggler/Juggler" + i + ".gif"; images[i] = loadImage(imageName); if (images[i] == null) { System.err.println("Couldn't load image " + imageName); return; } } } /** * This is an internal utility method to load GIF icons. * It takes the name of a resource file associated with the * current object's class-loader and loads a GIF image * from that file. ** @param resourceName A pathname relative to the DocumentBase * of this applet, e.g. "wombat.gif". * @return a GIF image object. May be null if the load failed. */ private java.awt.Image loadImage(String name) { try { URL url = new URL(getCodeBase(), name); Image img = getImage(url); return img; } catch (Exception ex) { return null; } } /** * Draw the current frame. */ public void paint(Graphics g) { int index = (loop%4) + 1; // If the animation is stopped, show the startup image. if (stopped) { index = 0; } if (images == null || index >= images.length) { return; } Image img = images[index]; if (img != null) { g.drawImage(img, 0, 0, this); } } /** * If false, suspend the animation thread. */ public synchronized void setEnabled(boolean x) { super.setEnabled(x); notify(); } /** * Resume the animation thread if we're enabled. * @see #stopJuggling * @see #setEnabled */ public synchronized void startJuggling() { if (images == null) { init(); } if (animationThread == null) { animationThread = new Thread(this); animationThread.start(); } stopped = false; notify(); } /** * Suspend the animation thread if neccessary. * @see #startJuggling * @see #setEnabled */ public synchronized void stopJuggling() { stopped = true; loop = 0; // Draw the stopped frame. Graphics g = getGraphics(); if (g == null || images == null) { return; } Image img = images[0]; if (img != null) { g.drawImage(img, 0, 0, this); } } /** * An event handling method that calls startJuggling. This method * can be used to connect a Button or a MenuItem to the Juggler. * */ public void startJuggling(ActionEvent x) { startJuggling(); } /** * This method can be used to connect a Button or a MenuItem * to the Juggler.stopJuggling method. */ public void stopJuggling(ActionEvent x) { stopJuggling(); } public int getAnimationRate() { return rate; } public void setAnimationRate(int x) { rate = x; } public Dimension getMinimumSize() { return new Dimension(144, 125); } /** * @deprecated provided for backward compatibility with old layout managers. */ public Dimension minimumSize() { return getMinimumSize(); } public Dimension getPreferredSize() { return minimumSize(); } /** * @deprecated provided for backward compatibility with old layout managers. */ public Dimension preferredSize() { return getPreferredSize(); } public void run() { try { while(true) { // First wait until the animation is not stopped. synchronized (this) { while (stopped || !isEnabled()) { wait(); } } loop++; // Now draw the current frame. Graphics g = getGraphics(); Image img = images[(loop % 4) + 1]; if (g != null && img != null) { g.drawImage(img, 0, 0, this); } Thread.sleep(rate); } } catch (InterruptedException e) { } } }
Java, JavaBeans, and JavaSoft are trademarks of Sun Microsystems Inc.
Copyright ©
1996 Sun Microsystems, Inc., 2550 Garcia Ave., Mtn. View, CA 94043-1100 USA.
All rights reserved.