package skrueger.swing; import java.awt.Component; import java.awt.Dialog; import java.awt.event.ActionEvent; import java.util.Locale; import javax.swing.AbstractAction; import javax.swing.JDialog; import javax.swing.JOptionPane; import schmitzm.lang.LangUtil; import schmitzm.lang.ResourceProvider; import schmitzm.swing.SwingUtil; /** * An abstract {@link JDialog} that implements a basic structure of how * cancellable {@link JDialog}s work. The {@link JDialog} is designed to work on * the real object and restore it's state when the user cancels the * {@link JDialog}. * * Pressing ESC or clicking the "Close X" results in asking the user whether to Save/Cancel/Abort . */ public abstract class CancellableDialogAdapter extends AtlasDialog implements CancellableDialog { protected static ResourceProvider RESOURCE = ResourceProvider.newInstance(LangUtil .extendPackagePath(SwingUtil.class, "resource.locales.SwingResourceBundle"), Locale.ENGLISH); /** Has this dialog been canceled ?**/ protected boolean cancelled = false; private OkButton okButton; private CancelButton cancelButton; public CancellableDialogAdapter(Component parentWindow) { super(parentWindow); } public CancellableDialogAdapter(Component parentWindow, String title) { super(parentWindow, title); } @Override public boolean isCancelled() { return cancelled; } /** * Allows to close the {@link JDialog} from "outside". The user will be * asked and she may cancel the close process. */ public boolean close() { int showConfirmDialog = JOptionPane.showConfirmDialog( CancellableDialogAdapter.this, RESOURCE.getString("CancellableDialogAdapter.close.save.msg",getTitle()), RESOURCE.getString("CancellableDialogAdapter.close.save.title"), JOptionPane.YES_NO_CANCEL_OPTION); if (showConfirmDialog == JOptionPane.YES_OPTION) { return okClose(); } else if (showConfirmDialog == JOptionPane.NO_OPTION) { cancelClose(); return true; } return false; } /** * This method can be called from "outside" to force a close of this * {@link Dialog}. The user can't cancel the process. He may only decide to * save possible changes. */ public void forceClose() { int res = JOptionPane.showConfirmDialog( CancellableDialogAdapter.this, RESOURCE.getString("CancellableDialogAdapter.forceClose.save.msg",getTitle()), RESOURCE.getString("CancellableDialogAdapter.close.save.title"), JOptionPane.YES_NO_OPTION); if (res == JOptionPane.YES_OPTION) { okClose(); } else { cancelClose(); } } /** * Default implementation that calls {@link #cancel()} and * {@link #dispose()}. */ @Override public void cancelClose() { cancel(); cancelled = true; dispose(); } @Override public abstract void cancel(); /** * This method is called when the dialog is closed and not canceled. Can be * overwritten to do anything when the dialog has been accepted. For example * checking for any {@link Checkable} components.
* * @Return false, if the ok has been vetoed. */ public boolean okClose() { dispose(); return true; } /** * @return a default OkButton that will call {@link #okClose()} */ protected OkButton getOkButton() { if (okButton == null) { okButton = new OkButton(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { okClose(); } }); } return okButton; } /** * @return a default CancelButton that will call {@link #cancelClose()} */ protected CancelButton getCancelButton() { if (cancelButton == null) { cancelButton = new CancelButton(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { cancelClose(); } }); } return cancelButton; } }