net.sac.ui
Class SplashScreen

java.lang.Object
  extended by net.sac.ui.SplashScreen
All Implemented Interfaces:
java.awt.image.ImageObserver

public class SplashScreen
extends java.lang.Object
implements java.awt.image.ImageObserver

SplashScreen is a general-purpose splash screen for application start-up. Usage is straightforward: simply construct a SplashScreen at the start of main() and call its splash() method. Proceed with start-up as normal. Use showStatus(String) for reporting progress during start-up. Finally, at the end of main() call SplashScreen's dispose() method. By default, the splash loads image splash.gif but you can change this if necessary.

Version:
1.5
Author:
Roy Ratcliffe

Field Summary
 
Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
 
Constructor Summary
SplashScreen()
          Constructs SplashScreen using filename "splash.gif" for the image unless you change the default using setImage or call splash with an argument specifying a different image.
SplashScreen(java.lang.String filename)
          Constructs SplashScreen using a given filename for the splash image.
SplashScreen(java.net.URL url)
          Constructs SplashScreen using a given URL for the splash image.
 
Method Summary
 void delayForSplash()
          Optimise splash latency by delaying the calling thread according to number of processors available.
 void dispose()
          Closes the splash screen if open, or abandons splash screen if not already open.
 boolean imageUpdate(java.awt.Image img, int infoflags, int x, int y, int width, int height)
          Runs during image loading.
static SplashScreen instance()
          Ensures the class has only one instance and gives a global point of access to it.
 void setImage(java.lang.String filename)
          Uses the given filename for the splash image.
 void setImage(java.net.URL url)
          Uses the given URL for the splash image.
 void showStatus(java.lang.String s)
          Changes the status message just below the image.
 void splash()
          Starts the asynchronous splash screen using the previously specified image, or using filename "splash.gif" by default if no image yet specified.
 void splash(java.awt.Image img)
          Splash the screen! Or, in other words, make a splash! Actually, this method merely starts the process of splashing.
 void splash(java.lang.String filename)
          Starts the asynchronous splash screen using the given filename for the image.
 void splash(java.net.URL url)
          Starts the asynchronous splash screen using the given URL for the image.
 void splashFor(int ms)
          Splashes the screen for at least the given number of milliseconds if, and only if, the splash screen has already loaded.
 void waitForSplash()
          Waits for the splash screen to load, returns when the splash starts.
 void waitForSplash(long ms)
          Waits for the splash screen to load for a limited amount of time.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SplashScreen

public SplashScreen(java.lang.String filename)
Constructs SplashScreen using a given filename for the splash image.

Parameters:
filename - name of an image file

SplashScreen

public SplashScreen(java.net.URL url)
Constructs SplashScreen using a given URL for the splash image.

Parameters:
url - the URL of an image

SplashScreen

public SplashScreen()
Constructs SplashScreen using filename "splash.gif" for the image unless you change the default using setImage or call splash with an argument specifying a different image.

Method Detail

setImage

public void setImage(java.lang.String filename)
Uses the given filename for the splash image. This method calls Toolkit.getImage which resolves multiple requests for the same filename to the same Image, unlike createImage which creates a non-shared instance of Image. In other words, getImage caches Images, createImage does not. Use splash(createImage(... if you want Image privacy.

Parameters:
filename - name of an image file

setImage

public void setImage(java.net.URL url)
Uses the given URL for the splash image.

Parameters:
url - the URL of an image

splash

public void splash(java.lang.String filename)
Starts the asynchronous splash screen using the given filename for the image.

Parameters:
filename - name of an image file

splash

public void splash(java.net.URL url)
Starts the asynchronous splash screen using the given URL for the image.

Parameters:
url - the URL of an image

splash

public void splash()
Starts the asynchronous splash screen using the previously specified image, or using filename "splash.gif" by default if no image yet specified.


splash

public void splash(java.awt.Image img)
Splash the screen! Or, in other words, make a splash! Actually, this method merely starts the process of splashing. The splash screen will appear sometime later when the splash image is ready for display. Note that this splash screen implementation uses fully asynchronous image loading. The splash() method itself returns to the caller as soon as possible. The screen appears later as soon as image loading completes.

Parameters:
img - the image used for splashing

imageUpdate

public boolean imageUpdate(java.awt.Image img,
                           int infoflags,
                           int x,
                           int y,
                           int width,
                           int height)
Runs during image loading. Informs this ImageObserver about progress. This method does not run in the main thread, i.e. the thread which calls splash() and dispose(). That is why methods splashScreen() and dispose() are synchronized.

Specified by:
imageUpdate in interface java.awt.image.ImageObserver

showStatus

public void showStatus(java.lang.String s)
Changes the status message just below the image. Use it to display start-up progress.


waitForSplash

public void waitForSplash()
Waits for the splash screen to load, returns when the splash starts. The wait is indefinite if necessary. The operation returns immediately if the splash image has already loaded.

Please note following discussion taken from design documentation by R.R.

As a guide, invoke this method at the end of start-up, not the beginning. Waiting for the image to load does not make the image load faster, necessarily. Image loading is an `input bound' process, reading from filesystem or network. Remaining start-up steps are typically `compute bound' and likely compute resource is available for consumption. Most likely, start-up mixes input and compute resource demands, and possibly even output.

This guideline applies to uniprocessor as well as multiprocessor platforms. Waiting only wastes any available compute cycles. If you need to delay unnecessarily, do this at the end when there is nothing left to do. Even so, this practice can be viewed as user interface cruft! Please use with care.


waitForSplash

public void waitForSplash(long ms)
Waits for the splash screen to load for a limited amount of time. Method returns when the splash has loaded, or when the given time limit expires.

Parameters:
ms - milliseconds to wait for

delayForSplash

public void delayForSplash()
Optimise splash latency by delaying the calling thread according to number of processors available. Multiprocessor platforms successfully load the splash image in parallel with low overhead. Uniprocessors struggle however! This method offers a compromise. It delays indefinitely with one processor, same as waitForSplash(); however, it returns immediately with four or more processors thereby maximising parallel execution; or waits for 500 milliseconds at most with dual processors. Call delayForSplash() in place of waitForSplash().


splashFor

public void splashFor(int ms)
Splashes the screen for at least the given number of milliseconds if, and only if, the splash screen has already loaded. If not already splashed, the method returns immediately. Invoke this method before disposing if you want to force a minimum splash period.

Why is this method synchronized? In order to avoid a race condition. It accesses the splashTime attribute which updates in another thread.

Parameters:
ms - milliseconds of minimum splash

dispose

public void dispose()
Closes the splash screen if open, or abandons splash screen if not already open. Relatively long image loading delays the opening. Call this method at the end of program start-up, i.e. typically at the end of main().

Implementation note. If you dispose too fast, this method could coincide with splashScreen(). We cannot now preempt the other thread. It needs synchronisation. This situation and its requirement proves inevitable when two threads access the same thing. For this reason, methods dispose() and splashScreen() share the synchronized attribute.


instance

public static SplashScreen instance()
Ensures the class has only one instance and gives a global point of access to it. The Singleton pattern avoids using global variables. Instead, the class itself references the single instance using a class-scoped variable, static in Java terms.

The implementation actually mixes singleton and non-singleton patterns. (Tempting to call it Multiton but that refers to a variation of Singleton where the instance has many multiplicity instead of unity.) Correctly applying the Singleton pattern requires closing access to constructor methods. However, SplashScreen retains public constructors, so compromises the pattern. You can follow Singleton usage or not at your own discretion.

Returns:
singleton SplashScreen instance