Deploying Multiple Java Applets as One - Lifecycle
(Page 3 of 5 )
InterfaceLifecyclefrom packagecom.croftsoft.core.lang.lifecycledefines all four of theAppletlifecycle methods:init(),start(),stop(), anddestroy(). The purpose of the interface is to allow you to build a framework for manipulating lifecycle objects without requiring that they extend from the superclassApplet. For example, you might have a non-visual component that must be initialized, started, stopped, and destroyed that does not need to extendAppletor its super-classPanel.
You might have a framework that needs to initialize a number of objects upon startup and then destroy them upon shutdown. You could pass the objects to the framework as an array of interfaceLifecycleinstances so that a generic routine could initialize and destroy them. This is somewhat less than satisfactory, however, as thestart()andstop()methods would be superfluous and you would need to implement them as blank method bodies.
Over time, I came to the conclusion that the best approach is to define an interface for each method and then extend those interfaces using multiple interface inheritance. Within packagecom.croftsoft.core.lang.lifecycle, you also find the interfacesInitializable,Startable,Stoppable, andDestroyable, each one defining a single lifecycle method. InterfaceCommissionable extends bothInitializable andDestroyable. InterfaceResumableextendsStartableandStoppable. InterfaceLifecycleindirectly extendsInitializable,Startable,Stoppable, andDestroyableby directly extendingCommissionableandResumable.
ClassLifecycleLibin the same package contains a library of static methods for manipulating objects that implement the lifecycle interfaces. For example, static methoddestroy()takes an array ofDestroyable instances as its argument and calls thedestroy()method of each in turn, catching and reporting any exceptions thrown before moving on to the next element.
LifecycleWindowListener
For the demonstration framework to run as a Swing desktop application independent of a container such as a browser, it must be able to translate windowing events into the appropriate lifecycle method calls to your game. For example, when the window is activated for the first time, it should call theinit()andstart()methods to start animation. It should callstop()to suspend the animation when the window is minimized anddestroy()when the window is closed.
package com.croftsoft.core.gui;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.croftsoft.core.awt.image.ImageLib;
import com.croftsoft.core.gui.FullScreenToggler;
import com.croftsoft.core.lang.NullArgumentException;
import com.croftsoft.core.lang.lifecycle.AppletLifecycle;
import com.croftsoft.core.lang.lifecycle.Lifecycle;
import com.croftsoft.core.lang.lifecycle.LifecycleLib;
public final class LifecycleWindowListener
implements WindowListener
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
{
private final Lifecycle [ ] lifecycles; private final String | shutdownConfirmationPrompt; |
private final String | shutdownConfirmationTitle; |
//
private boolean initialized;
[...]
public LifecycleWindowListener (
Lifecycle [ ] lifecycles,
String shutdownConfirmationPrompt,
String shutdownConfirmationTitle )
//////////////////////////////////////////////////////////////////////
{
this.lifecycles = lifecycles;
this.shutdownConfirmationPrompt = shutdownConfirmationPrompt;
this.shutdownConfirmationTitle = shutdownConfirmationTitle;
}
[...]
public void windowActivated ( WindowEvent windowEvent )
//////////////////////////////////////////////////////////////////////
{
if ( !initialized )
{
LifecycleLib.init ( lifecycles );
initialized = true;
}
LifecycleLib.start ( lifecycles );
}
[...]
public void windowClosing ( WindowEvent windowEvent )
//////////////////////////////////////////////////////////////////////
{
Window window = windowEvent.getWindow ( );
if ( shutdownConfirmationPrompt != null )
{
int confirm = JOptionPane.showOptionDialog ( window,
shutdownConfirmationPrompt,
shutdownConfirmationTitle != null
? shutdownConfirmationTitle : shutdownConfirmationPrompt,
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null );
if ( confirm != JOptionPane.YES_OPTION )
{
return;
}
}
window.hide ( );
if ( shutdownConfirmationPrompt == null )
{
LifecycleLib.stop ( lifecycles );
}
LifecycleLib.destroy ( lifecycles );
window.dispose ( );
System.exit ( 0 );
}
public void windowDeactivated ( WindowEvent windowEvent )
//////////////////////////////////////////////////////////////////////
{
LifecycleLib.stop ( lifecycles );
}
[...]
ClassLifecycleWindowListenerin packagecom.croftsoft.core.guiis an implementation of abstract classWindowListenerin packagejava.awt.event. You use it by passing it an array of objects that implement theLifecycleinterface. When the window is activated for the first time it calls theinit() method on theLifecycleobjects. It also calls thestart()method every time. When the window is deactivated, it calls thestop()method. This means that your game animation resumes when the user clicks the window or maximizes it and is suspended when the user clicks outside the window or minimizes it.
When the user clicks the close window icon, it displays a confirmation display window on top. This deactivates the parent window which results in a call to the game objectstop()method, suspending game animation. If the user then decides to proceed with the shutdown, it will call thedestroy()method before exit. If the user decides to cancel instead, the confirmation display is dismissed. This reactivates the parent window and results in a call to the game objectstart()method, resuming game animation.
public static void | launchFrameAsDesktopApp ( |
JFrame | jFrame, |
final Lifecycle [ ] | lifecycles, |
Dimension | frameSize, |
String | shutdownConfirmationPrompt ) |
//////////////////////////////////////////////////////////////////////
{
NullArgumentException.check ( jFrame );
jFrame.setDefaultCloseOperation (
WindowConstants.DO_NOTHING_ON_CLOSE );
jFrame.addWindowListener ( new
LifecycleWindowListener (
lifecycles, shutdownConfirmationPrompt ) );
if ( frameSize != null )
{
WindowLib.centerOnScreen ( jFrame, frameSize );
}
else
{
WindowLib.centerOnScreen ( jFrame, 0.8 );
}
jFrame.show ( );
}
Static methodlaunchFrameAsDesktopApp()is available within the same class. It adds a newLifecycleWindowListenerinstance to the frame and then calls itsshow()method. Showing the window activates it, which calls the lifecycleinit()andstart()methods of your game object. TheLifecyclearray constructor argument passes in the game object. If noframeSizeis specified, it defaults to 80 percent of the screen size.
public static void main ( String [ ] args )
//////////////////////////////////////////////////////////////////////
{
launchFrameAsDesktopApp (
new JFrame ( "Test" ),
new Lifecycle [ ] {
new Lifecycle ( )
{ public void | init | ( ) { System.out.println ( "init" | ); } |
public void | start | ( ) { System.out.println ( "start" | ); } |
public void | stop | ( ) { System.out.println ( "stop" | ); } |
public void | destroy ( ) { System.out.println ( "destroy" ); } |
} },
null, // frameSize
"Exit Test?" );
}
ClassLifecycleWindowListenercontains a staticmain()method that you can use to test and demonstrate its functionality by launching it from the command-line prompt. As you manipulate the window containing the test program, the lifecycle methods print debugging messages to the standard output.
Next: MultiApplet >>
More Java Articles
More By Apress Publishing
|
This article is excerpted from chapter two of Advanced Java Game Programming, written by David Wallace Croft (Apress; ISBN: 1590591232). Check it out today at your favorite bookstore. Buy this book now.
|
|