package robotinterface.util;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.image.ImageObserver;
import java.net.URL;
/**
* Present a simple graphic to the user upon launch of the application, to
* provide a faster initial response than is possible with the main window.
*
* <P>Adapted from an <a
* href=http://developer.java.sun.com/developer/qow/archive/24/index.html>item</a>
* on Sun's Java Developer Connection.
*
* <P>This splash screen appears within about 2.5 seconds on a development
* machine. The main screen takes about 6.0 seconds to load, so use of a splash
* screen cuts down the initial display delay by about 55 percent.
*/
public final class SplashScreen extends Frame {
/**
* Construct using an image for the splash screen.
*
* @param aImageId must have content, and is used by
* {@link Class#getResource(java.lang.String)} to retrieve the splash screen
* image.
*/
public SplashScreen(String aImageId) {
/*
* Implementation Note
* Args.checkForContent is not called here, in an attempt to minimize
* class loading.
*/
if (aImageId == null || aImageId.trim().length() == 0) {
throw new IllegalArgumentException("Image Id does not have content.");
}
fImageId = aImageId;
}
/**
* Show the splash screen to the end user.
*
* <P>Once this method returns, the splash screen is realized, which means
* that almost all work on the splash screen should proceed through the
* event dispatch thread. In particular, any call to <tt>dispose</tt> for
* the splash screen must be performed in the event dispatch thread.
*/
public void splash() {
initImageAndTracker();
setSize(fImage.getWidth(NO_OBSERVER), fImage.getHeight(NO_OBSERVER));
center();
fMediaTracker.addImage(fImage, IMAGE_ID);
try {
fMediaTracker.waitForID(IMAGE_ID);
} catch (InterruptedException ex) {
System.out.println("Cannot track image load.");
}
SplashWindow splashWindow = new SplashWindow(this, fImage);
}
// PRIVATE//
private final String fImageId;
private MediaTracker fMediaTracker;
private Image fImage;
private static final ImageObserver NO_OBSERVER = null;
private static final int IMAGE_ID = 0;
private void initImageAndTracker() {
fMediaTracker = new MediaTracker(this);
URL imageURL = SplashScreen.class.getResource(fImageId);
fImage = Toolkit.getDefaultToolkit().getImage(imageURL);
}
/**
* Centers the frame on the screen.
*
* <P>This centering service is more or less in
* {@link hirondelle.stocks.util.ui.UiUtil}; this duplication is justified
* only because the use of {@link hirondelle.stocks.util.ui.UiUtil} would
* entail more class loading, which is not desirable for a splash screen.
*/
private void center() {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle frame = getBounds();
setLocation((screen.width - frame.width) / 2, (screen.height - frame.height) / 2);
}
private class SplashWindow extends Window {
SplashWindow(Frame aParent, Image aImage) {
super(aParent);
fImage = aImage;
setSize(fImage.getWidth(NO_OBSERVER), fImage.getHeight(NO_OBSERVER));
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle window = getBounds();
setLocation((screen.width - window.width) / 2, (screen.height - window.height) / 2);
setVisible(true);
}
@Override
public void paint(Graphics graphics) {
if (fImage != null) {
graphics.drawImage(fImage, 0, 0, this);
}
}
private Image fImage;
}
}