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;
}
}