1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4   
     5  import org.aswing.ASWingUtils;
     6  import org.aswing.border.EmptyBorder;
     7  import org.aswing.BorderLayout;
     8  import org.aswing.Component;
     9  import org.aswing.FlowLayout;
    10  import org.aswing.Icon;
    11  import org.aswing.Insets;
    12  import org.aswing.JButton;
    13  import org.aswing.JFrame;
    14  import org.aswing.JLabel;
    15  import org.aswing.JPanel;
    16  import org.aswing.JTextField;
    17  import org.aswing.JWindow;
    18  import org.aswing.SoftBox;
    19  
    20  /**
    21   * JOptionPane makes it easy to pop up a standard dialog box that prompts users 
    22   * for a value or informs them of something.
    23   * <p>
    24   * There's some shortcut to do there with static methods like <code>showMessageDialog</code>, 
    25   * <code>showInputDialog</code>. But if you want to make a hole control of JOptionPane, 
    26   * you can create a JOptionPane by yourself and append it into a your JFrame.
    27   * @see #showMessageDialog()
    28   * @see #showInputDialog()
    29   * @author iiley
    30   */
    31  class org.aswing.JOptionPane extends JPanel {
    32  	public static var OK_STR:String = "OK";
    33  	public static var CANCEL_STR:String = "Cancel";
    34  	public static var YES_STR:String = "Yes";
    35  	public static var NO_STR:String = "No";
    36  	public static var CLOSE_STR:String = "Close";
    37  	
    38  	
    39  	public static var OK:Number = 1; //00001
    40  	public static var CANCEL:Number = 2; //00010
    41  	public static var YES:Number = 4; //00100
    42  	public static var NO:Number = 8; //01000
    43  	public static var CLOSE:Number = 16; //10000
    44  	
    45  	private var okButton:JButton;
    46  	private var cancelButton:JButton;
    47  	private var yesButton:JButton;
    48  	private var noButton:JButton;
    49  	private var closeButton:JButton;
    50  	
    51  	private var centerPane:JPanel;
    52  	private var msgLabel:JLabel;
    53  	private var inputText:JTextField;
    54  	private var buttonPane:JPanel;
    55  	private var frame:JFrame;
    56  	
    57  	public function JOptionPane() {
    58  		super(new BorderLayout());
    59  		centerPane = SoftBox.createVerticalBox(6);
    60  		msgLabel = new JLabel();
    61  		centerPane.append(ASWingUtils.createPaneToHold(msgLabel, new FlowLayout(FlowLayout.CENTER, 5, 5)));
    62  		inputText = new JTextField();
    63  		var inputContainer:JPanel = new JPanel(new BorderLayout());
    64  		inputContainer.setBorder(new EmptyBorder(null, new Insets(0, 8, 0, 8)));
    65  		inputContainer.append(inputText, BorderLayout.CENTER);
    66  		centerPane.append(inputContainer);
    67  		buttonPane = new JPanel(new FlowLayout(FlowLayout.CENTER));
    68  		append(centerPane, BorderLayout.CENTER);
    69  		append(buttonPane, BorderLayout.SOUTH);
    70  	}
    71  	
    72  	public function getFrame():JFrame{
    73  		return frame;
    74  	}
    75  	
    76  	public function getInputText():JTextField{
    77  		return inputText;
    78  	}
    79  	
    80  	public function getOkButton():JButton{
    81  		if(okButton == null){
    82  			okButton = new JButton(OK_STR);
    83  		}
    84  		return okButton;
    85  	}
    86  	
    87  	public function getCancelButton():JButton{
    88  		if(cancelButton == null){
    89  			cancelButton = new JButton(CANCEL_STR);
    90  		}
    91  		return cancelButton;
    92  	}	
    93  	public function getYesButton():JButton{
    94  		if(yesButton == null){
    95  			yesButton = new JButton(YES_STR);
    96  		}
    97  		return yesButton;
    98  	}
    99  	
   100  	public function getNoButton():JButton{
   101  		if(noButton == null){
   102  			noButton = new JButton(NO_STR);
   103  		}
   104  		return noButton;
   105  	}	
   106  	public function getCloseButton():JButton{
   107  		if(closeButton == null){
   108  			closeButton = new JButton(CLOSE_STR);
   109  		}
   110  		return closeButton;
   111  	}	
   112  	
   113  	private function addButton(button:JButton):Void{
   114  		buttonPane.append(button);
   115  	}
   116  	private function setMessage(msg:String):Void{
   117  		msgLabel.setText(msg);
   118  	}
   119  	private function setIcon(icon:Icon):Void{
   120  		msgLabel.setIcon(icon);
   121  	}	
   122  	private function addCloseListener(button:JButton):Void{
   123  		var f:JFrame = getFrame();
   124  		button.addActionListener(function(){ f.dispose(); });
   125  	}
   126  	
   127  	/**
   128  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, parentComponent:Component, modal:Boolean, icon:Icon, buttons:Number)<br>
   129  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, parentComponent:Component, modal:Boolean, icon:Icon)<br>
   130  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, parentComponent:Component, modal:Boolean)<br>
   131  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, parentComponent:Component)<br>
   132  	 * showMessageDialog(title:String, msg:String, finishHandler:Function)
   133  	 * <p>
   134  	 * Show a message box with specifield title, message, and icon.
   135  	 * <p>
   136  	 * for example:
   137  	 * <pre>
   138  	 * var handler:Function = Delegate.create(this, __whenUserConformed);
   139  	 * var pane:JOptionPane = showMessageDialog("title", "is that OK?", handler, null, JOptionPane.YES|JOptionPane.NO);
   140  	 * </pre>
   141  	 * will show a message box with yes and no buttons.
   142  	 * 
   143  	 * @param title the title of the box, can be null
   144  	 * @param msg the message , can be null
   145  	 * @param finishHandler the function(result:Number) to call when user finished input, 
   146  	 * will pass a number as parammeter, its value indicate what user's selection. 
   147  	 * For example CANCEL indicate that user pressed CANCEL button, CLOSE indicate that 
   148  	 * user pressed CLOSE button or just closed the frame by click frame's close button, 
   149  	 * YES indicate that user pressed the YES button etc.
   150  	 * @param parentComponent determines the Frame in which the
   151  	 *		dialog is displayed; can be null
   152  	 * @param modal is the window modal, default is true
   153  	 * @param icon the icon, can be null
   154  	 * @param buttons which buttons need to show.
   155  	 * @param closeBox is close the box frame when user click buttons
   156  	 * @see #OK
   157  	 * @see #CANCEL
   158  	 * @see #YES
   159  	 * @see #NO
   160  	 * @see #CLOSE
   161  	 */
   162  	public static function showMessageDialog(title:String, msg:String, finishHandler:Function, parentComponent:Component, modal:Boolean, icon:Icon, buttons:Number):JOptionPane{
   163  		var owner:JWindow = ASWingUtils.getWindowAncestor(parentComponent);
   164  		if(modal == undefined) modal = true;
   165  		var frame:JFrame = new JFrame(owner, title, modal);
   166  		var pane:JOptionPane = new JOptionPane();
   167  		pane.getInputText().setVisible(false);
   168  		pane.setMessage(msg);
   169  		pane.setIcon(icon);
   170  		pane.frame = frame;
   171  		if(buttons == undefined){
   172  			buttons = OK;
   173  		}
   174  		var handler:Function = finishHandler;
   175  		if((buttons & OK) == OK){
   176  			pane.addButton(pane.getOkButton());
   177  			pane.addCloseListener(pane.getOkButton());
   178  			pane.getOkButton().addActionListener(function(){
   179  				handler(JOptionPane.OK);
   180  			});
   181  		}
   182  		if((buttons & YES) == YES){
   183  			pane.addButton(pane.getYesButton());
   184  			pane.addCloseListener(pane.getYesButton());
   185  			pane.getYesButton().addActionListener(function(){
   186  				handler(JOptionPane.YES);
   187  			});
   188  		}
   189  		if((buttons & NO) == NO){
   190  			pane.addButton(pane.getNoButton());
   191  			pane.addCloseListener(pane.getNoButton());
   192  			pane.getNoButton().addActionListener(function(){
   193  				handler(JOptionPane.NO);
   194  			});
   195  		}
   196  		if((buttons & CANCEL) == CANCEL){
   197  			pane.addButton(pane.getCancelButton());
   198  			pane.addCloseListener(pane.getCancelButton());
   199  			pane.getCancelButton().addActionListener(function(){
   200  				handler(JOptionPane.CANCEL);
   201  			});
   202  		}
   203  		if((buttons & CLOSE) == CLOSE){
   204  			pane.addButton(pane.getCloseButton());
   205  			pane.addCloseListener(pane.getCloseButton());
   206  			pane.getCloseButton().addActionListener(function(){
   207  				handler(JOptionPane.CLOSE);
   208  			});
   209  		}
   210  		
   211  		frame.addEventListener(JFrame.ON_WINDOW_CLOSING, 
   212  			function(){
   213  				handler(JOptionPane.CLOSE);
   214  			});
   215  		
   216  		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
   217  		frame.setResizable(false);
   218  		frame.getContentPane().append(pane, BorderLayout.CENTER);
   219  		frame.pack();
   220  		frame.setLocation((Stage.width-frame.getWidth())/2, (Stage.height-frame.getHeight())/2);
   221  		frame.show();
   222  		return pane;
   223  	}
   224  	
   225  	/**
   226  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, defaultValue:String, parentComponent:Component, modal:Boolean, icon:Icon)<br>
   227  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, defaultValue:String, parentComponent:Component, modal:Boolean)<br>
   228  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, defaultValue:String, parentComponent:Component)<br>
   229  	 * showMessageDialog(title:String, msg:String, finishHandler:Function, defaultValue:String)<br>
   230  	 * showMessageDialog(title:String, msg:String, finishHandler:Function)
   231  	 * <p>
   232  	 * Show a message box with specifield title, message, and icon and a TextField to requare 
   233  	 * user to input a string.
   234  	 * <p>
   235  	 * for example:
   236  	 * <pre>
   237  	 * var handler:Function = Delegate.create(this, __whenUserEntered);
   238  	 * var pane:JOptionPane = showMessageDialog("title", "Please enter your name:", handler, "yournamehere");
   239  	 * </pre>
   240  	 * will show a message box with OK and CANCEL and a input Texts.
   241  	 * 
   242  	 * @param title the title of the box, can be null
   243  	 * @param msg the message , can be null
   244  	 * @param finishHandler the function(result:String) to call when user finished input, 
   245  	 * will pass a string as parammeter, if it is null indicate that user had pressed 
   246  	 * cancel or just closed the frame, otherwise it is the string what user entered.
   247  	 * @param defaultValue the default value for the input
   248  	 * @param parentComponent determines the Frame in which the
   249  			dialog is displayed; can be null
   250  	 * @param modal is the window modal, default is true
   251  	 * @param icon the icon, can be null
   252  	 */
   253  	public static function showInputDialog(title:String, msg:String, finishHandler:Function, defaultValue:String, parentComponent:Component, modal:Boolean, icon:Icon):JOptionPane{
   254  		var owner:JWindow = ASWingUtils.getWindowAncestor(parentComponent);
   255  		if(modal == undefined) modal = true;
   256  		var frame:JFrame = new JFrame(owner, title, modal);
   257  		var pane:JOptionPane = new JOptionPane();
   258  		if(defaultValue != undefined){
   259  			pane.inputText.setText(defaultValue);
   260  		}
   261  		pane.setMessage(msg);
   262  		pane.setIcon(icon);
   263  		pane.frame = frame;
   264  		
   265  		pane.addButton(pane.getOkButton());
   266  		pane.addCloseListener(pane.getOkButton());
   267  		pane.addButton(pane.getCancelButton());
   268  		pane.addCloseListener(pane.getCancelButton());
   269  		
   270  		var hander:Function = finishHandler;
   271  		
   272  		pane.getOkButton().addActionListener(
   273  			function(){
   274  				hander(pane.getInputText().getText());
   275  			}
   276  		);
   277  		
   278  		var cancelHandler:Function = function(){
   279  			hander(null);
   280  		};
   281  		
   282  		pane.getCancelButton().addActionListener(cancelHandler);
   283  		frame.addEventListener(JFrame.ON_WINDOW_CLOSING, cancelHandler);
   284  			
   285  		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
   286  		frame.setResizable(false);
   287  		frame.getContentPane().append(pane, BorderLayout.CENTER);
   288  		frame.pack();
   289  		frame.setLocation((Stage.width-frame.getWidth())/2, (Stage.height-frame.getHeight())/2);
   290  		frame.show();
   291  		return pane;
   292  	}
   293  }
   294