Dialog.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:41k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit;
  26. import com.sun.lwuit.animations.Transition;
  27. import com.sun.lwuit.geom.Dimension;
  28. import com.sun.lwuit.layouts.BorderLayout;
  29. import com.sun.lwuit.plaf.LookAndFeel;
  30. import com.sun.lwuit.plaf.Style;
  31. import com.sun.lwuit.plaf.UIManager;
  32. import java.util.Hashtable;
  33. /**
  34.  * A dialog is a form that occupies a part of the screen and appears as a modal
  35.  * entity to the developer. Dialogs allow us to prompt users for information and
  36.  * rely on the information being available on the next line after the show method.
  37.  * <p>Modality indicates that a dialog will block the calling thread even if the
  38.  * calling thread is the EDT. Notice that a dialog will not release the block
  39.  * until dispose is called even if show() from another form is called!
  40.  * <p>To determine the size of the dialog use the show method that accepts 4 integer
  41.  * values, notice that these values accept margin from the four sides rather than x, y, width
  42.  * and height values!
  43.  * <p>To style the dialog you would usually want to style the content pane rather than
  44.  * the dialog itself.
  45.  *
  46.  * @author Shai Almog
  47.  */
  48. public class Dialog extends Form {
  49.     /**
  50.      * Indicates whether the dialog has been disposed
  51.      */
  52.     private boolean disposed;
  53.     
  54.     /**
  55.      * Constant indicating the type of alert to indicate the sound to play or
  56.      * icon if none are explicitly set
  57.      */
  58.     public static final int TYPE_ALARM = 1;
  59.     /**
  60.      * Constant indicating the type of alert to indicate the sound to play or
  61.      * icon if none are explicitly set
  62.      */
  63.     public static final int TYPE_CONFIRMATION = 2;
  64.     /**
  65.      * Constant indicating the type of alert to indicate the sound to play or
  66.      * icon if none are explicitly set
  67.      */
  68.     public static final int TYPE_ERROR = 3;
  69.     /**
  70.      * Constant indicating the type of alert to indicate the sound to play or
  71.      * icon if none are explicitly set
  72.      */
  73.     public static final int TYPE_INFO = 4;
  74.     /**
  75.      * Constant indicating the type of alert to indicate the sound to play or
  76.      * icon if none are explicitly set
  77.      */
  78.     public static final int TYPE_WARNING = 5;
  79.     /**
  80.      * Indicates the time in which the alert should be disposed
  81.      */
  82.     private long time;
  83.     /**
  84.      * Indicates the last command selected by the user in this form
  85.      */
  86.     private Command lastCommandPressed;
  87.     /**
  88.      * Indicates that this is a menu preventing getCurrent() from ever returning this class
  89.      */
  90.     private boolean menu;
  91.     private String dialogUIID;
  92.     private String dialogTitleUIID;
  93.     private int dialogType;
  94.     private int top = -1;
  95.     private int bottom;
  96.     private int left;
  97.     private int right;
  98.     private boolean includeTitle;
  99.     private String position;
  100.     /**
  101.      * Indicates whether LWUIT should try to automatically adjust a showing dialog size
  102.      * when a screen size change event occurs
  103.      */
  104.     private static boolean autoAdjustDialogSize = true;
  105.     /**
  106.      * Default screen orientation position for the upcoming dialog. By default
  107.      * the dialog will be shown at hardcoded coordinates, this method allows us 
  108.      * to pack the dialog appropriately in one of the border layout based locations
  109.      * see BorderLayout for futher details.
  110.      */
  111.     private static String defaultDialogPosition;
  112.     /**
  113.      * Allows a developer to indicate his interest that the dialog should no longer
  114.      * scroll on its own but rather rely on the scrolling properties of internal 
  115.      * scrollable containers. This flag only affects the static show methods within
  116.      * this class.
  117.      */
  118.     private static boolean disableStaticDialogScrolling;
  119.     /**
  120.      * Determines whether the execution of a command on this dialog implicitly 
  121.      * disposes the dialog. This defaults to true which is a sensible default for
  122.      * simple dialogs.
  123.      */
  124.     private boolean autoDispose = true;
  125.     private boolean modal = true;
  126.     /**
  127.      * The default type for dialogs
  128.      */
  129.     private static int defaultDialogType = TYPE_INFO;
  130.     
  131.     /**
  132.      * Places commands as buttons at the bottom of the standard static dialogs rather than
  133.      * as softbuttons. This is especially appropriate for devices such as touch devices and
  134.      * devices without the common softbuttons (e.g. blackberries). 
  135.      * The default value is false
  136.      */
  137.     private static boolean commandsAsButtons;
  138.     private boolean disposeWhenPointerOutOfBounds = false;
  139.     /**
  140.      * Constructs a Dialog with a title
  141.      * 
  142.      * @param title the title of the dialog
  143.      */
  144.     public Dialog(String title) {
  145.         this();
  146.         setTitle(title);
  147.     }
  148.     /**
  149.      * Constructs a Dialog with a title
  150.      * 
  151.      */
  152.     public Dialog() {
  153.         this("Dialog", "DialogTitle");
  154.     }
  155.     Dialog(String dialogUIID, String dialogTitleUIID) {
  156.         super();
  157.         this.dialogUIID = dialogUIID;
  158.         this.dialogTitleUIID = dialogTitleUIID;
  159.         getContentPane().setUIID(dialogUIID);
  160.         getTitleComponent().setUIID(dialogTitleUIID);
  161.         super.getStyle().setBgTransparency(0);
  162.         super.getStyle().setBgImage(null);
  163.         setSmoothScrolling(false);
  164.         deregisterAnimated(this);
  165.     }
  166.     
  167.     /**
  168.      * Simple setter to set the Dialog Style
  169.      * 
  170.      * @param style
  171.      */
  172.     public void setDialogStyle(Style style){
  173.         getContentPane().setUnSelectedStyle(style);
  174.     }
  175.     /**
  176.      * Simple getter to get the Dialog Style
  177.      * 
  178.      * @return the style of the dialog
  179.      */
  180.     public Style getDialogStyle(){
  181.         return getContentPane().getStyle();
  182.     }
  183.     /**
  184.      * Initialize the default transition for the dialogs overriding the forms
  185.      * transition
  186.      * 
  187.      * @param laf the default transition for the dialog
  188.      */
  189.     void initLaf(LookAndFeel laf) {
  190.         setTransitionOutAnimator(laf.getDefaultDialogTransitionOut());
  191.         setTransitionInAnimator(laf.getDefaultDialogTransitionIn());
  192.     }
  193.     /**
  194.      * This method shows the form as a modal alert allowing us to produce a behavior
  195.      * of an alert/dialog box. This method will block the calling thread even if the
  196.      * calling thread is the EDT. Notice that this method will not release the block
  197.      * until dispose is called even if show() from another form is called!
  198.      * <p>Modal dialogs Allow the forms "content" to "hang in mid air" this is especially useful for
  199.      * dialogs where you would want the underlying form to "peek" from behind the 
  200.      * form. 
  201.      * 
  202.      * @param top space in pixels between the top of the screen and the form
  203.      * @param bottom space in pixels between the bottom of the screen and the form
  204.      * @param left space in pixels between the left of the screen and the form
  205.      * @param right space in pixels between the right of the screen and the form
  206.      * @param includeTitle whether the title should hang in the top of the screen or
  207.      * be glued onto the content pane
  208.      * @return the last command pressed by the user if such a command exists
  209.      */
  210.     public Command show(int top, int bottom, int left, int right, boolean includeTitle) {
  211.         return show(top, bottom, left, right, includeTitle, true);
  212.     }
  213.     /**
  214.      * This method shows the form as a modal alert allowing us to produce a behavior
  215.      * of an alert/dialog box. This method will block the calling thread even if the
  216.      * calling thread is the EDT. Notice that this method will not release the block
  217.      * until dispose is called even if show() from another form is called!
  218.      * <p>Modal dialogs Allow the forms "content" to "hang in mid air" this is especially useful for
  219.      * dialogs where you would want the underlying form to "peek" from behind the 
  220.      * form. 
  221.      * 
  222.      * @param top space in pixels between the top of the screen and the form
  223.      * @param bottom space in pixels between the bottom of the screen and the form
  224.      * @param left space in pixels between the left of the screen and the form
  225.      * @param right space in pixels between the right of the screen and the form
  226.      * @param includeTitle whether the title should hang in the top of the screen or
  227.      * be glued onto the content pane
  228.      * @param modal indicates the dialog should be modal set to false for modeless dialog
  229.      * which is useful for some use cases
  230.      * @return the last command pressed by the user if such a command exists
  231.      */
  232.     public Command show(int top, int bottom, int left, int right, boolean includeTitle, boolean modal) {
  233.         this.top = top;
  234.         this.bottom = bottom;
  235.         if(isRTL()){
  236.             this.left = right;
  237.             this.right = left;            
  238.         }else{
  239.             this.left = left;
  240.             this.right = right;
  241.         }
  242.         this.includeTitle = includeTitle;
  243.         setDisposed(false);
  244.         this.modal = modal;
  245.         lastCommandPressed = null;
  246.         super.showModal(this.top, this.bottom, this.left, this.right, includeTitle, modal, false);
  247.         return lastCommandPressed;
  248.     }
  249.     /**
  250.      * Indicates the time (in milliseconds) afterwhich the dialog will be disposed 
  251.      * implicitly
  252.      * 
  253.      * @param time a milliseconds time used to dispose the dialog
  254.      */
  255.     public void setTimeout(long time) {
  256.         this.time = System.currentTimeMillis() + time;
  257.         super.registerAnimatedInternal(this);
  258.     }
  259.     /**
  260.      * Shows a modal prompt dialog with the given title and text.
  261.      * 
  262.      * @param title The title for the dialog optionally null;
  263.      * @param text the text displayed in the dialog
  264.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  265.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  266.      * @param icon the icon for the dialog, can be null
  267.      * @param okText the text to appear in the command dismissing the dialog
  268.      * @param cancelText optionally null for a text to appear in the cancel command
  269.      * for canceling the dialog
  270.      * @return true if the ok command was pressed or if cancelText is null. False otherwise.
  271.      */
  272.     public static boolean show(String title, String text, int type, Image icon, String okText, String cancelText) {
  273.         return show(title, text, type, icon, okText, cancelText, 0);
  274.     }
  275.     /**
  276.      * @inheritDoc
  277.      */
  278.     void sizeChangedInternal(int w, int h) {
  279.         if(autoAdjustDialogSize) {
  280.             // if the dialog is packed we can scale it far more accurately based on intention
  281.             if(position != null) {
  282.                 Component contentPane = getContentPane();
  283.                 Component title = getTitleComponent();
  284.                 Style contentPaneStyle = contentPane.getStyle();
  285.                 Style titleStyle = title.getStyle();
  286.                 int menuHeight = 0;
  287.                 if(getSoftButtonCount() > 1) {
  288.                     Component menuBar = getSoftButton(0).getParent();
  289.                     Style menuStyle = menuBar.getStyle();
  290.                     menuHeight = menuBar.getPreferredH() + menuStyle.getMargin(false, TOP) + menuStyle.getMargin(false, BOTTOM);
  291.                 }
  292.                 int prefHeight = contentPane.getPreferredH() + contentPaneStyle.getMargin(false, TOP) + contentPaneStyle.getMargin(false, BOTTOM);
  293.                 int prefWidth = contentPane.getPreferredW() + contentPaneStyle.getMargin(isRTL(), LEFT) + contentPaneStyle.getMargin(isRTL(), RIGHT);
  294.                 prefWidth = Math.min(prefWidth, w);
  295.                 h = h - menuHeight - title.getPreferredH() - titleStyle.getMargin(false, TOP) - titleStyle.getMargin(false, BOTTOM);
  296.                 int topBottom = Math.max(0, (h - prefHeight) / 2);
  297.                 int leftRight = Math.max(0, (w - prefWidth) / 2);
  298.                 int top = topBottom, bottom = topBottom;
  299.                 int left = leftRight, right = leftRight;
  300.                 if(position.equals(BorderLayout.EAST)) {
  301.                     left = Math.max(0, w - prefWidth);
  302.                     right = 0;
  303.                 } else {
  304.                     if(position.equals(BorderLayout.WEST)) {
  305.                         right = 0;
  306.                         left = Math.max(0, w - prefWidth);
  307.                     } else {
  308.                         if(position.equals(BorderLayout.NORTH)) {
  309.                             top = 0;
  310.                             bottom = Math.max(0, h - prefHeight);
  311.                         } else {
  312.                             if(position.equals(BorderLayout.SOUTH)) {
  313.                                 top = Math.max(0, h - prefHeight);
  314.                                 bottom = 0;
  315.                             }
  316.                         }
  317.                     }
  318.                 }
  319.                 Style contentStyle = getDialogStyle();
  320.                 if (includeTitle) {
  321.                     titleStyle.setMargin(Component.TOP, top, true);
  322.                     titleStyle.setMargin(Component.BOTTOM, 0, true);
  323.                     titleStyle.setMargin(Component.LEFT, left, true);
  324.                     titleStyle.setMargin(Component.RIGHT, right, true);
  325.                     contentStyle.setMargin(Component.TOP, 0, true);
  326.                     contentStyle.setMargin(Component.BOTTOM, bottom, true);
  327.                     contentStyle.setMargin(Component.LEFT, left, true);
  328.                     contentStyle.setMargin(Component.RIGHT, right, true);
  329.                 } else {
  330.                     titleStyle.setMargin(Component.TOP, 0, true);
  331.                     titleStyle.setMargin(Component.BOTTOM, 0, true);
  332.                     titleStyle.setMargin(Component.LEFT, 0, true);
  333.                     titleStyle.setMargin(Component.RIGHT, 0, true);
  334.                     contentStyle.setMargin(Component.TOP, top, true);
  335.                     contentStyle.setMargin(Component.BOTTOM, bottom, true);
  336.                     contentStyle.setMargin(Component.LEFT, left, true);
  337.                     contentStyle.setMargin(Component.RIGHT, right, true);
  338.                 }
  339.             } else {
  340.                 int oldW = getWidth();
  341.                 int oldH = getHeight();
  342.                 if(oldW != w || oldH != h) {
  343.                     float ratioW = ((float)w) / ((float)oldW);
  344.                     float ratioH = ((float)h) / ((float)oldH);
  345.                     Style s = getDialogStyle();
  346.                     s.setMargin(TOP, (int)(s.getMargin(false, TOP) * ratioH));
  347.                     s.setMargin(BOTTOM, (int)(s.getMargin(false, BOTTOM) * ratioH));
  348.                     s.setMargin(LEFT, (int)(s.getMargin(isRTL(), LEFT) * ratioW));
  349.                     s.setMargin(RIGHT, (int)(s.getMargin(isRTL(), RIGHT) * ratioW));
  350.                     Style titleStyle = getTitleStyle();
  351.                     titleStyle.setMargin(TOP, (int)(titleStyle.getMargin(false, TOP) * ratioH));
  352.                     titleStyle.setMargin(LEFT, (int)(titleStyle.getMargin(isRTL(), LEFT) * ratioW));
  353.                     titleStyle.setMargin(RIGHT, (int)(titleStyle.getMargin(isRTL(), RIGHT) * ratioW));
  354.                 }
  355.             }
  356.         }
  357.         
  358.         top = -1;
  359.         bottom = -1;
  360.         left = -1;
  361.         right = -1;
  362.         position = null;
  363.         super.sizeChangedInternal(w, h);
  364.         Form frm = getPreviousForm();
  365.         if(frm != null){
  366.             frm.sizeChangedInternal(w, h);
  367.         }        
  368.     }
  369.     /**
  370.      * Shows a modal prompt dialog with the given title and text.
  371.      * 
  372.      * @param title The title for the dialog optionally null;
  373.      * @param text the text displayed in the dialog
  374.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  375.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  376.      * @param icon the icon for the dialog, can be null
  377.      * @param okText the text to appear in the command dismissing the dialog
  378.      * @param cancelText optionally null for a text to appear in the cancel command
  379.      * for canceling the dialog
  380.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  381.      * @return true if the ok command was pressed or if cancelText is null. False otherwise.
  382.      */
  383.     public static boolean show(String title, String text, int type, Image icon, String okText, String cancelText, long timeout) {
  384.         Command[] cmds;
  385.         Command okCommand = new Command(okText);
  386.         if (cancelText != null) {
  387.             cmds = new Command[]{new Command(cancelText), okCommand};
  388.         } else {
  389.             cmds = new Command[]{okCommand};
  390.         }
  391.         return show(title, text, okCommand, cmds, type, icon, timeout) == okCommand;
  392.     }
  393.     /**
  394.      * Shows a modal prompt dialog with the given title and text.
  395.      * 
  396.      * @param title The title for the dialog optionally null;
  397.      * @param text the text displayed in the dialog
  398.      * @param cmds commands that are added to the form any click on any command
  399.      * will dispose the form
  400.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  401.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  402.      * @param icon the icon for the dialog, can be null
  403.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  404.      * @return the command pressed by the user
  405.      */
  406.     public static Command show(String title, String text, Command[] cmds, int type, Image icon, long timeout) {
  407.         return show(title, text, null, cmds, type, icon, timeout);
  408.     }
  409.     /**
  410.      * Shows a modal prompt dialog with the given title and text.
  411.      * 
  412.      * @param title The title for the dialog optionally null;
  413.      * @param text the text displayed in the dialog
  414.      * @param defaultCommand command to be assigned as the default command or null
  415.      * @param cmds commands that are added to the form any click on any command
  416.      * will dispose the form
  417.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  418.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  419.      * @param icon the icon for the dialog, can be null
  420.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  421.      * @return the command pressed by the user
  422.      */
  423.     public static Command show(String title, String text, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout) {
  424.         return show(title, text, defaultCommand, cmds, type, icon, timeout, null);
  425.     }
  426.     /**
  427.      * Shows a modal prompt dialog with the given title and text.
  428.      * 
  429.      * @param title The title for the dialog optionally null;
  430.      * @param text the text displayed in the dialog
  431.      * @param cmds commands that are added to the form any click on any command
  432.      * will dispose the form
  433.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  434.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  435.      * @param icon the icon for the dialog, can be null
  436.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  437.      * @param transition the transition installed when the dialog enters/leaves
  438.      * @return the command pressed by the user
  439.      */
  440.     public static Command show(String title, String text, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
  441.         return show(title, text, null, cmds, type, icon, timeout, transition);
  442.     }
  443.     /**
  444.      * Shows a modal prompt dialog with the given title and text.
  445.      * 
  446.      * @param title The title for the dialog optionally null;
  447.      * @param text the text displayed in the dialog
  448.      * @param defaultCommand command to be assigned as the default command or null
  449.      * @param cmds commands that are added to the form any click on any command
  450.      * will dispose the form
  451.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  452.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  453.      * @param icon the icon for the dialog, can be null
  454.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  455.      * @param transition the transition installed when the dialog enters/leaves
  456.      * @return the command pressed by the user
  457.      */
  458.     public static Command show(String title, String text, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
  459.         Hashtable h =  UIManager.getInstance().getResourceBundle();
  460.         if(h != null && text != null) {
  461.             Object o = h.get(text);
  462.             if(o != null) {
  463.                 text = (String)o;
  464.             }
  465.         } 
  466.         TextArea t = new TextArea(text, 3, 30);
  467.         t.setUnselectedStyle(UIManager.getInstance().getComponentStyle("DialogBody"));
  468.         t.setSelectedStyle(UIManager.getInstance().getComponentSelectedStyle("DialogBody"));
  469.         t.setEditable(false);
  470.         return show(title, t, defaultCommand, cmds, type, icon, timeout, transition);
  471.     }
  472.     /**
  473.      * Shows a modal prompt dialog with the given title and text.
  474.      * 
  475.      * @param title The title for the dialog optionally null;
  476.      * @param text the text displayed in the dialog
  477.      * @param okText the text to appear in the command dismissing the dialog
  478.      * @param cancelText optionally null for a text to appear in the cancel command
  479.      * for canceling the dialog
  480.      * @return true if the ok command was pressed or if cancelText is null. False otherwise.
  481.      */
  482.     public static boolean show(String title, String text, String okText, String cancelText) {
  483.         return show(title, text, defaultDialogType, null, okText, cancelText);
  484.     }
  485.     /**
  486.      * Shows a modal dialog with the given component as its "body" placed in the
  487.      * center. 
  488.      * 
  489.      * @param title title for the dialog
  490.      * @param body component placed in the center of the dialog
  491.      * @param cmds commands that are added to the form any click on any command
  492.      * will dispose the form
  493.      * @return the command pressed by the user
  494.      */
  495.     public static Command show(String title, Component body, Command[] cmds) {
  496.         return show(title, body, cmds, defaultDialogType, null);
  497.     }
  498.     /**
  499.      * Shows a modal dialog with the given component as its "body" placed in the
  500.      * center. 
  501.      * 
  502.      * @param title title for the dialog
  503.      * @param body component placed in the center of the dialog
  504.      * @param cmds commands that are added to the form any click on any command
  505.      * will dispose the form
  506.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  507.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  508.      * @param icon the icon for the dialog, can be null
  509.      * @return the command pressed by the user
  510.      */
  511.     public static Command show(String title, Component body, Command[] cmds, int type, Image icon) {
  512.         return show(title, body, cmds, type, icon, 0);
  513.     }
  514.     /**
  515.      * Shows a modal dialog with the given component as its "body" placed in the
  516.      * center. 
  517.      * 
  518.      * @param title title for the dialog
  519.      * @param body component placed in the center of the dialog
  520.      * @param cmds commands that are added to the form any click on any command
  521.      * will dispose the form
  522.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  523.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  524.      * @param icon the icon for the dialog, can be null
  525.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  526.      * @return the command pressed by the user
  527.      */
  528.     public static Command show(String title, Component body, Command[] cmds, final int type, Image icon, long timeout) {
  529.         return show(title, body, cmds, type, icon, timeout, null);
  530.     }
  531.     
  532.     /**
  533.      * Shows a modal dialog with the given component as its "body" placed in the
  534.      * center. 
  535.      * 
  536.      * @param title title for the dialog
  537.      * @param body component placed in the center of the dialog
  538.      * @param cmds commands that are added to the form any click on any command
  539.      * will dispose the form
  540.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  541.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  542.      * @param icon the icon for the dialog, can be null
  543.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  544.      * @param transition the transition installed when the dialog enters/leaves
  545.      * @return the command pressed by the user
  546.      */
  547.     public static Command show(String title, Component body, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
  548.         return show(title, body, null, cmds, type, icon, timeout, transition);
  549.     }
  550.     /**
  551.      * Shows a modal dialog with the given component as its "body" placed in the
  552.      * center. 
  553.      * 
  554.      * @param title title for the dialog
  555.      * @param body component placed in the center of the dialog
  556.      * @param defaultCommand command to be assigned as the default command or null
  557.      * @param cmds commands that are added to the form any click on any command
  558.      * will dispose the form
  559.      * @param type the type of the alert one of TYPE_WARNING, TYPE_INFO, 
  560.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  561.      * @param icon the icon for the dialog, can be null
  562.      * @param timeout a timeout after which null would be returned if timeout is 0 inifinite time is used
  563.      * @param transition the transition installed when the dialog enters/leaves
  564.      * @return the command pressed by the user
  565.      */
  566.     public static Command show(String title, Component body, Command defaultCommand, Command[] cmds, int type, Image icon, long timeout, Transition transition) {
  567.         Dialog dialog = new Dialog(title);
  568.         dialog.dialogType = type;
  569.         dialog.setTransitionInAnimator(transition);
  570.         dialog.setTransitionOutAnimator(transition);
  571.         dialog.lastCommandPressed = null;
  572.         dialog.setLayout(new BorderLayout());
  573.         if(cmds != null) {
  574.             if(commandsAsButtons) {
  575.                 Container buttonArea = new Container();
  576.                 dialog.addComponent(BorderLayout.SOUTH, buttonArea);
  577.                 if(cmds.length > 0) {
  578.                     for(int iter = 0 ; iter < cmds.length ; iter++) {
  579.                         buttonArea.addComponent(new Button(cmds[iter]));
  580.                     }
  581.                     buttonArea.getComponentAt(0).requestFocus();
  582.                 }
  583.             } else {
  584.                 for(int iter = 0 ; iter < cmds.length ; iter++) {
  585.                     dialog.addCommand(cmds[iter]);
  586.                 }
  587.             }
  588.             // for the special case of one command map it to the back button
  589.             if(cmds.length == 1) {
  590.                 dialog.setBackCommand(cmds[0]);
  591.             } else {
  592.                 // map two commands to fire and back
  593.                 if(cmds.length == 2 && defaultCommand == null) {
  594.                     defaultCommand = cmds[0];
  595.                     dialog.setBackCommand(cmds[1]);
  596.                 }
  597.             }
  598.         }
  599.         dialog.addComponent(BorderLayout.CENTER, body);
  600.         if (icon != null) {
  601.             dialog.addComponent(BorderLayout.EAST, new Label(icon));
  602.         }
  603.         if (timeout != 0) {
  604.             dialog.setTimeout(timeout);
  605.         }
  606.         if(body.isScrollable() || disableStaticDialogScrolling){
  607.             dialog.setScrollable(false);
  608.         }
  609.         dialog.show();
  610.         return dialog.lastCommandPressed;
  611.     }
  612.     
  613.     /**
  614.      * @inheritDoc
  615.      */
  616.     protected void onShow() {
  617.         if (dialogType > 0) {
  618.             Display.getInstance().playDialogSound(dialogType);
  619.         }
  620.     }
  621.     
  622.     /**
  623.      * @inheritDoc
  624.      */
  625.     public void showBack() {
  626.         showImpl(true);
  627.     }
  628.     /**
  629.      * The default version of show modal shows the dialog occupying the center portion
  630.      * of the screen.
  631.      */
  632.     public void show() {
  633.         showImpl(false);
  634.     }
  635.     /**
  636.      * The default version of show modal shows the dialog occupying the center portion
  637.      * of the screen.
  638.      */
  639.     private void showImpl(boolean reverse) {
  640.         // this behavior allows a use case where dialogs of various sizes are layered
  641.         // one on top of the other
  642.         setDisposed(false);
  643.         if(top > -1) {
  644.             show(top, bottom, left, right, includeTitle, modal);
  645.         } else {
  646.             if(modal) {
  647.                 if(defaultDialogPosition == null) {
  648.                     super.showModal(reverse);
  649.                 } else {
  650.                     showPacked(defaultDialogPosition, true);
  651.                 }
  652.             } else {
  653.                 showModeless();
  654.             }
  655.         }
  656.     }
  657.     /**
  658.      * Shows a modeless dialog which is useful for some simpler use cases such as
  659.      * progress indication etc...
  660.      */
  661.     public void showModeless() {
  662.         // this behavior allows a use case where dialogs of various sizes are layered 
  663.         // one on top of the other
  664.         modal = false;
  665.         setDisposed(false);
  666.         if(top > -1) {
  667.             show(top, bottom, left, right, includeTitle, false);
  668.         } else {
  669.             if(defaultDialogPosition == null) {
  670.                 showDialog(false, false);
  671.             } else {
  672.                 showPacked(defaultDialogPosition, false);
  673.             }
  674.         }
  675.     }
  676.     
  677.     /**
  678.      * Convenience method to show a dialog sized to match its content.
  679.      * 
  680.      * @param position one of the values from the BorderLayout class e.g. BorderLayout.CENTER, BorderLayout.NORTH etc.
  681.      * @param modal whether the dialog should be modal or modaless
  682.      * @return the command selected if the dialog is modal and disposed via a command
  683.      */
  684.     public Command showPacked(String position, boolean modal) {
  685.         this.position = position;
  686.         int height = Display.getInstance().getDisplayHeight();
  687.         int width = Display.getInstance().getDisplayWidth();
  688.         if(top > -1){
  689.             refreshTheme();
  690.         }
  691.         Component contentPane = getContentPane();
  692.         Component title = getTitleComponent();
  693.         
  694.         Style contentPaneStyle = contentPane.getStyle();
  695.         Style titleStyle = title.getStyle();
  696.         
  697.         int menuHeight = 0;
  698.         if(getSoftButtonCount() > 1) {
  699.             Component menuBar = getSoftButton(0).getParent();
  700.             Style menuStyle = menuBar.getStyle();
  701.             menuHeight = menuBar.getPreferredH() + menuStyle.getMargin(false, TOP) + menuStyle.getMargin(false, BOTTOM);
  702.         }
  703.         int prefHeight = contentPane.getPreferredH() + contentPaneStyle.getMargin(false, TOP) + contentPaneStyle.getMargin(false, BOTTOM);
  704.         int prefWidth = contentPane.getPreferredW() + contentPaneStyle.getMargin(isRTL(), LEFT) + contentPaneStyle.getMargin(isRTL(), RIGHT);
  705.         prefWidth = Math.min(prefWidth, width);
  706.         height = height - menuHeight - title.getPreferredH() - titleStyle.getMargin(false, TOP) - titleStyle.getMargin(false, BOTTOM);
  707.         int topBottom = Math.max(0, (height - prefHeight) / 2);
  708.         int leftRight = Math.max(0, (width - prefWidth) / 2);
  709.         
  710.         if(position.equals(BorderLayout.CENTER)) {
  711.             show(topBottom, topBottom, leftRight, leftRight, true, modal);
  712.             return lastCommandPressed;
  713.         } 
  714.         if(position.equals(BorderLayout.EAST)) {
  715.             show(topBottom, topBottom, Math.max(0, width - prefWidth), 0, true, modal);
  716.             return lastCommandPressed;
  717.         } 
  718.         if(position.equals(BorderLayout.WEST)) {
  719.             show(topBottom, topBottom, 0, Math.max(0, width - prefWidth), true, modal);
  720.             return lastCommandPressed;
  721.         } 
  722.         if(position.equals(BorderLayout.NORTH)) {
  723.             show(0, Math.max(0, height - prefHeight), leftRight, leftRight, true, modal);
  724.             return lastCommandPressed;
  725.         } 
  726.         if(position.equals(BorderLayout.SOUTH)) {
  727.             show(Math.max(0, height - prefHeight), 0, leftRight, leftRight, true, modal);
  728.             return lastCommandPressed;
  729.         } 
  730.         throw new IllegalArgumentException("Unknown position: " + position);
  731.     }
  732.     /**
  733.      * Closes the current form and returns to the previous form, releasing the 
  734.      * EDT in the process 
  735.      */
  736.     public void dispose() {
  737.         setDisposed(true);
  738.         // the dispose parent method might send us back to the form while the command
  739.         // within the dialog might be directing us to another form causing a "blip"
  740.         if(!menu) {
  741.             super.dispose();
  742.         }
  743.     }
  744.     /**
  745.      * Shows a modal dialog and returns the command pressed within the modal dialog
  746.      * 
  747.      * @return last command pressed in the modal dialog
  748.      */
  749.     public Command showDialog() {
  750.         lastCommandPressed = null;
  751.         show();
  752.         return lastCommandPressed;
  753.     }
  754.     
  755.     /**
  756.      * Invoked to allow subclasses of form to handle a command from one point
  757.      * rather than implementing many command instances
  758.      * 
  759.      * @param cmd the action command
  760.      */
  761.     protected void actionCommand(Command cmd) {
  762.         // this is important... In a case of nested dialogs based on commands/events a command might be
  763.         // blocked by a different dialog, so when that dialog is disposed (as a result of a command) going
  764.         // back to this dialog will block that command from proceeding and it can be fired again later
  765.         // E.g.:
  766.         // Dialog A has a command which triggers dialog B on top.
  767.         // User presses Cancel in dialog B
  768.         // Dialog A is shown as a result of dialog B dispose method
  769.         // Cancel command event firing is blocked since the dialog B dispose method is now blocking on dialog A show()...
  770.         // When dialog A is disposed using the OK command the OK command is sent correctly and causes dispose
  771.         // EDT is released which also releases the Cancel for dialog B to keep processing...
  772.         // Cancel for dialog B proceeds in the event chain reaching this method....
  773.         // lastCommandPressed can be overrwritten if this check isn't made!!!
  774.         if(!autoDispose || lastCommandPressed == null) {
  775.             lastCommandPressed = cmd;
  776.         }
  777.         if(menu || (autoDispose && cmd.isDisposesDialog())) {
  778.             dispose();
  779.         }
  780.     }
  781.     /**
  782.      * @inheritDoc
  783.      */
  784.     public boolean animate() {
  785.         isTimedOut();
  786.         return false;
  787.     }
  788.     private boolean isTimedOut(){
  789.         if (time != 0 && System.currentTimeMillis() >= time) {
  790.             time = 0;
  791.             dispose();
  792.             deregisterAnimatedInternal(this);
  793.             return true;
  794.         }
  795.         return false;
  796.     }
  797.     /**
  798.      * Indicates that this is a menu preventing getCurrent() from ever returning this class
  799.      */
  800.     boolean isMenu() {
  801.         return menu;
  802.     }
  803.     /**
  804.      * Indicates that this is a menu preventing getCurrent() from ever returning this class
  805.      */
  806.     void setMenu(boolean menu) {
  807.         this.menu = menu;
  808.     }
  809.     /**
  810.      * Prevent a menu from adding the select button
  811.      */
  812.     void addSelectCommand() {
  813.         if (!menu) {
  814.             super.addSelectCommand(getSelectCommandText());
  815.         }
  816.     }
  817.     
  818.     /**
  819.      * Allows us to indicate disposed state for dialogs
  820.      */
  821.     boolean isDisposed() {
  822.         return disposed || isTimedOut();
  823.     }
  824.     /**
  825.      * Allows us to indicate disposed state for dialogs
  826.      */
  827.     void setDisposed(boolean disposed) {
  828.         this.disposed = disposed;
  829.     }
  830.     /**
  831.      * Determines whether the execution of a command on this dialog implicitly 
  832.      * disposes the dialog. This defaults to true which is a sensible default for
  833.      * simple dialogs.
  834.      * 
  835.      * @return true if this dialog disposes on any command
  836.      */
  837.     public boolean isAutoDispose() {
  838.         return autoDispose;
  839.     }
  840.     /**
  841.      * Determines whether the execution of a command on this dialog implicitly 
  842.      * disposes the dialog. This defaults to true which is a sensible default for
  843.      * simple dialogs.
  844.      * 
  845.      * @param autoDispose true if this dialog disposes on any command
  846.      */
  847.     public void setAutoDispose(boolean autoDispose) {
  848.         this.autoDispose = autoDispose;
  849.     }
  850.     /**
  851.      * Default screen orientation position for the upcoming dialog. By default
  852.      * the dialog will be shown at hardcoded coordinates, this method allows us 
  853.      * to pack the dialog appropriately in one of the border layout based locations
  854.      * see BorderLayout for futher details.
  855.      * 
  856.      * @param p for dialogs on the sceen using BorderLayout orientation tags
  857.      */
  858.     public static void setDefaultDialogPosition(String p) {
  859.         defaultDialogPosition = p;
  860.     }
  861.     
  862.     /**
  863.      * Default screen orientation position for the upcoming dialog. By default
  864.      * the dialog will be shown at hardcoded coordinates, this method allows us 
  865.      * to pack the dialog appropriately in one of the border layout based locations
  866.      * see BorderLayout for futher details.
  867.      * 
  868.      * @return position for dialogs on the sceen using BorderLayout orientation tags
  869.      */
  870.     public static String getDefaultDialogPosition() {
  871.         return defaultDialogPosition;
  872.     }
  873.     /**
  874.      * The type of the dialog can be one of TYPE_WARNING, TYPE_INFO, 
  875.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  876.      * 
  877.      * @return can be one of TYPE_WARNING, TYPE_INFO, 
  878.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  879.      */
  880.     public int getDialogType() {
  881.         return dialogType;
  882.     }
  883.     /**
  884.      * The type of the dialog can be one of TYPE_WARNING, TYPE_INFO, 
  885.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  886.      * 
  887.      * @param dialogType can be one of TYPE_WARNING, TYPE_INFO, 
  888.      * TYPE_ERROR, TYPE_CONFIRMATION or TYPE_ALARM
  889.      */
  890.     public void setDialogType(int dialogType) {
  891.         this.dialogType = dialogType;
  892.     }
  893.     /**
  894.      * The default type for dialogs
  895.      * 
  896.      * @param d the default type for the dialog
  897.      */
  898.     public static void setDefaultDialogType(int d) {
  899.         defaultDialogType = d;
  900.     }
  901.     /**
  902.      * The default type for dialogs
  903.      * 
  904.      * @return the default type for the dialog
  905.      */
  906.     public static int getDefaultDialogType() {
  907.         return defaultDialogType;
  908.     }
  909.     /**
  910.      * Indicates whether LWUIT should try to automatically adjust a showing dialog size
  911.      * when a screen size change event occurs
  912.      *
  913.      * @param a true to indicate that LWUIT should make a "best effort" to resize the dialog
  914.      */
  915.     public static void setAutoAdjustDialogSize(boolean a) {
  916.         autoAdjustDialogSize = a;
  917.     }
  918.     /**
  919.      * Allows a developer to indicate his interest that the dialog should no longer
  920.      * scroll on its own but rather rely on the scrolling properties of internal
  921.      * scrollable containers. This flag only affects the static show methods within
  922.      * this class.
  923.      *
  924.      * @param d indicates whether scrolling should be active or not
  925.      */
  926.     public static void setDisableStaticDialogScrolling(boolean d) {
  927.         disableStaticDialogScrolling = d;
  928.     }
  929.     /**
  930.      * Allows a developer to indicate his interest that the dialog should no longer
  931.      * scroll on its own but rather rely on the scrolling properties of internal
  932.      * scrollable containers. This flag only affects the static show methods within
  933.      * this class.
  934.      *
  935.      * @return true if scrolling should be activated, false otherwise
  936.      */
  937.     public static boolean isDisableStaticDialogScrolling() {
  938.         return disableStaticDialogScrolling;
  939.     }
  940.     /**
  941.      * Places commands as buttons at the bottom of the standard static dialogs rather than
  942.      * as softbuttons. This is especially appropriate for devices such as touch devices and
  943.      * devices without the common softbuttons (e.g. blackberries).
  944.      * The default value is false
  945.      *
  946.      * @param commandsAsButtons true to place commands as buttons and not as softbutton keys
  947.      */
  948.     public static void setCommandsAsButtons(boolean c) {
  949.         commandsAsButtons = c;
  950.     }
  951.     /**
  952.      * Places commands as buttons at the bottom of the standard static dialogs rather than
  953.      * as softbuttons. This is especially appropriate for devices such as touch devices and
  954.      * devices without the common softbuttons (e.g. blackberries).
  955.      * The default value is false
  956.      *
  957.      * @return true if commands are placed as buttons and not as softbutton keys
  958.      */
  959.     public static boolean isCommandsAsButtons() {
  960.         return commandsAsButtons;
  961.     }
  962.     /**
  963.      * This flag indicates if the dialog should be disposed if a pointer 
  964.      * released event occurred out of the dialog content.
  965.      * 
  966.      * @param disposeWhenPointerOutOfBounds
  967.      */
  968.     protected void setDisposeWhenPointerOutOfBounds(boolean disposeWhenPointerOutOfBounds) {
  969.         this.disposeWhenPointerOutOfBounds = disposeWhenPointerOutOfBounds;
  970.     }
  971.     /**
  972.      * @inheritDoc
  973.      */
  974.     public void pointerReleased(int x, int y) {
  975.         super.pointerReleased(x, y);
  976.         if(disposeWhenPointerOutOfBounds &&
  977.                 !getTitleComponent().contains(x, y) && 
  978.                 !getContentPane().contains(x, y) && 
  979.                 !getMenuBar().contains(x, y)){
  980.             dispose();
  981.         }
  982.     }
  983.     
  984.     
  985. }