001         package com.croftsoft.core.gui;
002    
003         import java.awt.*;
004         import java.awt.event.*;
005         import javax.swing.*;
006    
007         import com.croftsoft.core.awt.image.ImageLib;
008         import com.croftsoft.core.gui.FullScreenToggler;
009         import com.croftsoft.core.lang.NullArgumentException;
010         import com.croftsoft.core.lang.lifecycle.AppletLifecycle;
011         import com.croftsoft.core.lang.lifecycle.Lifecycle;
012         import com.croftsoft.core.lang.lifecycle.LifecycleLib;
013    
014         /*********************************************************************
015         * Calls the lifecycle methods in response to windowing events.
016         *
017         * <p>
018         * When the window is activated, calls the start() methods.
019         * When the window is deactivated, calls the stop() methods.
020         * The first time the window is activated, the init() method
021         * will be called.
022         * </p>
023         *
024         * <p>
025         * Performs the following upon the window closing event:
026         * <ol>
027         * <li> Prompts for shutdown confirmation.
028         * <li> Calls the window hide() method.
029         * <li> Calls the stop and destroy() method, in array order, of each of
030         *      the Lifecycle instances passed via the constructor argument.
031         *      Any exceptions are caught, printed, and ignored.
032         * <li> Calls the window dispose() method.
033         * <li> Calls System.exit(0).
034         * </ol>
035         * </p>
036         *
037         * <p>
038         * Example:
039         * <code>
040         * <pre>
041         * jFrame.setDefaultCloseOperation (
042         *   javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE );
043         *
044         * jFrame.addWindowListener (
045         *   new LifecycleWindowListener ( this, "Exit Program?" ) );
046         * </pre>
047         * </code>
048         * </p>
049         *
050         * @version
051         *   $Date: 2006/01/03 20:05:54 $
052         * @since
053         *   2002-12-24
054         * @author
055         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
056         *********************************************************************/
057    
058         public final class  LifecycleWindowListener
059           implements WindowListener
060         //////////////////////////////////////////////////////////////////////
061         //////////////////////////////////////////////////////////////////////
062         {
063    
064         private final Lifecycle [ ]  lifecycles;
065    
066         private final String         shutdownConfirmationPrompt;
067    
068         private final String         shutdownConfirmationTitle;
069    
070         //
071    
072         private boolean  initialized;
073    
074         //////////////////////////////////////////////////////////////////////
075         // Static methods
076         //////////////////////////////////////////////////////////////////////
077    
078         /*********************************************************************
079         * Test and demonstration method.
080         *********************************************************************/
081         public static void  main ( String [ ]  args )
082         //////////////////////////////////////////////////////////////////////
083         {
084           launchFrameAsDesktopApp (
085             new JFrame ( "Test" ),
086             new Lifecycle [ ] {
087               new Lifecycle ( )
088               {
089                 public void  init    ( ) { System.out.println ( "init"    ); }
090                 public void  start   ( ) { System.out.println ( "start"   ); }
091                 public void  stop    ( ) { System.out.println ( "stop"    ); }
092                 public void  destroy ( ) { System.out.println ( "destroy" ); }
093               } },
094             null, // frameSize
095             "Exit Test?" );
096         }
097    
098         /*********************************************************************
099         * Associates a LifecycleWindowListener with the JFrame and launches.
100         *
101         * <p>
102         * In order to create a flexible JFrame subclass that can be run either
103         * as a stand-alone desktop application by itself or as a pop-up frame
104         * called from a currently running program, you will need to maintain
105         * the logic for handling these different modes of operation outside of
106         * the subclass itself.  This method provides the logic for running a
107         * JFrame subclass as an independent desktop application.
108         * </p>
109         *
110         * <p>
111         * This method associates a LifecycleWindowAdapter with the JFrame which
112         * will call the lifecycle methods in response to windowing events.
113         * It then launches the JFrame on the center of the screen.
114         * </p>
115         *
116         * @see
117         *   Lifecycle
118         *
119         * @param  lifecycles
120         *
121         *   An optional array of Lifecycle objects to initialized upon
122         *   startup, started upon window activation, stopped upon window
123         *   deactivation, and destroyed upon shutdown.  May be null.
124         *
125         * @param  frameSize
126         *
127         *   If null, a default value will be used based upon screen size.
128         *
129         * @param  shutdownConfirmationPrompt
130         *
131         *   If null, no confirmation prompt will be given.
132         *********************************************************************/
133         public static void  launchFrameAsDesktopApp (
134           JFrame               jFrame,
135           final Lifecycle [ ]  lifecycles,
136           Dimension            frameSize,
137           String               shutdownConfirmationPrompt )
138         //////////////////////////////////////////////////////////////////////
139         {
140           NullArgumentException.check ( jFrame );
141    
142           jFrame.setDefaultCloseOperation (
143             WindowConstants.DO_NOTHING_ON_CLOSE );
144    
145           jFrame.addWindowListener ( new LifecycleWindowListener (
146             lifecycles, shutdownConfirmationPrompt ) );
147    
148           if ( frameSize != null )
149           {
150             WindowLib.centerOnScreen ( jFrame, frameSize );
151           }
152           else
153           {
154             WindowLib.centerOnScreen ( jFrame, 0.8 );
155           }
156    
157           jFrame.setVisible ( true );
158         }
159    
160         public static void  launchFrameAsDesktopApp (
161           final JFrame     jFrame,
162           final Lifecycle  lifecycle,
163           final Dimension  frameSize,
164           final String     shutdownConfirmationPrompt )
165         //////////////////////////////////////////////////////////////////////
166         {
167           launchFrameAsDesktopApp (
168             jFrame,
169             new Lifecycle [ ] { lifecycle },
170             frameSize,
171             shutdownConfirmationPrompt );
172         }
173         
174         public static void  launchAppletAsDesktopApp (
175           JApplet      applet,
176           String       frameTitle,
177           String       frameIconFilename,
178           ClassLoader  classLoader,
179           boolean      useFullScreenToggler,
180           Dimension    frameSize,
181           String       shutdownConfirmationPrompt )
182         //////////////////////////////////////////////////////////////////////
183         {
184           NullArgumentException.check ( applet );
185    
186           if ( frameTitle == null )
187           {
188             frameTitle = "";
189           }
190    
191           JFrame  jFrame = new JFrame ( frameTitle );
192    
193           if ( frameIconFilename != null )
194           {
195             try
196             {
197               jFrame.setIconImage ( ImageLib.loadBufferedImage (
198                 frameIconFilename, classLoader ) );
199             }
200             catch ( Exception  ex )
201             {
202             }
203           }
204    
205           jFrame.setContentPane ( applet );
206    
207           if ( useFullScreenToggler )
208           {
209             FullScreenToggler.monitor ( jFrame );
210           }
211    
212           LifecycleWindowListener.launchFrameAsDesktopApp (
213             jFrame,
214             new Lifecycle [ ] { new AppletLifecycle ( applet ) },
215             frameSize,
216             shutdownConfirmationPrompt );
217         }
218    
219         //////////////////////////////////////////////////////////////////////
220         // constructor methods
221         //////////////////////////////////////////////////////////////////////
222    
223         /*********************************************************************
224         * Main constructor.
225         *
226         * @param  lifecycles
227         *   May be null.
228         * @param  shutdownConfirmationPrompt
229         *   If null, no shutdown confirmation prompt dialog will be given.
230         * @param  shutdownConfirmationTitle
231         *   If null, the shutdownConfirmationPrompt value will be used.
232         *********************************************************************/
233         public  LifecycleWindowListener (
234           Lifecycle [ ]  lifecycles,
235           String         shutdownConfirmationPrompt,
236           String         shutdownConfirmationTitle )
237         //////////////////////////////////////////////////////////////////////
238         {
239           this.lifecycles                 = lifecycles;
240    
241           this.shutdownConfirmationPrompt = shutdownConfirmationPrompt;
242    
243           this.shutdownConfirmationTitle  = shutdownConfirmationTitle;
244         }
245    
246         /*********************************************************************
247         * Convenience constructor.
248         *
249         * <code>
250         * <pre>
251         * this ( lifecycles, shutdownConfirmationPrompt, null );
252         * </pre>
253         * </code>
254         *********************************************************************/
255         public  LifecycleWindowListener (
256           Lifecycle [ ]  lifecycles,
257           String         shutdownConfirmationPrompt )
258         //////////////////////////////////////////////////////////////////////
259         {
260           this ( lifecycles, shutdownConfirmationPrompt, null );
261         }
262    
263         /*********************************************************************
264         * Convenience constructor.
265         *
266         * <code>
267         * <pre>
268         * this (
269         *   new Lifecycle [ ] { lifecycle },
270         *   shutdownConfirmationPrompt );
271         * </pre>
272         * </code>
273         *********************************************************************/
274         public  LifecycleWindowListener (
275           Lifecycle  lifecycle,
276           String     shutdownConfirmationPrompt )
277         //////////////////////////////////////////////////////////////////////
278         {
279           this (
280             new Lifecycle [ ] { lifecycle },
281             shutdownConfirmationPrompt );
282         }
283    
284         /*********************************************************************
285         * Convenience constructor.
286         *
287         * <code>
288         * <pre>
289         * this ( lifecycles, null );
290         * </pre>
291         * </code>
292         *********************************************************************/
293         public  LifecycleWindowListener ( Lifecycle [ ]  lifecycles )
294         //////////////////////////////////////////////////////////////////////
295         {
296           this ( lifecycles, null );
297         }
298    
299         /*********************************************************************
300         * Convenience constructor.
301         *
302         * <code>
303         * <pre>
304         * this ( new Lifecycle [ ] { lifecycle } );
305         * </pre>
306         * </code>
307         *********************************************************************/
308         public  LifecycleWindowListener ( Lifecycle  lifecycle )
309         //////////////////////////////////////////////////////////////////////
310         {
311           this ( new Lifecycle [ ] { lifecycle } );
312         }
313    
314         //////////////////////////////////////////////////////////////////////
315         //////////////////////////////////////////////////////////////////////
316    
317         public void  windowActivated ( WindowEvent  windowEvent )
318         //////////////////////////////////////////////////////////////////////
319         {
320           if ( !initialized )
321           {
322             LifecycleLib.init ( lifecycles );
323    
324             initialized = true;
325           }
326    
327           LifecycleLib.start ( lifecycles );
328         }
329    
330         public void  windowClosed ( WindowEvent  windowEvent )
331         //////////////////////////////////////////////////////////////////////
332         {
333         }
334    
335         public void  windowClosing ( WindowEvent  windowEvent )
336         //////////////////////////////////////////////////////////////////////
337         {
338           Window  window = windowEvent.getWindow ( );
339    
340           if ( shutdownConfirmationPrompt != null )
341           {
342             int  confirm = JOptionPane.showOptionDialog ( window,
343               shutdownConfirmationPrompt, 
344               shutdownConfirmationTitle != null
345                 ? shutdownConfirmationTitle : shutdownConfirmationPrompt,
346               JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
347               null, null, null );
348    
349             if ( confirm != JOptionPane.YES_OPTION )
350             {
351               return;
352             }
353           }
354    
355           window.setVisible ( false );
356    
357           if ( shutdownConfirmationPrompt == null )
358           {
359             LifecycleLib.stop ( lifecycles );
360           }
361    
362           LifecycleLib.destroy ( lifecycles );
363    
364           window.dispose ( );
365    
366           System.exit ( 0 );
367         }
368    
369         public void  windowDeactivated ( WindowEvent  windowEvent )
370         //////////////////////////////////////////////////////////////////////
371         {
372           LifecycleLib.stop ( lifecycles );
373         }
374    
375         public void  windowDeiconified ( WindowEvent  windowEvent )
376         //////////////////////////////////////////////////////////////////////
377         {
378         }
379    
380         public void  windowIconified ( WindowEvent  windowEvent )
381         //////////////////////////////////////////////////////////////////////
382         {
383         }
384    
385         public void  windowOpened ( WindowEvent  windowEvent )
386         //////////////////////////////////////////////////////////////////////
387         {
388         }
389    
390         //////////////////////////////////////////////////////////////////////
391         //////////////////////////////////////////////////////////////////////
392         }