Package net.xoetrope.swing.deploy

Source Code of net.xoetrope.swing.deploy.XSystemTrayManager

package net.xoetrope.swing.deploy;

import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.lang.reflect.Method;
import javax.jnlp.ServiceManager;
import javax.jnlp.SingleInstanceListener;
import javax.jnlp.SingleInstanceService;
import javax.jnlp.UnavailableServiceException;
import javax.swing.Icon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.swing.*;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.build.BuildProperties;

import org.jdesktop.jdic.tray.SystemTray;
import org.jdesktop.jdic.tray.TrayIcon;

/**
* <p>
* A manager class for tray actions. When a system tray icon is added the
* application can choose to stay resident in memory after the main window has
* been closed by setting the ExitOnClose startup property to false. The
* advantage of doing this is that the data model does not need to be
* reinitialized if the main window is just being redisplayed.
* </p>
* <p>
* The tray icon provides two menu items, one to open the window and the second
* to close the window and exit the JVM.
* </p>
* <p>This version of the class uses the SwingLabs version of the tray support
* and is therefore limited to Swing. If JDK 6 or later is being used then
* the JVM's tray support could be used for non Swing applications
* </p>
* <p>
* If the application is launched via JavaWebStart then the XSystemTrayManager
* is installed as a singleton and each subsequent invocation via JWS will
* cause a new activation. If the application has set an "ActivationObject"
* via the project.setObject( "ActivationObject", XActivation ) then the
* XActivation.activate method is invoked and the appliction can check the
* startup properties and perform the appropriate action.
* </p>
* <p>Copyright (c) Xoetrope Ltd., 2001-2007, see license.txt for details</p>
*/
public class XSystemTrayManager implements ActionListener, SingleInstanceListener
  private static XSystemTrayManager instance;
  private static TrayIcon trayIcon;
 
  private static XProject currentProject;

  private boolean stripSplashArgument;
 
  /**
   *
   * Creates a new instance of XSystemTrayManager
   */
  private XSystemTrayManager()
  {
    stripSplashArgument = false;
   
    try {
      SingleInstanceService singleInstanceService = (SingleInstanceService)ServiceManager.
                lookup( "javax.jnlp.SingleInstanceService" );
      // add the listener to this application!
      singleInstanceService.addSingleInstanceListener( this );
    }
    catch ( UnavailableServiceException use ) {
      DebugLogger.logWarning( "The JNLP singleton service is not available" );
    }
       
    if ( trayIcon == null ) {
      SystemTray st = SystemTray.getDefaultSystemTray();
      trayIcon = new TrayIcon( (Icon)currentProject.getIcon( "xui_icon.png" ), currentProject.getStartupParam( "Title" ));
      trayIcon.addActionListener( this );
      st.addTrayIcon( trayIcon );
     
      JPopupMenu popup = new JPopupMenu();
      JMenuItem defaultItem = new JMenuItem( "Exit" );
      defaultItem.addActionListener( new ActionListener() {
        public void actionPerformed( ActionEvent ae )
        {
          currentProject.setStatus( XProject.CLOSING );
          currentProject.setStartupParam( "ExitOnClose", "true" );
          Window window = currentProject.getAppWindow();
          if ( window != null )
            window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ));
         
          window.dispose();
          System.gc();
        }
      });
     
      JMenuItem openItem = new JMenuItem( "Open" );
      openItem.addActionListener( this );

      popup.add( openItem );
      popup.addSeparator();
      popup.add( defaultItem );
      trayIcon.setPopupMenu( popup );
    }
  }
 
  public static XSystemTrayManager getInstance( XProject project )
  {
    currentProject = project;

    if ( instance == null )
      instance = new XSystemTrayManager();
   
    return instance;
  }
  
  /**
   * Relaunch the application
   */
  public void actionPerformed( ActionEvent e )
  {   
    try {
      Frame f = currentProject.getAppFrame();     
      // Check if the frame is in existance.
      if (( f != null ) && f.isDisplayable()) {
        f.setState( Frame.NORMAL );
        f.toFront();
      }
      else {
        currentProject.setStatus( XProject.RESTARTING );
        Class clazz = Class.forName( currentProject.getStartupParam( "MainClass" ).trim());
        Method mainMethod = clazz.getMethod( "main", new Class[] { String[].class } );
       
        String[] startupArgs = (String[])currentProject.getObject( "StartupArgs" );
        mainMethod.invoke( null, new Object[] { startupArgs });
      }
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG )
        ex.printStackTrace();
      InternalError error = new InternalError( "Failed to invoke main method" );
      error.initCause( ex );
      throw error;
    }
  }
 
  /**
   * Specified by the JNLP SingleInstanceListener interface. Called when a new
   * application instance is being started
   * @param args The command line parameters used for this invocation
   */
  public void newActivation( String[] args )
  {
    /**
     * @todo add some way of distinguishing projects/startups
     */
   
    if ( stripSplashArgument ) {
      String[] appArgs = new String[ args.length -1 ];
      for ( int i = 1; i < args.length; i++ )
        appArgs[ i-1 ] = args[ i ];

      args = appArgs;
    }

    currentProject.setObject( "StartupArgs", args );
   
    if ( BuildProperties.DEBUG ) {
      for ( int i = 0; i < args.length; i++ )
        DebugLogger.trace( "Restart arg " + i + ": " + args[ i ] );
    }
   
    actionPerformed( null );
    showActivationEvent();
  }
 
  /**
   * Set a flag to strip the extra argument added when a splash screen is used
   * at startup. The XSplashWindow class requires an extra argument of the
   * 'main' class proper, but strips this before passing the arguments to that
   * class. Setting this flag to true replicates that behavior for the
   * startup via the system tray when a second JNLP invocation occurs. This is
   * necessary as the new JNLP invocation provides a fresh set of startup
   * arguments
   * @param state true to strip the first argument
   */
  public void setStripSplashArgument( boolean state )
  {
    stripSplashArgument = state;
  }
 
  /**
   * Invoke any registered activation event
   */
  public void showActivationEvent()
  {
    XActivation activationObject = (XActivation)currentProject.getObject( "ActivationObject" );
    if ( activationObject != null )
      activationObject.activate();
  }
}
TOP

Related Classes of net.xoetrope.swing.deploy.XSystemTrayManager

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.