package net.xoetrope.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Image;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Hashtable;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import net.xoetrope.debug.AWTExceptionHandler;
import net.xoetrope.xui.PageSupport;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.xui.XApplicationContext;
import net.xoetrope.xui.XPage;
import net.xoetrope.xui.XStartupObject;
/**
* <p>This class is constructed with a window or frame
* and can be part of an applet or an application. The class acts as the main
* entry point to an XUI application and provides some of the infrastructure
* needed to support the application.</p>
* <p>The applet can provide support for a frameset or a single page. Page display
* functions are also supported to allow the application to display more than a
* single page or change the page that is displayed.</p>
* <p>By choosing either the AWT or Swing version of the XApplet you choose to
* have either an AWT or a Swing application/applet. In general once this choice
* has been made you should not mix toolkits.</p>
* <p>Copyright (c) Xoetrope Ltd., 1998-2006. See license.txt for more details</p>
* @version $Revision: 1.1 $
*/
public class XApplet
extends JApplet
implements XStartupObject
{
/**
* The application window
*/
protected Window appWindow;
/**
* The Application frame
*/
protected JFrame clientFrame;
/**
* true if a popup window is in use
*/
protected boolean bUseWindow;
protected XApplicationContext applicationContext;
/**
* The panel holding the page content
*/
protected Container pageHolder;
/**
* main method to be invoked as an application. This method is invoked as the
* entry point to the 'Application', it is not used if an Applet is being
* launched. This method establishes the frame within which the application
* runs. If overloading this method remeber to call the setup method.
* @param args the optional command line arguments
* <ol>
* <li>the relative path to the startup file, defaults to startup.properties if no arguments are provided</li>
* <li>the package name for the widgets e.g. "net.xoetrope.swing"</li>
* </ol>
*/
public static void main( String args[] )
{
if ( BuildProperties.DEBUG )
AWTExceptionHandler.register();
final String[] myArgs = args;
SwingUtilities.invokeLater( new Runnable() {
public void run()
{
// createSplashScreen();
loadUI( myArgs );
}
});
}
/**
* Do the actual work of loading the UI
* @param args the optional command line arguments
* <ol>
* <li>the relative path to the startup file, defaults to startup.properties if no arguments are provided</li>
* <li>the package name for the widgets e.g. "net.xoetrope.swing"</li>
* </ol>
*/
protected static void loadUI( String[] args )
{
JFrame frame = new JFrame();
XApplet applet = new XApplet( args, frame );
frame.getContentPane().add( applet );
frame.validate();
}
/**
* A default constructor. Most of the setup work is actually done by the initialize
* method and is called by the main method or the init method depending on
* whether or not an application of applet is being launched.
* @param args the application command-line arguments
* @param frame the parent frame
*/
public XApplet()
{
this( null, null );
}
/**
* Create a new aplication. Most of the setup work is actually done by the initialize
* method and is called by the main method or the init method depending on
* whether or not an application of applet is being launched.
* @param args the optional command line arguments
* <ol>
* <li>the relative path to the startup file, defaults to startup.properties if no arguments are provided</li>
* <li>the package name for the widgets e.g. "net.xoetrope.swing"</li>
* </ol>
* @param frame the main (application) frame.
*/
public XApplet( String[] args, JFrame frame )
{
clientFrame = frame;
SwingWidgetAdapter.getInstance();
applicationContext = new XApplicationContext( this, args );
}
/**
* Get the parent object
* @return the parent
*/
public Object getParentObject()
{
return getParent();
}
/**
* Get the package name for the default widget set
*/
public String getWidgetClassPackage()
{
return XPage.XUI_SWING_PACKAGE;
}
/**
* Setup frameset. This method is called prior to the addition of any target
* areas in the framset and prior to the display of any pages. Since this
* applet does not support configurable framesets, this method ignores the
* parameter values passed.
* @param params the framset parameters if any
*/
public void setupFrameset( Hashtable params )
{
}
/**
* Display a window decoration, for example a toolbar
* @param page the new page
* @param constraint a value controlling how and where the decoration is
* displayed, this value is application type specific
* @return the page being displayed
*/
public Object displayDecoration( PageSupport page, String constraint )
{
if ( constraint.equals( "NORTH" ))
pageHolder.add( (Component)page, BorderLayout.NORTH );
else if ( constraint.equals( "SOUTH" ))
pageHolder.add( (Component)page, BorderLayout.SOUTH );
else if ( constraint.equals( "EAST" ))
pageHolder.add( (Component)page, BorderLayout.EAST );
else if ( constraint.equals( "WEST" ))
pageHolder.add( (Component)page, BorderLayout.WEST );
else if ( constraint.equals( "CENTER" ))
pageHolder.add( (Component)page, BorderLayout.CENTER );
else
return null;
return page;
}
/**
* Validate and repaint the display
*/
public void refresh()
{
if ( appWindow != null ) {
appWindow.invalidate();
appWindow.validate();
appWindow.repaint();
}
layout();
}
/**
* <p>Restore the normal page views, as in the case of the docking layout where
* panels may be zoomed or minimized. The method is called prior to the
* display of a new page.</p>
* <p>In this context the method has no effect.</p>
*/
public void restoreViews()
{
}
/**
* Get the content pane used by XUI - the container in which pages are
* displayed
* @return the page container
*/
public Object getContentPaneEx()
{
return pageHolder;
}
public void setAppTitle( String title )
{
try {
if ( clientFrame != null )
clientFrame.setTitle( title );
}
catch ( Exception ex1 ) {
ex1.printStackTrace();
}
}
/**
* Set the application icon
* @param img the image name
*/
public void setIcon( Image icon )
{
if ( icon != null )
clientFrame.setIconImage( icon );
}
/**
* Setup the main application window
* @param context the application context for the new application
* @param currentProject the current project
* @param clientWidth the desired width for the new window
* @param clientHeight the desired height for the new window
*/
public void setupWindow( XApplicationContext context, XProject currentProject, int clientWidth, int clientHeight )
{
currentProject.setStartupParam( "MainClass", "net.xoetrope.swing.XApplet" );
String sUseWindow = currentProject.getStartupParam( "UseWindow" );
bUseWindow = "true".equals( sUseWindow ) ? true : false;
String sMaximize = currentProject.getStartupParam( "MaximizeWindow" );
if (( sMaximize != null ) && ( sMaximize.equals( "true" ))) {
Dimension mScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
clientWidth = mScreenSize.width;
clientHeight = mScreenSize.height;
}
setSize( clientWidth, clientHeight );
if ( clientFrame != null )
clientFrame.setSize( clientWidth, clientHeight );
String sUndecoratedWin = currentProject.getStartupParam( "UndecoratedWin" );
if (( clientFrame != null ) && ( sUndecoratedWin != null ) && sUndecoratedWin.equals( "true" ))
callDecorationMethod( clientFrame, true );
appWindow = null;
if ( bUseWindow ) {
appWindow = new JWindow( clientFrame );
appWindow.setSize( clientWidth, clientHeight );
appWindow.addWindowListener( context );
clientFrame.addWindowListener( context );
}
else {
appWindow = clientFrame;
if ( clientFrame != null )
clientFrame.addWindowListener( context );
}
clientFrame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if ( bUseWindow ) {
Dimension frameSize = appWindow.getSize();
appWindow.setLocation( ( screenSize.width - frameSize.width ) / 2, ( screenSize.height - frameSize.height ) / 2 );
appWindow.setVisible( true );
clientFrame.setLocation( screenSize.width / 2, screenSize.height / 2 );
clientFrame.setSize( 0,0 );
clientFrame.setVisible( true );
appWindow.setLayout( new BorderLayout());
appWindow.add( pageHolder = new JPanel(), BorderLayout.CENTER );
pageHolder.setVisible( true );
}
else if ( clientFrame != null ) {
Dimension frameSize = clientFrame.getSize();
String center = null;
try {
center = currentProject.getStartupParam( "CenterWin" );
}
catch ( Exception ex ) {
}
if ( "true".equals( center ))
clientFrame.setLocation(( screenSize.width - frameSize.width ) / 2, ( screenSize.height - frameSize.height ) / 2 );
clientFrame.setVisible( true );
getContentPane().setLayout( new BorderLayout());
pageHolder = super.getContentPane();
}
currentProject.setApplet( this );
currentProject.setStartupObject( this );
currentProject.setAppFrame( clientFrame );
currentProject.setAppWindow( appWindow );
}
/**
* Call setUndecorated via reflection as it is only in JDK1.4+
* @param obj a reference to the dialog instance
* @param value the boolean argument
* @return true if the call succeeds
*/
private boolean callDecorationMethod( Object obj, boolean value )
{
try {
Class c = obj.getClass();
Field f = this.getClass().getField( "trueField" );
Class[] params = new Class[ 1 ];
params[ 0 ] = f.getType();
Method theMethod = c.getMethod( "setUndecorated", params );
Object args[] = new Object[ 1 ];
args[ 0 ] = f.get( this );
theMethod.invoke( obj, args );
return true;
}
catch ( Exception ex ) {
ex.getCause().printStackTrace();
}
return false;
}
/**
* Invoked when used as an applet. Sets up the startup file and initialises
* the application. Reads the applet parameters and calls initialize.
*/
public void init()
{
applicationContext.init();
}
/**
* Gets the Frame containing the applet.
* @return Frame which is the applet or application's parent
*/
public JFrame getFrame()
{
if ( clientFrame != null )
return clientFrame;
Container parent;
for ( parent = getParent(); parent != null; parent = parent.getParent() ) {
if (( parent != null ) && ( parent instanceof JFrame ))
return (JFrame)parent;
}
return null;
}
/**
* Set the menubar.
* @param mb the new menu bar
*/
public void setMenuBar( JMenuBar mb )
{
setJMenuBar( mb );
}
/**
* Get the menubar.
* @return the menu bar
*/
public Object getApplicationMenuBar()
{
return getJMenuBar();
}
/**
* Set the menubar
* @param mb the menubar
*/
public void setApplicationMenuBar( Object mb )
{
setJMenuBar( (JMenuBar)mb );
// Force the menu to refresh, otherwise the menu is not usable till the
// frame is revalidated/resized
((JMenuBar)mb).setVisible( false );
((JMenuBar)mb).setVisible( true );
}
}