package skrueger.swing; import java.awt.Component; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import javax.swing.JDialog; import org.apache.log4j.Logger; public abstract class DialogManager { final static private Logger LOGGER = Logger.getLogger(DialogManager.class); public abstract class FactoryInterface { public abstract DIALOG create(); /** May be overridden to add Listeners **/ public void afterCreation(DIALOG newInstance) { }; /** May be overridden to remove Listeners added earlier **/ public void beforeDispose(DIALOG newInstance) { }; } protected HashMap dialogCache = new HashMap(); /** * A {@link DialogManager} instance can be created for any extension of * {@link JDialog} that will implement the * {@link #getInstanceFor(Object, Component, Object...)} method. */ public DialogManager() { } /** * This will be done with every dialog that an instance is required for. * * @param dialog * @return */ protected DIALOG bringup(DIALOG dialog) { if (dialog == null){ // The dialog creation may have been cancelled return null; } if (!dialog.isVisible()) dialog.setVisible(true); dialog.toFront(); return dialog; } /** * Implementing this should have a
* try { ... return ... } catch (Exception e) { ExceptionDialog.show(owner, e); return null; } block. * * @param key * @param owner * @param constArgs * @return a cached instance or creates a new instance. Instances are always * returned visible and toFront. */ public abstract DIALOG getInstanceFor(final KEY key, final Component owner, final Object... constArgs); /** * @return Is there an open/visible dialog for the given layer id? */ public boolean isVisibleFor(KEY key) { return dialogCache.containsKey(key) && dialogCache.get(key).isVisible(); } /** * Will dispose any dialog that is registered to the given parent * {@link Component} * * @param parent */ public void disposeInstanceForParent(final Component parent) { final HashMap clonedHashMap = (HashMap) dialogCache .clone(); for (KEY chartId : clonedHashMap.keySet()) { if (dialogCache.get(chartId).getParent() == parent) { disposeInstanceFor(chartId); } } } public boolean disposeInstanceFor(KEY key) { synchronized (dialogCache) { final DIALOG dialog = dialogCache.get(key); if (dialog != null) { dialog.dispose(); dialogCache.remove(key); return true; } return false; } } /** * Checks whether there already is an instance for that key and otherwise * will create the instance by invoking the {@link FactoryInterface} #create * method. * * @param factory * {@link FactoryInterface} that creates the DIALOG * * @return Always a visible and inFront instance of DIALOG for the given * key. */ public DIALOG getInstanceFor(final KEY key, final FactoryInterface factory) { final DIALOG dialog; if (isVisibleFor(key)) { dialog = dialogCache.get(key); } else { dialog = factory.create(); if (dialog.isDisposed) { // The creation of the Dialog may have been cancelled for some reason return null; } dialogCache.put(key, dialog); dialog.setVisible(true); dialog.toFront(); dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosed(final WindowEvent e) { dialogCache.remove(key); factory.beforeDispose(dialog); } @Override public void windowClosing(final WindowEvent e) { } }); factory.afterCreation(dialog); } return dialog; } /** * Disposes all open instances and removes them from the cache. * * @return true if at least one window has been disposed. */ public boolean disposeAll() { boolean atLeastOne = false; HashSet tempKeys = new HashSet(dialogCache.keySet()); for (KEY key : tempKeys) { DIALOG dialog = dialogCache.get(key); if (dialog != null) { dialog.dispose(); atLeastOne = true; } } tempKeys.clear(); dialogCache.clear(); return atLeastOne; } /** * @return All instances of DIALOG as they are cached. */ public Collection getAllInstances() { return dialogCache.values(); } }