package toy; import java.applet.*; import java.awt.*; import java.awt.event.*; import toy.image.*; /** * ToySplash is a very special component that it does practically everything for * the splash window or splash applet. It just needs to be placed in the * correct window. * * @author Brian Tsang * @version 7.0 */ public class ToySplash extends Component implements Runnable, WindowListener { /** * The version and build number of Visual X-TOY (for debugging purposes. */ private static final String BUILD_STRING = "7.0.32"; /** * The date when this program was last modified (for debugging purposes. */ private static final String DATE_STRING = "9/13/01"; /** * The width of the splash image. */ public static final int WIDTH = 341; /** * The height of the splash image. */ public static final int HEIGHT = 256; /** * The ToyFrame that was launched. * @serial */ private ToyFrame frame; /** * The ToyImageManager that will load the images. This is static because * the browser might not launch different applets in different VMs. Thus * we save time by having the images already loaded. */ private static ToyImageManager imageManager; /** * The ToyParameterManager that will load the starting preferences and * example programs. This is static because the browser might not launch * different applets in different VMs. Thus we save time by having the * parameters and example programs already loaded. */ private static ToyParameterManager parameterManager; /** * The current brightness of the "Click To Start" text. Ranges from 0 to * 255. * @serial */ private int colorCtr; /** * The splash applet (if this is an applet). * @serial */ private Applet parentApplet; /** * The splash window (if this is an application). * @serial */ private Window parentWindow; /** * The buffered screen. * @serial */ private Image offscreenImage; /** * The graphics object attached to the buffered screen. * @serial */ private Graphics offscreen; /** * The animation thread. * @serial */ private Thread runner; /** * Constructs a new ToySplash object attached to a window. * @param newParentWindow the window that this ToySplash will be attached * to. */ public ToySplash(Window newParentWindow) { System.out.println("Visual X-TOY"); System.out.println("Originally Coded by Brian Tsang"); System.out.println("Build " + BUILD_STRING + " (" + DATE_STRING + ")"); parentWindow = newParentWindow; setBackground(new Color(64, 80, 96)); //get the parameters and example programs if (parameterManager == null) parameterManager = new ToyParameterManager(); //get the images if (imageManager == null) imageManager = new ToyImageManager(parentWindow); //Our animation thread runner = new Thread(this); runner.start(); enableEvents(AWTEvent.MOUSE_EVENT_MASK); } /** * Constructs a new ToySplash object attached to a applet. * @param newParentApplet the applet that this ToySpash will be attached to. */ public ToySplash(Applet newParentApplet) { System.out.println("Visual X-TOY"); System.out.println("Originally Coded by Brian Tsang"); System.out.println("Build " + BUILD_STRING + " (" + DATE_STRING + ")"); parentApplet = newParentApplet; setBackground(new Color(64, 80, 96)); //get the parameters and example programs if (parameterManager == null) parameterManager = new ToyParameterManager(parentApplet); //get the images, but don't bother if we already have an imageManger //it's static if (imageManager == null) imageManager = new ToyImageManager(parentApplet); //Our animation thread runner = new Thread(this); runner.start(); enableEvents(AWTEvent.MOUSE_EVENT_MASK); } /** * Make sure the thread stops while we */ public void finalize() { //toss out the thread runner = null; } /** * Implement the Runnable interface to animate the splash screen. */ public void run() { Thread thisThread = Thread.currentThread(); colorCtr = 255; //"Click to Start" should start at black int direction = -7; //and should be getting brighter in steps of 7 boolean cursorChanged = false; repaint(); while (runner == thisThread && frame == null) { //Ccall the repaint function repaint(); //increment the color colorCtr += direction; //don't let the color change if we're loading if (!(imageManager.isReady() && parameterManager.isReady())) colorCtr = 255; //Reverse the direction if the color reaches one of the RGB bounds if (colorCtr <= 10) direction = 7; if (colorCtr >= 245) direction = -7; //when our images are ready, we can set the cursor to the hand //(or launch the frame if we're an application) if (!cursorChanged && imageManager.isReady() && parameterManager.isReady()) { if (parentWindow == null) { cursorChanged = true; setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } else launchAttempt(); } try { //pause for a number of milliseconds if (imageManager.isReady() && parameterManager.isReady()) //pause longer if the color is closer to white Thread.sleep(50 + colorCtr * colorCtr / 500); else //pause for only 100 milliseconds Thread.sleep(100); } catch (Exception e) { //whatever } } runner = null; colorCtr = 255; repaint(); } /** * Repaint has been simplified to speed the animation process. */ public void repaint() { paint(getGraphics()); } /** * Update has been simplified to speed the animation process. * @param g the graphics object on which to paint. */ public void update(Graphics g) { paint(g); } /** * Paint the logo and text onto the buffer and then to g * @param g the graphics object on which to paint. */ public void paint(Graphics g) { if (g == null) return; if (offscreen == null) { //initialize the g buffer offscreenImage = createImage(getBounds().width, getBounds().height); if (offscreenImage == null) return; offscreen = offscreenImage.getGraphics(); offscreen.setFont(new Font("SansSerif", Font.PLAIN, 12)); } offscreen.clearRect(0, 0, getBounds().width, getBounds().height); //put the logo on the buffer offscreen.drawImage( imageManager.getImage(ToyImageManager.SPLASH_BACKGROUND), 0, 0, this ); //put the "Click to launch" on the buffer (we set the color back in start() offscreen.setColor(new Color(colorCtr, colorCtr, colorCtr)); if (imageManager.isReady() && parameterManager.isReady()) { if (frame != null) offscreen.drawString("Frame Launched", 244, 251); else { if (parentWindow == null) offscreen.drawString("Click to Launch", 248, 251); else offscreen.drawString("Launching...", 248, 251); } } else offscreen.drawString( "Loading... " + imageManager.getPercentDone() + "%", 248, 251 ); //put the buffer on the g g.drawImage(offscreenImage, 0, 0, this); } /** * Attempt to launch a frame if it does not already exist. If a frame * already exists, just bring it to the front. */ public void launchAttempt() { if (imageManager.isReady() && parameterManager.isReady()) { //If there's already a frame, just bring it to the front if (frame != null && frame.isShowing()) { frame.requestFocus(); frame.toFront(); } else { //If not, make a new one frame = new ToyFrame( parentApplet, parameterManager, imageManager ); frame.addWindowListener(this); frame.show(); if (parentWindow != null) parentWindow.hide(); } } } /** * Listen to Mouse Events for the MouseEvent.MOUSE_CLICKED event, attempt * to launch if that event is processed. * @see #launchAttempt() */ public void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_CLICKED) launchAttempt(); } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowOpened(WindowEvent e) { } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. If the ToyFrame is closed, then restart the animation if this is * an applet, and if this is an application, terminate this process. */ public void windowClosed(WindowEvent e) { if (parentWindow == null) { frame = null; if (runner == null) { runner = new Thread(this); runner.start(); } } else System.exit(0); } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowClosing(WindowEvent e) { } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowActivated(WindowEvent e) { } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowDeactivated(WindowEvent e) { } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowIconified(WindowEvent e) { } /** * Implement the WindowListener interface to be notified when the ToyFrame * closes. This particualr function does nothing. * @see #windowClosed(java.awt.event.WindowEvent) */ public void windowDeiconified(WindowEvent e) { } }