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="https://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 }