Package net.xoetrope.swing.splash

Source Code of net.xoetrope.swing.splash.XSplashWindow

package net.xoetrope.swing.splash;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.lang.reflect.Method;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import net.xoetrope.xui.build.BuildProperties;


/*
* @(#)XSplashWindow.java  2.2.1  2006-05-27
*
* Copyright (c) 2003-2006 Werner Randelshofer
* Staldenmattweg 2, Immensee, CH-6405, Switzerland.
* All rights reserved.
*
* @see http://www.randelshofer.ch/oop/javasplash/javasplash.html
* This software is in the public domain.
*/


/**
* A Splash window.
<p>
* Usage: MyApplication is your application class. Create a Splasher class which
* opens the splash window, invokes the main method of your Application class,
* and disposes the splash window afterwards.
* Please note that we want to keep the Splasher class and the XSplashWindow class
* as small as possible. The less code and the less classes must be loaded into
* the JVM to open the splash screen, the faster it will appear.
* <pre>
* class Splasher {
*    public static void main(String[] args) {
*         XSplashWindow.splash(Startup.class.getResource("splash.gif"));
*         MyApplication.main(args);
*         XSplashWindow.disposeSplash();
*    }
* }
* </pre>
*
*
* @author Werner Randelshofer
* @version 2.2.1 2006-05-27 Abort when splash image can not be loaded.
* @see http://www.randelshofer.ch/oop/javasplash/javasplash.html
*/
public class XSplashWindow extends Window
{
  /**
   * The current instance of the splash window.
   * (Singleton design pattern).
   */
  private static XSplashWindow instance;

  /**
   * The splash image which is displayed on the splash window.
   */
  private Image image;

  /**
   * 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;

  private int x, y, imgWidth, imgHeight;
 
  private BufferedImage screenShot;
 
  /**
   * Creates a new instance.
   * @param parent the parent of the window.
   * @param image the splash image.
   */
  private XSplashWindow(Frame parent, Image image)
  {
      super( parent );
      this.image = image;
  //    setAlwaysOnTop();
     
      // Load the image
      MediaTracker mt = new MediaTracker(this);
      mt.addImage(image,0);
      try {
          mt.waitForID(0);
      } catch(InterruptedException ie){}

      // Abort on failure
      if (mt.isErrorID(0)) {
          setSize(0,0);
          System.err.println("Warning: SplashWindow couldn't load splash image.");
          synchronized(this) {
              paintCalled = true;
              notifyAll();
          }
          return;
      }

      // Center the window on the screen
      Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
      imgWidth = image.getWidth(this);
      imgHeight = image.getHeight(this);
      x = (screenDim.width - imgWidth) / 2;
      y = (screenDim.height - imgHeight) / 2;
      captureScreenShot();
      setSize(imgWidth, imgHeight);
      setLocation( x, y );

      // 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() {
          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(XSplashWindow.this) {
                  XSplashWindow.this.paintCalled = true;
                  XSplashWindow.this.notifyAll();
              }
              dispose();
          }
      };
      addMouseListener(disposeOnClick);
     
      addWindowListener( new WindowAdapter()
      {
        public void windowDeactivated( WindowEvent we )
        {
          SwingUtilities.invokeLater( new Runnable() {
            public void run()
            {
              captureScreenShot();
              XSplashWindow.this.toFront();
            }
          });
        }
      });
  }

  public Graphics getGraphics()
  {
    return super.getGraphics();
  }
 
  /**
   * Updates the display area of the window.
   */
  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.
    paint(g);
  }

  /**
   * Paints the image on the window.
   */
  public void paint(Graphics g)
  {
    if ( screenShot != null )
      g.drawImage(screenShot, 0, 0, this);
   
    g.drawImage(image, 0, 0, this);

    // 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(); }
    }
  }

  /**
   * Open's a splash window using the specified image.
   * @param image The splash image.
   */
  public static void splash(Image image)
  {
      if (instance == null && image != null) {
          Frame f = new Frame();

          // Create the splash image
          instance = new XSplashWindow(f, image);

          // Show the window.
          instance.show();

          // 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 once by the AWT event dispatcher thread.
          // If more than one processor is available, we don't wait,
          // and maximize CPU throughput instead.
          if ( !EventQueue.isDispatchThread()
          && Runtime.getRuntime().availableProcessors() == 1 ) {
              synchronized( instance ) {
                  while ( !instance.paintCalled ) {
                      try { instance.wait(); } catch (InterruptedException e) {}
                  }
              }
          }
      }
  }

  /**
   * Open's a splash window using the specified image.
   * @param imageURL The url of the splash image.
   */
  public static void splash(URL imageURL)
  {
      if (imageURL != null) {
          splash(Toolkit.getDefaultToolkit().createImage(imageURL));
      }
  }

  /**
   * Closes the splash window.
   * @param delay the dealy in milliseconds
   */
  public static void disposeSplash(int delay)
  {
      if (instance != null) {
        instance.repaint();
        ActionListener taskPerformer = new ActionListener()
        {
          public void actionPerformed( ActionEvent evt )
          {
            instance.getOwner().dispose();
            instance = null;
          }
        };
        Timer timer = new Timer( delay, taskPerformer );
        timer.setRepeats( false );
        timer.start();
      }
  }

  /**
   * Invokes the main method of the provided class name.
   * @param args the command line arguments
   */
  public static void invokeMain(String className, String[] args)
  {
      try {
        Class.forName( className.trim())
          .getMethod("main", new Class[] {String[].class})
          .invoke(null, new Object[] {args});
      }
      catch (Exception e) {
        if ( BuildProperties.DEBUG )
          e.printStackTrace();
        InternalError error = new InternalError("Failed to invoke main method");
        error.initCause(e);
        throw error;
      }
  }

  /**
   * Make sure the splash screen is always on top
   */
  public void setAlwaysOnTop()
  {
    try {
      // Do not invoke directly as this method is only available on 1.5+
      Class params[] = new Class[ 1 ];
      params[ 0 ] = boolean.class;

      Object target = this;
      Method method = target.getClass().getMethod( "setAlwaysOnTop", params );
      if ( method != null ) {
        Object args[] = new Object[ 1 ];
        args[ 0 ] = Boolean.TRUE;

        if ( method != null )
          method.invoke( target, args );
      }
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG ) {
        Throwable t = ex.getCause();
        if ( t != null )
          t.printStackTrace();
        else 
          ex.printStackTrace();
      }
    }
  }
  
  private void captureScreenShot()
  {
    try {
      setSize( 0,0 );
      Robot robot = new Robot();
      Rectangle rect = new Rectangle( x, y, imgWidth, imgHeight );
      screenShot = robot.createScreenCapture( rect );
      setSize( imgWidth, imgHeight );
      repaint();
    }
    catch (java.awt.AWTException ex)
    {
      ex.printStackTrace();
    }
  }

/**
   * Shows the splash screen, launches the application and then disposes
   * the splash screen.
   * @param args the command line arguments
   */
  public static void main( String[] args )
  {
    XSplashWindow.splash( XSplashWindow.class.getResource( "/splash.gif" ));
    if ( args.length == 0 )
      XSplashWindow.invokeMain( "net.xoetrope.swing.XApplet", args );
    else {
      String[] appArgs = new String[ args.length -1 ];
      for ( int i = 1; i < args.length; i++ )
        appArgs[ i-1 ] = args[ i ];
      XSplashWindow.invokeMain( args[ 0 ], appArgs );
    }
    XSplashWindow.disposeSplash( 8000 );
  }  
}
TOP

Related Classes of net.xoetrope.swing.splash.XSplashWindow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.