/* GeoGebra - Dynamic Mathematics for Everyone http://www.geogebra.org This file is part of GeoGebra. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. */ package org.geogebra.desktop; /* * Copyright (c) 1999-2003 Werner Randelshofer * Staldenmattweg 2, Immensee, CH-6405, Switzerland * All rights reserved. * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software is hereby granted without fee, * provided this copyright notice is retained on all copies. */ import java.awt.Color; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Window; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * Splash Window to show an image during startup of an application. * <p> * * Usage: * * <pre> * // open the splash window * Frame splashOwner = SplashWindow.splash(anImage); * * // start the application * // ... * * // dispose the splash window by disposing the frame that owns the window. * splashOwner.dispose(); * </pre> * * <p> * To use the splash window as an about dialog write this: * * <pre> * new SplashWindow(this, * getToolkit() * .createImage(getClass().getResource(GeoGebra.SPLASH_STRING))) * .show(); * </pre> * * The splash window disposes itself when the user clicks on it. * * @author Werner Randelshofer, Staldenmattweg 2, Immensee, CH-6405, * Switzerland. * @version 1.3 2003-06-01 Revised. */ public class SplashWindow extends Window { /** * */ private static final long serialVersionUID = 1L; private Image splashImage; /** * This attribute indicates whether the method paint(Graphics) has been * called at least once since the construction of this window.<br> * This attribute is used to notify method splash(Image) that the window has * been drawn at least once by the AWT event dispatcher thread.<br> * This attribute acts like a latch. Once set to true, it will never be * changed back to false again. * * @see #paint * @see #splash */ private boolean paintCalled = false; /** * Constructs a splash window and centers it on the screen. The user can * click on the window to dispose it. * * @param owner * The frame owning the splash window. * @param splashImage * The splashImage to be displayed. * @param canDispose * If a mouse click should dispose the window */ public SplashWindow(Frame owner, Image splashImage, boolean canDispose) { super(owner); this.splashImage = splashImage; // Load the image MediaTracker mt = new MediaTracker(this); mt.addImage(splashImage, 0); try { mt.waitForID(0); } catch (InterruptedException ie) { } // Center the window on the screen. int imgWidth = splashImage.getWidth(this); int imgHeight = splashImage.getHeight(this); setSize(imgWidth, imgHeight); setLocationRelativeTo(null); if (canDispose) { // Users shall be able to close the splash window by // clicking on its display area. This mouse listener // listens for mouse clicks and disposes the splash window. MouseAdapter disposeOnClick = new MouseAdapter() { @Override public void mouseClicked(MouseEvent evt) { // Note: To avoid that method splash hangs, we // must set paintCalled to true and call notifyAll. // This is necessary because the mouse click may // occur before the contents of the window // has been painted. synchronized (SplashWindow.this) { paintCalled = true; notifyAll(); } setVisible(false); } }; addMouseListener(disposeOnClick); } } /** * Updates the display area of the window. */ @Override public void update(Graphics g) { // Note: Since the paint method is going to draw an // image that covers the complete area of the component we // do not fill the component with its background color // here. This avoids flickering. g.setColor(getForeground()); paint(g); } /** * Paints the image on the window. */ @Override public void paint(Graphics g) { g.drawImage(splashImage, 0, 0, this); // Markus Hohenwarter (14. 4. 2006): add border to splashImage g.setColor(Color.darkGray); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); // Notify method splash that the window // has been painted. // Note: To improve performance we do not enter // the synchronized block unless we have to. if (!paintCalled) { paintCalled = true; synchronized (this) { notifyAll(); } } } /** * Constructs and displays a SplashWindow. * <p> * This method is useful for startup splashs. Dispose the return frame to * get rid of the splash window. * <p> * * @param splashImage * The image to be displayed. * @return Returns the frame that owns the SplashWindow. */ public static Frame splash(Image splashImage) { Frame f = new Frame(); SplashWindow w = new SplashWindow(f, splashImage, false); // Show the window. w.toFront(); w.setVisible(true); // Note: To make sure the user gets a chance to see the // splash window we wait until its paint method has been // called at least by the AWT event dispatcher thread. if (!EventQueue.isDispatchThread()) { synchronized (w) { while (!w.paintCalled) { try { w.wait(); } catch (InterruptedException e) { } } } } return f; } }