/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.dtv.lwuit;
import com.sun.dtv.lwuit.animations.Transition;
import com.sun.dtv.lwuit.geom.Dimension;
import com.sun.dtv.lwuit.layouts.BorderLayout;
import com.sun.dtv.lwuit.plaf.LookAndFeel;
import com.sun.dtv.lwuit.plaf.Style;
import com.sun.dtv.lwuit.plaf.UIManager;
/**
* A dialog is a form that occupies a part of the screen and appears as a modal
* entity to the developer. Dialogs allow us to prompt users for information and
* rely on the information being available on the next line after the show method.
* <p>Modality indicates that a dialog will block the calling thread even if the
* calling thread is the EDT. Notice that a dialog will not release the block
* until dispose is called even if show() from another form is called!
* <p>To determin the size of the dialog use the show method that accepts 4 integer
* values, notice that these values accept margin from the four sides rather than x, y, width
* and height values!
* <p>To style the dialog you would usually want to style the content pane rather than
* the dialog itself.
*
* @author Shai Almog
*/
public class Dialog extends Form {
/**
* Indicates whether the dialog has been disposed
*/
private boolean disposed;
/**
* Constant indicating the type of alert to indicate the sound to play or
* icon if none are explicitly set
*/
public static final int TYPE_ALARM = 1;
/**
* Constant indicating the type of alert to indicate the sound to play or
* icon if none are explicitly set
*/
public static final int TYPE_CONFIRMATION = 2;
/**
* Constant indicating the type of alert to indicate the sound to play or
* icon if none are explicitly set
*/
public static final int TYPE_ERROR = 3;
/**
* Constant indicating the type of alert to indicate the sound to play or
* icon if none are explicitly set
*/
public static final int TYPE_INFO = 4;
/**
* Constant indicating the type of alert to indicate the sound to play or
* icon if none are explicitly set
*/
public static final int TYPE_WARNING = 5;
/**
* Indicates the time in which the alert should be disposed
*/
private long time;
/**
* Indicates the last command selected by the user in this form
*/
private Command lastCommandPressed;
/**
* Indicates that this is a menu preventing getCurrent() from ever returning this class
*/
private boolean menu;
private String dialogUIID;
private String dialogTitleUIID;
private int dialogType;
private int top = -1;
private int bottom;
private int left;
private int right;
private boolean includeTitle;
/**
* Determins whether the execution of a command on this dialog implicitly
* disposes the dialog. This defaults to true which is a sensible default for
* simple dialogs.
*/
private boolean autoDispose = true;
private boolean modal = true;
/**
* Constructs a Dialog with a title
*
* @param title the title of the dialog
*/
public Dialog(String title) {
this();
setTitle(title);
}
/**
* Constructs a Dialog with a title
*
*/
public Dialog() {
this("Dialog", "DialogTitle");
}
Dialog(String dialogUIID, String dialogTitleUIID) {
super();
this.dialogUIID = dialogUIID;
this.dialogTitleUIID = dialogTitleUIID;
setDialogStyle(UIManager.getInstance().getComponentStyle(dialogUIID));
setTitleStyle(UIManager.getInstance().getComponentStyle(dialogTitleUIID));
super.getStyle().setBgTransparency(0);
super.getStyle().setBgImage(null);
setSmoothScrolling(false);
deregisterAnimated(this);
}
/**
* Simple setter to set the Dialog Style
*
* @param style
*/
public void setDialogStyle(Style style){
getContentPane().setStyle(style);
}
/**
* Simple getter to get the Dialog Style
*/
public Style getDialogStyle(){
return getContentPane().getStyle();
}
/**
* Initialize the default transition for the dialogs overriding the forms
* transition
*
* @param laf the default transition for the dialog
*/
void initLaf(LookAndFeel laf) {
setTransitionOutAnimator(laf.getDefaultDialogTransitionOut());
setTransitionInAnimator(laf.getDefaultDialogTransitionIn());
}
/**
* This method shows the form as a modal alert allowing us to produce a behavior
* of an alert/dialog box. This method will block the calling thread even if the
* calling thread is the EDT. Notice that this method will not release the block
* until dispose is called even if show() from another form is called!
* <p>Modal dialogs Allow the forms "content" to "hang in mid air" this is especially useful for
* dialogs where you would want the underlying form to "peek" from behind the
* form.
*
* @param top space in pixels between the top of the screen and the form
* @param bottom space in pixels between the bottom of the screen and the form
* @param left space in pixels between the left of the screen and the form
* @param right space in pixels between the right of the screen and the form
* @param includeTitle whether the title should hang in the top of the screen or
* be glued onto the content pane
* @return the last command pressed by the user if such a command exists
*/
public Command show(int top, int bottom, int left, int right, boolean includeTitle) {
return show(top, bottom, left, right, includeTitle, true);
}
/**
* This method shows the form as a modal alert allowing us to produce a behavior
* of an alert/dialog box. This method will block the calling thread even if the
* calling thread is the EDT. Notice that this method will not release the block
* until dispose is called even if show() from another form is called!
* <p>Modal dialogs Allow the forms "content" to "hang in mid air" this is especially useful for
* dialogs where you would want the underlying form to "peek" from behind the
* form.
*
* @param top space in pixels between the top of the screen and the form
* @param bottom space in pixels between the bottom of the screen and the form
* @param left space in pixels between the left of the screen and the form
* @param right space in pixels between the right of the screen and the form
* @param includeTitle whether the title should hang in the top of the screen or
* be glued onto the content pane
* @param modal indicates the dialog should be modal set to false for modeless dialog
* which is useful for some use cases
* @return the last command pressed by the user if such a command exists
*/
public Command show(int top, int bottom, int left, int right, boolean includeTitle, boolean modal) {
this.top = top;
this.bottom = bottom;
this.left = left;
this.right = right;
this.includeTitle = includeTitle;
setDisposed(false);
this.modal = modal;
super.showModal(top, bottom, left, right, includeTitle, modal);
return lastCommandPressed;
}
/**
* Indicates the time (in milliseconds) afterwhich the dialog will be disposed
* implicitly
*
* @param time a milliseconds time used to dispose the dialog
*/
public void setTimeout(long time) {
this.time = System.currentTimeMillis() + time;
super.registerAnimated(this);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param okText the text to appear in the command dismissing the dialog
* @param cancelText optionally null for a text to appear in the cancel command
* for canceling the dialog
* @return true if the ok command was pressed or if cancelText is null. False otherwise.
*/
public static boolean show(String title, String text, int type, Image icon, String okText, String cancelText) {
return show(title, text, type, icon, okText, cancelText, 0);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param okText the text to appear in the command dismissing the dialog
* @param cancelText optionally null for a text to appear in the cancel command
* for canceling the dialog
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @return true if the ok command was pressed or if cancelText is null. False otherwise.
*/
public static boolean show(String title, String text, int type, Image icon, String okText, String cancelText, long timeout) {
Command[] cmds;
Command okCommand = new Command(okText);
if (cancelText != null) {
cmds = new Command[]{new Command(cancelText), okCommand};
} else {
cmds = new Command[]{okCommand};
}
return show(title, text, okCommand, cmds, type, icon, timeout) == okCommand;
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @return the command pressed by the user
*/
public static Command show(String title, String text, Command[] cmds, int type, Image icon, long timeout) {
return show(title, text, null, cmds, type, icon, timeout);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param defaultCommand command to be assigned as the default command or null
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @return the command pressed by the user
*/
public static Command show(String title, String text, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout) {
return show(title, text, defaultCommand, cmds, type, icon, timeout, null);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @param transition the transition installed when the dialog enters/leaves
* @return the command pressed by the user
*/
public static Command show(String title, String text, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
return show(title, text, null, cmds, type, icon, timeout, transition);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param defaultCommand command to be assigned as the default command or null
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @param transition the transition installed when the dialog enters/leaves
* @return the command pressed by the user
*/
public static Command show(String title, String text, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
TextArea t = new TextArea(text, 3, 30);
t.setStyle(UIManager.getInstance().getComponentStyle("DialogBody"));
t.setEditable(false);
return show(title, t, defaultCommand, cmds, type, icon, timeout, transition);
}
/**
* Shows a modal prompt dialog with the given title and text.
*
* @param title The title for the dialog optionally null;
* @param text the text displayed in the dialog
* @param okText the text to appear in the command dismissing the dialog
* @param cancelText optionally null for a text to appear in the cancel command
* for canceling the dialog
* @return true if the ok command was pressed or if cancelText is null. False otherwise.
*/
public static boolean show(String title, String text, String okText, String cancelText) {
return show(title, text, TYPE_INFO, null, okText, cancelText);
}
/**
* Shows a modal dialog with the given component as its "body" placed in the
* center.
*
* @param title title for the dialog
* @param body component placed in the center of the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @return the command pressed by the user
*/
public static Command show(String title, Component body, Command[] cmds) {
return show(title, body, cmds, TYPE_INFO, null);
}
/**
* Shows a modal dialog with the given component as its "body" placed in the
* center.
*
* @param title title for the dialog
* @param body component placed in the center of the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @return the command pressed by the user
*/
public static Command show(String title, Component body, Command[] cmds, int type, Image icon) {
return show(title, body, cmds, type, icon, 0);
}
/**
* Shows a modal dialog with the given component as its "body" placed in the
* center.
*
* @param title title for the dialog
* @param body component placed in the center of the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* @return the command pressed by the user
*/
public static Command show(String title, Component body, Command[] cmds, final int type, Image icon, long timeout) {
return show(title, body, cmds, type, icon, timeout, null);
}
/**
* Shows a modal dialog with the given component as its "body" placed in the
* center.
*
* @param title title for the dialog
* @param body component placed in the center of the dialog
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* the transition installed when the dialog enters/leaves
* @return the command pressed by the user
*/
public static Command show(String title, Component body, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
return show(title, body, null, cmds, type, icon, timeout, transition);
}
/**
* Shows a modal dialog with the given component as its "body" placed in the
* center.
*
* @param title title for the dialog
* @param body component placed in the center of the dialog
* @param defaultCommand command to be assigned as the default command or null
* @param cmds commands that are added to the form any click on any command
* will dispose the form
* @param type the type of the alert one of TYPE_WARNING, TYPE_INFO,
* TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
* @param icon the icon for the dialog, can be null
* @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
* the transition installed when the dialog enters/leaves
* @return the command pressed by the user
*/
public static Command show(String title, Component body, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
Dialog dialog = new Dialog(title);
dialog.dialogType = type;
dialog.setTransitionInAnimator(transition);
dialog.setTransitionOutAnimator(transition);
dialog.lastCommandPressed = null;
if(cmds != null) {
for(int iter = 0 ; iter < cmds.length ; iter++) {
dialog.addCommand(cmds[iter]);
}
}
dialog.setLayout(new BorderLayout());
dialog.addComponent(BorderLayout.CENTER, body);
if (icon != null) {
dialog.addComponent(BorderLayout.EAST, new Label(icon));
}
if (timeout != 0) {
dialog.setTimeout(timeout);
}
dialog.show();
return dialog.lastCommandPressed;
}
/**
* @inheritDoc
*/
protected void onShow() {
if (dialogType > 0) {
Display.getInstance().playDialogSound(dialogType);
}
}
/**
* The default version of show modal shows the dialog occupying the center portion
* of the screen.
*/
public void show() {
// this behavior allows a use case where dialogs of various sizes are layered
// one on top of the other
setDisposed(false);
if(top > -1) {
show(top, bottom, left, right, includeTitle, modal);
} else {
if(modal) {
super.showModal();
} else {
showModeless();
}
}
}
/**
* Shows a modeless dialog which is useful for some simpler use cases such as
* progress indication etc...
*/
public void showModeless() {
// this behavior allows a use case where dialogs of various sizes are layered
// one on top of the other
modal = false;
setDisposed(false);
if(top > -1) {
show(top, bottom, left, right, includeTitle, false);
} else {
showDialog(false);
}
}
/**
* Closes the current form and returns to the previous form, releasing the
* EDT in the process
*/
public void dispose() {
setDisposed(true);
if(!menu) {
super.dispose();
}
}
/**
* @inheritDoc
*/
public void refreshTheme() {
Container content = getContentPane();
content.refreshTheme(dialogUIID);
Style titleStyle = getTitleStyle();
if (titleStyle.isModified()) {
titleStyle.merge(UIManager.getInstance().getComponentStyle(dialogTitleUIID));
} else {
setTitleStyle(UIManager.getInstance().getComponentStyle(dialogTitleUIID));
}
int size = content.getComponentCount();
for (int i = 0; i < size; i++) {
Component cmp = content.getComponentAt(i);
cmp.refreshTheme();
}
}
/**
* Shows a modal dialog and returns the command pressed within the modal dialog
*
* @return last command pressed in the modal dialog
*/
public Command showDialog() {
lastCommandPressed = null;
show();
return lastCommandPressed;
}
/**
* Invoked to allow subclasses of form to handle a command from one point
* rather than implementing many command instances
*
* @param cmd the action command
*/
protected void actionCommand(Command cmd) {
lastCommandPressed = cmd;
if(menu || (autoDispose && cmd.isDisposesDialog())) {
dispose();
}
}
/**
* @inheritDoc
*/
public boolean animate() {
if (time != 0 && System.currentTimeMillis() >= time) {
time = 0;
dispose();
}
return false;
}
/**
* @inheritDoc
*/
protected void sizeChanged(int w, int h) {
Form frm = getPreviousForm();
while (frm instanceof Dialog) {
frm = frm.getPreviousForm();
}
frm.setSize(new Dimension(w, h));
frm.setShouldCalcPreferredSize(true);
frm.doLayout();
super.sizeChanged(w, h);
}
/**
* Indicates that this is a menu preventing getCurrent() from ever returning this class
*/
boolean isMenu() {
return menu;
}
/**
* Indicates that this is a menu preventing getCurrent() from ever returning this class
*/
void setMenu(boolean menu) {
this.menu = menu;
}
/**
* Prevent a menu from adding the select button
*/
void addSelectCommand() {
if (!menu) {
super.addSelectCommand();
}
}
/**
* Allows us to indicate disposed state for dialogs
*/
boolean isDisposed() {
return disposed;
}
/**
* Allows us to indicate disposed state for dialogs
*/
void setDisposed(boolean disposed) {
this.disposed = disposed;
}
/**
* Determins whether the execution of a command on this dialog implicitly
* disposes the dialog. This defaults to true which is a sensible default for
* simple dialogs.
*/
public boolean isAutoDispose() {
return autoDispose;
}
/**
* Determins whether the execution of a command on this dialog implicitly
* disposes the dialog. This defaults to true which is a sensible default for
* simple dialogs.
*/
public void setAutoDispose(boolean autoDispose) {
this.autoDispose = autoDispose;
}
}