001 package com.croftsoft.core.gui;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import javax.swing.JOptionPane;
006
007 import com.croftsoft.core.lang.lifecycle.Destroyable;
008
009 /*********************************************************************
010 * Performs a graceful shutdown of a program when the window is closed.
011 *
012 * <p>
013 * <ol>
014 * <li> Prompts for shutdown confirmation.
015 * <li> Calls the window hide() method.
016 * <li> Calls the destroy() method, in array order, of each of the
017 * Destroyable instances passed via the constructor argument.
018 * Any exceptions are caught, printed, and ignored.
019 * <li> Calls the window dispose() method.
020 * <li> Calls System.exit(0).
021 * </ol>
022 * </p>
023 *
024 * <p>
025 * Example:
026 * <code>
027 * <pre>
028 * jFrame.setDefaultCloseOperation (
029 * javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE );
030 *
031 * jFrame.addWindowListener (
032 * new ShutdownWindowAdapter ( this, "Exit Program?" ) );
033 * </pre>
034 * </code>
035 * </p>
036 *
037 * @version
038 * $Date: 2006/01/13 18:47:08 $
039 * @version
040 * 2001-03-06
041 * @author
042 * <a href="http://www.CroftSoft.com/">David Wallace Croft</a>
043 *********************************************************************/
044
045 public class ShutdownWindowAdapter
046 extends WindowAdapter
047 //////////////////////////////////////////////////////////////////////
048 //////////////////////////////////////////////////////////////////////
049 {
050
051 private final Destroyable [ ] destroyables;
052
053 private final String shutdownConfirmationPrompt;
054
055 private final String shutdownConfirmationTitle;
056
057 //////////////////////////////////////////////////////////////////////
058 //////////////////////////////////////////////////////////////////////
059
060 /*********************************************************************
061 * Main constructor.
062 *
063 * @param destroyables
064 * May be null.
065 * @param shutdownConfirmationPrompt
066 * If null, no shutdown confirmation prompt dialog will be given.
067 * @param shutdownConfirmationTitle
068 * If null, the shutdownConfirmationPrompt value will be used.
069 *********************************************************************/
070 public ShutdownWindowAdapter (
071 Destroyable [ ] destroyables,
072 String shutdownConfirmationPrompt,
073 String shutdownConfirmationTitle )
074 //////////////////////////////////////////////////////////////////////
075 {
076 this.destroyables = destroyables;
077
078 this.shutdownConfirmationPrompt = shutdownConfirmationPrompt;
079
080 this.shutdownConfirmationTitle = shutdownConfirmationTitle;
081 }
082
083 /*********************************************************************
084 * Convenience constructor.
085 *
086 * <code>
087 * <pre>
088 * this ( destroyables, shutdownConfirmationPrompt, null );
089 * </pre>
090 * </code>
091 *********************************************************************/
092 public ShutdownWindowAdapter (
093 Destroyable [ ] destroyables,
094 String shutdownConfirmationPrompt )
095 //////////////////////////////////////////////////////////////////////
096 {
097 this ( destroyables, shutdownConfirmationPrompt, null );
098 }
099
100 /*********************************************************************
101 * Convenience constructor.
102 *
103 * <code>
104 * <pre>
105 * this (
106 * new Destroyable [ ] { destroyable },
107 * shutdownConfirmationPrompt );
108 * </pre>
109 * </code>
110 *********************************************************************/
111 public ShutdownWindowAdapter (
112 Destroyable destroyable,
113 String shutdownConfirmationPrompt )
114 //////////////////////////////////////////////////////////////////////
115 {
116 this (
117 new Destroyable [ ] { destroyable },
118 shutdownConfirmationPrompt );
119 }
120
121 /*********************************************************************
122 * Convenience constructor.
123 *
124 * <code>
125 * <pre>
126 * this ( destroyables, null );
127 * </pre>
128 * </code>
129 *********************************************************************/
130 public ShutdownWindowAdapter ( Destroyable [ ] destroyables )
131 //////////////////////////////////////////////////////////////////////
132 {
133 this ( destroyables, null );
134 }
135
136 /*********************************************************************
137 * Convenience constructor.
138 *
139 * <code>
140 * <pre>
141 * this ( new Destroyable [ ] { destroyable } );
142 * </pre>
143 * </code>
144 *********************************************************************/
145 public ShutdownWindowAdapter ( Destroyable destroyable )
146 //////////////////////////////////////////////////////////////////////
147 {
148 this ( new Destroyable [ ] { destroyable } );
149 }
150
151 public ShutdownWindowAdapter ( )
152 //////////////////////////////////////////////////////////////////////
153 {
154 this ( ( Destroyable [ ] ) null );
155 }
156
157 //////////////////////////////////////////////////////////////////////
158 //////////////////////////////////////////////////////////////////////
159
160 public void windowClosing ( WindowEvent windowEvent )
161 //////////////////////////////////////////////////////////////////////
162 {
163 Window window = windowEvent.getWindow ( );
164
165 if ( shutdownConfirmationPrompt != null )
166 {
167 int confirm = JOptionPane.showOptionDialog ( window,
168 shutdownConfirmationPrompt,
169 shutdownConfirmationTitle != null
170 ? shutdownConfirmationTitle : shutdownConfirmationPrompt,
171 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
172 null, null, null );
173
174 if ( confirm != JOptionPane.YES_OPTION )
175 {
176 return;
177 }
178 }
179
180 window.setVisible ( false );
181
182 if ( destroyables != null )
183 {
184 for ( int i = 0; i < destroyables.length; i++ )
185 {
186 Destroyable destroyable = destroyables [ i ];
187
188 if ( destroyable != null )
189 {
190 try
191 {
192 destroyable.destroy ( );
193 }
194 catch ( Exception ex )
195 {
196 ex.printStackTrace ( );
197 }
198 }
199 }
200 }
201
202 window.dispose ( );
203
204 System.exit ( 0 );
205 }
206
207 //////////////////////////////////////////////////////////////////////
208 //////////////////////////////////////////////////////////////////////
209 }