1
2
3
4
5
6
7
8
9
10
11 package splash;
12 import java.awt.Dimension;
13 import java.awt.EventQueue;
14 import java.awt.Frame;
15 import java.awt.Graphics;
16 import java.awt.Image;
17 import java.awt.MediaTracker;
18 import java.awt.Toolkit;
19 import java.awt.Window;
20 import java.awt.event.MouseAdapter;
21 import java.awt.event.MouseEvent;
22 import java.net.URL;
23
24 /***
25 * A Splash window.
26 * <p>
27 * Usage: MyApplication is your application class. Create a Splasher class which
28 * opens the splash window, invokes the main method of your Application class,
29 * and disposes the splash window afterwards.
30 * Please note that we want to keep the Splasher class and the SplashWindow class
31 * as small as possible. The less code and the less classes must be loaded into
32 * the JVM to open the splash screen, the faster it will appear.
33 * <pre>
34 * class Splasher {
35 * public static void main(String[] args) {
36 * SplashWindow.splash(Startup.class.getResource("splash.gif"));
37 * MyApplication.main(args);
38 * SplashWindow.disposeSplash();
39 * }
40 * }
41 * </pre>
42 *
43 * @author Werner Randelshofer
44 * @version 2.1 2005-04-03 Revised.
45 */
46 public class SplashWindow extends Window {
47 /***
48 * The current instance of the splash window.
49 * (Singleton design pattern).
50 */
51 private static SplashWindow instance;
52
53 /***
54 * The splash image which is displayed on the splash window.
55 */
56 private Image image;
57
58 /***
59 * This attribute indicates whether the method
60 * paint(Graphics) has been called at least once since the
61 * construction of this window.<br>
62 * This attribute is used to notify method splash(Image)
63 * that the window has been drawn at least once
64 * by the AWT event dispatcher thread.<br>
65 * This attribute acts like a latch. Once set to true,
66 * it will never be changed back to false again.
67 *
68 * @see #paint
69 * @see #splash
70 */
71 private boolean paintCalled = false;
72
73 /***
74 * Creates a new instance.
75 * @param parent the parent of the window.
76 * @param image the splash image.
77 */
78 private SplashWindow(Frame parent, Image image) {
79 super(parent);
80 this.image = image;
81
82
83 MediaTracker mt = new MediaTracker(this);
84 mt.addImage(image,0);
85 try {
86 mt.waitForID(0);
87 } catch(InterruptedException ie){}
88
89
90 int imgWidth = image.getWidth(this);
91 int imgHeight = image.getHeight(this);
92 setSize(imgWidth, imgHeight);
93 Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
94 setLocation(
95 (screenDim.width - imgWidth) / 2,
96 (screenDim.height - imgHeight) / 2
97 );
98
99
100
101
102 MouseAdapter disposeOnClick = new MouseAdapter() {
103 public void mouseClicked(MouseEvent evt) {
104
105
106
107
108
109 synchronized(SplashWindow.this) {
110 SplashWindow.this.paintCalled = true;
111 SplashWindow.this.notifyAll();
112 }
113 dispose();
114 }
115 };
116 addMouseListener(disposeOnClick);
117 }
118
119 /***
120 * Updates the display area of the window.
121 */
122 public void update(Graphics g) {
123
124
125
126
127 paint(g);
128 }
129 /***
130 * Paints the image on the window.
131 */
132 public void paint(Graphics g) {
133 g.drawImage(image, 0, 0, this);
134
135
136
137
138
139 if (! paintCalled) {
140 paintCalled = true;
141 synchronized (this) { notifyAll(); }
142 }
143 }
144
145 /***
146 * Open's a splash window using the specified image.
147 * @param image The splash image.
148 */
149 public static void splash(Image image) {
150 if (instance == null && image != null) {
151 Frame f = new Frame();
152
153
154 instance = new SplashWindow(f, image);
155
156
157 instance.show();
158
159
160
161
162
163
164 if (! EventQueue.isDispatchThread()
165 && Runtime.getRuntime().availableProcessors() == 1) {
166 synchronized (instance) {
167 while (! instance.paintCalled) {
168 try { instance.wait(); } catch (InterruptedException e) {}
169 }
170 }
171 }
172 }
173 }
174 /***
175 * Open's a splash window using the specified image.
176 * @param imageURL The url of the splash image.
177 */
178 public static void splash(URL imageURL) {
179 if (imageURL != null) {
180 splash(Toolkit.getDefaultToolkit().createImage(imageURL));
181 }
182 }
183
184 /***
185 * Closes the splash window.
186 */
187 public static void disposeSplash() {
188 if (instance != null) {
189 instance.getOwner().dispose();
190 instance = null;
191 }
192 }
193
194 /***
195 * Invokes the main method of the provided class name.
196 * @param args the command line arguments
197 */
198 public static void invokeMain(String className, String[] args) {
199 try {
200 Class.forName(className)
201 .getMethod("main", new Class[] {String[].class})
202 .invoke(null, new Object[] {args});
203 } catch (Exception e) {
204 InternalError error = new InternalError("Failed to invoke main method");
205 error.initCause(e);
206 throw error;
207 }
208 }
209 }