source: src/main/java/weka/gui/SplashWindow.java @ 9

Last change on this file since 9 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 7.8 KB
RevLine 
[4]1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * @(#)SplashWindow.java  2.2  2005-04-03
19 *
20 * Copyright (c) 2003-2005 Werner Randelshofer
21 * Staldenmattweg 2, Immensee, CH-6405, Switzerland.
22 * All rights reserved.
23 *
24 * This software is in the public domain.
25 *
26 */
27
28package weka.gui;
29
30import java.awt.Dimension;
31import java.awt.EventQueue;
32import java.awt.Frame;
33import java.awt.Graphics;
34import java.awt.Image;
35import java.awt.MediaTracker;
36import java.awt.Toolkit;
37import java.awt.Window;
38import java.awt.event.MouseAdapter;
39import java.awt.event.MouseEvent;
40import java.net.URL;
41
42/**
43 * A Splash window.
44 *  <p>
45 * Usage: MyApplication is your application class. Create a Splasher class which
46 * opens the splash window, invokes the main method of your Application class,
47 * and disposes the splash window afterwards.
48 * Please note that we want to keep the Splasher class and the SplashWindow class
49 * as small as possible. The less code and the less classes must be loaded into
50 * the JVM to open the splash screen, the faster it will appear.
51 * <pre>
52 * class Splasher {
53 *    public static void main(String[] args) {
54 *         SplashWindow.splash(Startup.class.getResource("splash.gif"));
55 *         MyApplication.main(args);
56 *         SplashWindow.disposeSplash();
57 *    }
58 * }
59 * </pre>
60 *
61 * @author  Werner Randelshofer
62 * @author  Mark Hall
63 * @version $Revision: 1.3 $
64 */
65public class SplashWindow
66  extends Window {
67
68  /** for serialization */
69  private static final long serialVersionUID = -2685134277041307795L;
70 
71  /**
72   * The current instance of the splash window.
73   * (Singleton design pattern).
74   */
75  private static SplashWindow m_instance;
76   
77  /**
78   * The splash image which is displayed on the splash window.
79   */
80  private Image image;
81   
82  /**
83   * This attribute indicates whether the method
84   * paint(Graphics) has been called at least once since the
85   * construction of this window.<br>
86   * This attribute is used to notify method splash(Image)
87   * that the window has been drawn at least once
88   * by the AWT event dispatcher thread.<br>
89   * This attribute acts like a latch. Once set to true,
90   * it will never be changed back to false again.
91   *
92   * @see #paint
93   * @see #splash
94   */
95  private boolean paintCalled = false;
96   
97  /**
98   * Creates a new instance.
99   * @param parent the parent of the window.
100   * @param image the splash image.
101   */
102  private SplashWindow(Frame parent, Image image) {
103    super(parent);
104    this.image = image;
105
106    // Load the image
107    MediaTracker mt = new MediaTracker(this);
108    mt.addImage(image,0);
109    try {
110      mt.waitForID(0);
111    } catch(InterruptedException ie){
112    }
113       
114    // Center the window on the screen
115    int imgWidth = image.getWidth(this);
116    int imgHeight = image.getHeight(this);
117    setSize(imgWidth, imgHeight);
118    Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
119    setLocation(
120                (screenDim.width - imgWidth) / 2,
121                (screenDim.height - imgHeight) / 2
122                );
123
124       
125    // Users shall be able to close the splash window by
126    // clicking on its display area. This mouse listener
127    // listens for mouse clicks and disposes the splash window.
128    MouseAdapter disposeOnClick = new MouseAdapter() {
129        public void mouseClicked(MouseEvent evt) {
130          // Note: To avoid that method splash hangs, we
131          // must set paintCalled to true and call notifyAll.
132          // This is necessary because the mouse click may
133          // occur before the contents of the window
134          // has been painted.
135          synchronized(SplashWindow.this) {
136            SplashWindow.this.paintCalled = true;
137            SplashWindow.this.notifyAll();
138          }
139          dispose();
140        }
141      };
142    addMouseListener(disposeOnClick);
143  }
144   
145  /**
146   * Updates the display area of the window.
147   */
148  public void update(Graphics g) {
149    // Note: Since the paint method is going to draw an
150    // image that covers the complete area of the component we
151    // do not fill the component with its background color
152    // here. This avoids flickering.
153
154    paint(g);
155  } 
156
157  /**
158   * Paints the image on the window.
159   */
160  public void paint(Graphics g) {
161    g.drawImage(image, 0, 0, this);
162    // Notify method splash that the window
163    // has been painted.
164    // Note: To improve performance we do not enter
165    // the synchronized block unless we have to.
166    if (! paintCalled) {
167      paintCalled = true;
168      synchronized (this) { notifyAll(); }
169    }
170  }
171   
172  /**
173   * Open's a splash window using the specified image.
174   * @param image The splash image.
175   */
176  public static void splash(Image image) {
177    if (m_instance == null && image != null) {
178      Frame f = new Frame();
179           
180      // Create the splash image
181      m_instance = new SplashWindow(f, image);
182           
183      // Show the window.
184      m_instance.show();
185           
186      // Note: To make sure the user gets a chance to see the
187      // splash window we wait until its paint method has been
188      // called at least once by the AWT event dispatcher thread.
189      // If more than one processor is available, we don't wait,
190      // and maximize CPU throughput instead.
191      if (!EventQueue.isDispatchThread() 
192            &&  Runtime.getRuntime().availableProcessors() == 1) {
193        synchronized (m_instance) {
194          while (! m_instance.paintCalled) {
195            try { m_instance.wait(); } catch (InterruptedException e) {}
196          }
197        }
198      }
199    }
200  }
201
202  /**
203   * Open's a splash window using the specified image.
204   * @param imageURL The url of the splash image.
205   */
206  public static void splash(URL imageURL) {
207    if (imageURL != null) {
208      splash(Toolkit.getDefaultToolkit().createImage(imageURL));
209    }
210  }
211   
212  /**
213   * Closes the splash window.
214   */
215  public static void disposeSplash() {
216    if (m_instance != null) {
217      m_instance.getOwner().dispose();
218      m_instance = null;
219    }
220  }
221   
222  /**
223   * Invokes the named method of the provided class name.
224   * @param className the name of the class
225   * @param methodName the name of the method to invoke
226   * @param args the command line arguments
227   */
228  public static void invokeMethod(String className, String methodName, 
229                                  String [] args) {
230    try {
231      Class.forName(className)
232        .getMethod(methodName, new Class[] {String[].class})
233        .invoke(null, new Object[] {args});
234    } catch (Exception e) {
235      InternalError error = new InternalError("Failed to invoke method: "
236                                              +methodName);
237      error.initCause(e);
238      throw error;
239    }
240  }
241
242  /**
243   * Invokes the main method of the provided class name.
244   * @param className the name of the class
245   * @param args the command line arguments
246   */
247  public static void invokeMain(String className, String[] args) {
248    try {
249      Class.forName(className)
250        .getMethod("main", new Class[] {String[].class})
251        .invoke(null, new Object[] {args});
252    } catch (Exception e) {
253      InternalError error = new InternalError("Failed to invoke main method");
254      error.initCause(e);
255      throw error;
256    }
257  }
258}
Note: See TracBrowser for help on using the repository browser.