* Bug #8066 fixed - Add an OK button to x_choose.
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / messagebox / SwingScilabMessageBox.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent Couvert
4  * Copyright (C) 2010 - DIGITEO - Vincent Couvert
5  * Copyright (C) 2013 - Scilab Enterprises - Clement DAVID
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
12  *
13  */
14
15 package org.scilab.modules.gui.bridge.messagebox;
16
17 import java.awt.BorderLayout;
18 import java.awt.Component;
19 import java.awt.Font;
20 import java.awt.GridBagConstraints;
21 import java.awt.GridBagLayout;
22 import java.awt.Image;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.MouseEvent;
26 import java.awt.event.MouseListener;
27 import java.util.ArrayList;
28 import java.util.Enumeration;
29 import java.util.List;
30
31 import javax.swing.AbstractButton;
32 import javax.swing.Action;
33 import javax.swing.BorderFactory;
34 import javax.swing.ButtonGroup;
35 import javax.swing.DefaultListModel;
36 import javax.swing.GroupLayout;
37 import javax.swing.GroupLayout.Alignment;
38 import javax.swing.GroupLayout.ParallelGroup;
39 import javax.swing.GroupLayout.SequentialGroup;
40 import javax.swing.Icon;
41 import javax.swing.ImageIcon;
42 import javax.swing.JButton;
43 import javax.swing.JCheckBox;
44 import javax.swing.JDialog;
45 import javax.swing.JLabel;
46 import javax.swing.JList;
47 import javax.swing.JOptionPane;
48 import javax.swing.JPanel;
49 import javax.swing.JScrollPane;
50 import javax.swing.JTextArea;
51 import javax.swing.JTextField;
52 import javax.swing.JTextPane;
53 import javax.swing.JToggleButton;
54 import javax.swing.LayoutStyle.ComponentPlacement;
55 import javax.swing.ListSelectionModel;
56 import javax.swing.UIManager;
57 import javax.swing.event.HyperlinkEvent;
58 import javax.swing.event.HyperlinkListener;
59 import javax.swing.text.html.HTMLEditorKit;
60 import javax.swing.text.html.StyleSheet;
61
62 import org.scilab.modules.commons.gui.FindIconHelper;
63 import org.scilab.modules.gui.console.ScilabConsole;
64 import org.scilab.modules.gui.messagebox.SimpleMessageBox;
65 import org.scilab.modules.gui.tab.SimpleTab;
66 import org.scilab.modules.gui.tab.Tab;
67 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
68 import org.scilab.modules.gui.utils.WebBrowser;
69 import org.scilab.modules.localization.Messages;
70
71 /**
72  * Swing implementation of a Scilab MessageBox
73  * @author Vincent COUVERT
74  */
75 public class SwingScilabMessageBox extends JDialog implements SimpleMessageBox, ActionListener {
76
77     private static final long serialVersionUID = 7939976395338222763L;
78
79     private static final int X_MESSAGE_TYPE = 0;
80     private static final int X_DIALOG_TYPE = 1;
81     private static final int X_CHOOSE_TYPE = 2;
82     private static final int X_MDIALOG_TYPE = 3;
83     private static final int X_CHOICES_TYPE = 4;
84
85     /**
86      * New line character for mutli-line text components
87      */
88     private static final String NEW_LINE = "\n";
89
90     /**
91      * Separator used for x_choices
92      */
93     private static final String SEPARATOR = "[--sep--]";
94
95     /**
96      * The minimal fixed width of any mdialog inputs
97      */
98     private static final int X_MDIALOG_TEXTFIELD_SIZE = 10;
99
100     /**
101      * Icons
102      */
103     private final Icon scilabIcon = new ImageIcon(FindIconHelper.findIcon("scilab", "48x48"));
104     private final Icon passwdIcon = new ImageIcon(FindIconHelper.findIcon("emblem-readonly", "48x48"));
105     private final Icon hourglassIcon = new ImageIcon(FindIconHelper.findIcon("process-working"));
106
107     private int elementId;
108
109     private Icon messageIcon;
110
111     private int scilabDialogType = X_MESSAGE_TYPE;
112
113     private Component parentWindow;
114
115     private final JButton btnOK = new JButton(Messages.gettext("OK"));
116     private final JButton btnCancel = new JButton(Messages.gettext("Cancel"));
117
118     /**
119      * Used for x_dialog
120      */
121     private JTextArea textArea;
122     private String initialValue;
123     private int initialValueSize;
124     private String userValue;
125
126     /**
127      * Used for x_choose
128      */
129     private JList listBox;
130     private String[] listboxItems;
131     private int selectedItem;
132
133     /**
134      * Used for x_mdialog
135      */
136     private String[] lineLabels;
137     private String[] columnLabels;
138     private String[] defaultInput;
139     private Component[] textFields;
140     private String[] userValues;
141
142     /**
143      * Used for x_choose & x_message
144      */
145     private String[] buttonsLabels;
146     private int selectedButton;
147
148     /**
149      * Used for x_choices
150      */
151     private int[] defaultSelectedButtons;
152     private ButtonGroup[] buttonGroups;
153     private int[] userSelectedButtons;
154
155     /**
156      * Used for all Message Boxes
157      */
158     private String message;
159     private String title;
160     private final Image imageForIcon = ((ImageIcon) scilabIcon).getImage();
161     private int messageType = -1;
162     private Component[] objs;
163     private Object[] buttons;
164     private boolean modal = true;
165     private JCheckBox checkbox;
166
167     /**
168      * Default constructor
169      */
170     public SwingScilabMessageBox() {
171         super();
172         setIconImage(imageForIcon);
173     }
174
175     /**
176      * Set the element id for this MessageBox
177      * @param id the id of the corresponding MessageBox object
178      */
179     @Override
180     public void setElementId(int id) {
181         this.elementId = id;
182     }
183
184     /**
185      * Get the element id for MessageBox
186      * @return id the id of the corresponding MessageBox object
187      */
188     @Override
189     public int getElementId() {
190         return this.elementId;
191     }
192
193     /**
194      * Set the title of the MessageBox
195      * @param title the title to set
196      */
197     @Override
198     public void setTitle(String title) {
199         this.title = title;
200     }
201
202     /**
203      * Set the message of the MessageBox
204      * @param message the message to set
205      */
206     @Override
207     public void setMessage(String message) {
208         this.message = message;
209     }
210
211     /**
212      * Set the message of the MessageBox (multi-line)
213      * @param mess the message to set
214      */
215     @Override
216     public void setMessage(String[] mess) {
217         int line = 0;
218         message = "<HTML>";
219         for (line = 0; line < mess.length - 1; line++) {
220             message += "<div>" + mess[line] + "</div>";
221         }
222         message += mess[line] + "</HTML>";
223     }
224
225     /**
226      * Set a checkbox in the messagebox
227      * @param message text of the checkbox
228      * @param action the associated action
229      * @param checked if true the checkbox is checked
230      */
231     public void setCheckbox(String message, Action action) {
232         checkbox = new JCheckBox(action);
233         checkbox.setText(message);
234     }
235
236     /**
237      * DefaultValues
238      * Display this MessageBox and wait for user selection
239      */
240     @Override
241     public void displayAndWait() {
242         JButton defaultButton = null;
243
244         // Set the title & icon
245         //setIconImage(imageForIcon); // Not Java 1.5 compatible
246         super.setTitle(title);
247
248         // Create the message to display
249         JTextPane messageLabel = new JTextPane();
250         messageLabel.setContentType("text/html");
251         messageLabel.setOpaque(false);
252         messageLabel.setBorder(null);
253         messageLabel.setEditable(false);
254
255         // Update the stylesheet so that the font matches JLabel font
256         Font labelFont = UIManager.getFont("Label.font");
257         HTMLEditorKit editorKit = (HTMLEditorKit) messageLabel.getEditorKit();
258         StyleSheet styles = editorKit.getStyleSheet();
259         String css = "body {font-family:\"" + labelFont.getName()
260                      + "\"; font-size:\"" + labelFont.getSize() + "pt\"}";
261         styles.addRule(css);
262         editorKit.setStyleSheet(styles);
263         messageLabel.setEditorKit(editorKit);
264
265         messageLabel.setText(message);
266
267         /* Add a link to make HTML links active */
268         messageLabel.addHyperlinkListener(new HyperlinkListener() {
269             @Override
270             public void hyperlinkUpdate(HyperlinkEvent e) {
271                 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
272                     WebBrowser.openUrl(e.getURL(), e.getDescription());
273                 }
274             }
275         });
276
277         JScrollPane messageScrollPane = new JScrollPane(messageLabel);
278         // Make the scroll Pane transparent
279         messageScrollPane.setOpaque(false);
280         messageScrollPane.getViewport().setOpaque(false);
281         /* Make the Border of the ScrollPane invisible */
282         messageScrollPane.setBorder(BorderFactory.createEmptyBorder());
283         messageScrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
284
285         if (scilabDialogType == X_CHOICES_TYPE) {
286             // Create a MessageBox for Scilab x_choices
287
288             // All objects in the MessageBox:
289             //  - Message
290             //  - Editable zone
291             objs = new Component[2];
292
293             objs[0] = messageScrollPane;
294
295             // Search the max number of objects in a line
296             int curNumber = 0;
297             int numberOfLines = 0;
298             int numberOfColumns = 0;
299             List<Integer> buttonsPerLines = new ArrayList<Integer>();
300             for (int itemIndex = 0; itemIndex < lineLabels.length; itemIndex++) {
301                 if (!lineLabels[itemIndex].equals(SEPARATOR)) {
302                     curNumber++;
303                 } else {
304                     if (curNumber > numberOfColumns) {
305                         numberOfColumns = curNumber;
306                     }
307                     // Store information of current line
308                     buttonsPerLines.add(curNumber);
309                     curNumber = 0;
310                     numberOfLines++;
311                 }
312             }
313             // Store information of last line
314             // Because no separator after last line items
315             buttonsPerLines.add(curNumber);
316             numberOfLines++;
317
318             // Create the panel with button groups
319             JPanel panel = new JPanel(new GridBagLayout());
320             GridBagConstraints gbc = new GridBagConstraints();
321             gbc.gridx = 0;
322             gbc.gridy = 0;
323             gbc.fill = GridBagConstraints.HORIZONTAL;
324             buttonGroups = new ButtonGroup[numberOfLines];
325
326             // Initialize return value
327             userSelectedButtons = new int[numberOfLines];
328
329             int curItemIndex = 0;
330             int lineNumber = 0;
331             int buttonNumber = 0;
332             for (curItemIndex = 0; curItemIndex < lineLabels.length; curItemIndex++) {
333                 // Add the label of the line
334                 gbc.weightx = 1; // Labels will use remaining space when resizing
335                 panel.add(new JLabel(lineLabels[curItemIndex]), gbc);
336                 gbc.gridx++; // Increment the column index
337
338                 buttonNumber = 0;
339                 curItemIndex++;
340
341                 // Add the button group
342                 ButtonGroup group = new ButtonGroup();
343                 while (curItemIndex < lineLabels.length &&  !lineLabels[curItemIndex].equals(SEPARATOR)) {
344                     // Add a toggle button
345                     JToggleButton button = new JToggleButton(lineLabels[curItemIndex]);
346                     buttonNumber++;
347
348                     // Select this button if default
349                     if (buttonNumber == defaultSelectedButtons[lineNumber]) {
350                         button.setSelected(true);
351                     }
352                     // Select this button if default selection is a non existing button
353                     // And this button is the last of the line
354                     if (buttonNumber == (buttonsPerLines.get(lineNumber) - 1)
355                             && defaultSelectedButtons[lineNumber] > (buttonsPerLines.get(lineNumber) - 1)) {
356                         button.setSelected(true);
357                     }
358                     // Add the button to the group (for toggle)
359                     // And to the panel (for display)
360                     group.add(button);
361                     gbc.weightx = 0; // Button size will not change when resizing
362                     panel.add(button, gbc);
363                     gbc.gridx++; // Increment the column index
364
365                     // Increment item index
366                     curItemIndex++;
367
368                 }
369                 // Add empty labels if number of buttons in the line is lesser than maximum number of buttons found in a line
370                 for (int emptyLabelsIndex = buttonsPerLines.get(lineNumber); emptyLabelsIndex < numberOfColumns; emptyLabelsIndex++) {
371                     panel.add(new JLabel(), gbc);
372                     gbc.gridx++; // Increment the column index
373                 }
374
375                 // Store the group to get the user selection when returning
376                 buttonGroups[lineNumber] = group;
377
378                 // Increment current line number
379                 lineNumber++;
380                 gbc.gridx = 0; // New line --> Back to first column
381                 gbc.gridy++; // Increment the row index
382             }
383
384             // Display the panel
385             panel.doLayout();
386
387             // Editable text zone
388             JScrollPane scrollPane = new JScrollPane(panel);
389
390             objs[1] = scrollPane;
391
392             // And now the buttons
393             buttons = new Object[2];
394             btnOK.addActionListener(this);
395             btnCancel.addActionListener(this);
396             /* Test added for bug 4347 fix */
397             if (isWindows()) {
398                 buttons[0] = btnOK;
399                 buttons[1] = btnCancel;
400
401             } else {
402                 buttons[0] = btnCancel;
403                 buttons[1] = btnOK;
404             }
405             defaultButton = btnOK;
406         } else if (scilabDialogType == X_MDIALOG_TYPE) {
407             // Create a MessageBox for Scilab x_mdialog
408
409             // All objects in the MessageBox:
410             //  - Message
411             //  - Editable zone
412             objs = new Component[2];
413
414             objs[0] = messageScrollPane;
415
416             int numberOfColumns = 0;
417             if (columnLabels == null) {
418                 numberOfColumns = 2;
419             } else {
420                 numberOfColumns = columnLabels.length + 1;
421             }
422
423             // Allocate the Java Components
424             final JLabel[] colLabels;
425             final JLabel[] rowLabels;
426             if (columnLabels != null) {
427                 // Optional first line
428                 colLabels = new JLabel[columnLabels.length + 1];
429
430                 // the first column label is on top of the row label
431                 colLabels[0] = new JLabel("");
432
433                 // create the components on each column
434                 for (int col = 0; col < columnLabels.length; col++) {
435                     colLabels[col + 1] = new JLabel(columnLabels[col]);
436                 }
437             } else {
438                 // there is no first line
439                 colLabels = null;
440             }
441             rowLabels = new JLabel[lineLabels.length];
442             for (int row = 0; row < lineLabels.length; row++) {
443                 // add a gap (a space) between the column's labels and data
444                 rowLabels[row] = new JLabel(lineLabels[row] + " ");
445             }
446
447             // Prepare return value
448             if (columnLabels == null) {
449                 userValues = new String[lineLabels.length];
450                 textFields = new Component[lineLabels.length];
451             } else {
452                 userValues = new String[lineLabels.length * columnLabels.length];
453                 textFields = new Component[lineLabels.length * columnLabels.length];
454             }
455
456             // set the initial values
457             for (int line = 0; line < lineLabels.length; line++) {
458                 for (int col = 0; col < numberOfColumns - 1; col++) {
459                     final String initial = defaultInput[col * lineLabels.length + line];
460
461                     final Component c;
462                     if ("T".equalsIgnoreCase(initial)) {
463                         c = new JCheckBox();
464                         ((JCheckBox) c).setSelected(true);
465                     } else if ("F".equalsIgnoreCase(initial)) {
466                         c = new JCheckBox();
467                         ((JCheckBox) c).setSelected(false);
468                     } else {
469                         c = new JTextField(initial);
470
471                         // force an initial width when the initial text is too small
472                         if (initial.length() < X_MDIALOG_TEXTFIELD_SIZE) {
473                             ((JTextField) c).setColumns(X_MDIALOG_TEXTFIELD_SIZE);
474                         }
475                     }
476
477                     textFields[col * lineLabels.length + line] = c;
478                     rowLabels[line].setLabelFor(c);
479                 }
480             }
481
482             // Prepare the layout
483             JPanel panel = new JPanel();
484             GroupLayout layout = new GroupLayout(panel);
485             panel.setLayout(layout);
486
487             final SequentialGroup horizontalGroup = layout.createSequentialGroup().addContainerGap();
488             final SequentialGroup verticalGroup = layout.createSequentialGroup().addContainerGap();
489
490             // Horizontal layout
491             {
492                 final ParallelGroup localGroup = layout.createParallelGroup(Alignment.LEADING);
493
494                 if (colLabels != null) {
495                     localGroup.addComponent(colLabels[0]);
496                 }
497                 // special case for the row label
498                 for (int row = 0; row < lineLabels.length; row++) {
499                     localGroup.addComponent(rowLabels[row]);
500                 }
501                 horizontalGroup.addGroup(localGroup);
502                 horizontalGroup.addGap(18, 18, 18);
503             }
504             for (int col = 0 ; col < numberOfColumns - 1; col++) {
505                 if (col > 0) {
506                     horizontalGroup.addPreferredGap(ComponentPlacement.RELATED);
507                 }
508
509                 final ParallelGroup localGroup = layout.createParallelGroup(Alignment.CENTER);
510
511                 if (colLabels != null) {
512                     // center the labels to be rendered like a spreadsheet
513                     localGroup.addComponent(colLabels[col + 1]);
514                 }
515
516                 // common case for the initial values
517                 for (int row = 0; row < lineLabels.length; row++) {
518                     localGroup.addComponent(textFields[col * lineLabels.length + row]);
519                 }
520
521                 horizontalGroup.addGroup(localGroup);
522             }
523             layout.setHorizontalGroup(
524                 layout.createParallelGroup(Alignment.LEADING)
525                 .addGroup(horizontalGroup.addContainerGap()));
526
527             // Vertical layout
528             if (colLabels != null) {
529                 final ParallelGroup localGroup = layout.createParallelGroup(Alignment.BASELINE);
530                 for (int col = 0 ; col < numberOfColumns; col++) {
531                     localGroup.addComponent(colLabels[col]);
532                 }
533                 verticalGroup.addGroup(localGroup);
534                 verticalGroup.addGap(18, 18, 18);
535             }
536             for (int row = 0; row < lineLabels.length; row++) {
537                 if (row > 0) {
538                     verticalGroup.addPreferredGap(ComponentPlacement.RELATED);
539                 }
540
541                 final ParallelGroup localGroup = layout.createParallelGroup(Alignment.BASELINE);
542                 localGroup.addComponent(rowLabels[row]);
543                 for (int col = 0 ; col < numberOfColumns - 1; col++) {
544                     localGroup.addComponent(textFields[col * lineLabels.length + row]);
545                 }
546                 verticalGroup.addGroup(localGroup);
547             }
548             layout.setVerticalGroup(
549                 layout.createParallelGroup(Alignment.LEADING)
550                 .addGroup(verticalGroup.addContainerGap()));
551
552             // Editable text zone
553             JScrollPane scrollPane = new JScrollPane(panel);
554
555             objs[1] = scrollPane;
556
557             // And now the buttons
558             buttons = new Object[2];
559             btnOK.addActionListener(this);
560             btnCancel.addActionListener(this);
561             /* Test added for bug 4347 fix */
562             if (isWindows()) {
563                 buttons[0] = btnOK;
564                 buttons[1] = btnCancel;
565
566             } else {
567                 buttons[0] = btnCancel;
568                 buttons[1] = btnOK;
569             }
570             defaultButton = btnOK;
571         } else if (scilabDialogType == X_CHOOSE_TYPE) {
572             // Create a MessageBox for Scilab x_choose
573
574             // All objects in the MessageBox:
575             //  - Message
576             //  - Listbox
577             objs = new Component[2];
578
579             // Add the message
580             objs[0] = messageScrollPane;
581
582             // Add the listBox
583             objs[1] = createXchooseListBox();
584
585             // And now the buttons
586             buttons = new Object[2];
587             if (buttonsLabels != null) {
588                 btnCancel.setText(buttonsLabels[0]);
589             }
590             btnOK.addActionListener(this);
591             btnCancel.addActionListener(this);
592             buttons[0] = btnCancel;
593             buttons[1] = btnOK;
594         } else if (scilabDialogType == X_DIALOG_TYPE) {
595             // Create a MessageBox for Scilab x_dialog
596
597             // All objects in the MessageBox:
598             //  - Message
599             //  - Editable zone
600             objs = new Component[2];
601
602             objs[0] = messageScrollPane;
603
604             // Editable text zone
605             textArea = new JTextArea(initialValue);
606             textArea.setRows(initialValueSize);
607             JScrollPane scrollPane = new JScrollPane(textArea);
608
609             objs[1] = scrollPane;
610
611             // And now the buttons
612             buttons = new Object[2];
613             btnOK.addActionListener(this);
614             btnCancel.addActionListener(this);
615             /* Test added for bug 4347 fix */
616             if (isWindows()) {
617                 buttons[0] = btnOK;
618                 buttons[1] = btnCancel;
619
620             } else {
621                 buttons[0] = btnCancel;
622                 buttons[1] = btnOK;
623             }
624             defaultButton = btnOK;
625         } else {
626             // Create a MessageBox for Scilab x_message
627
628             // All objects in the MessageBox:
629             //  - Message
630             int nb = checkbox == null ? 1 : 2;
631             objs = new Component[nb];
632
633             // Add the message
634             objs[0] = messageScrollPane;
635             if (nb == 2) {
636                 objs[1] = checkbox;
637             }
638
639             // And now the buttons
640             if (buttonsLabels == null) {
641                 buttons = new Object[1];
642                 btnOK.addActionListener(this);
643                 buttons[0] = btnOK;
644                 defaultButton = btnOK;
645                 //messageType = JOptionPane.INFORMATION_MESSAGE;
646             } else {
647                 buttons = new Object[buttonsLabels.length];
648                 for (int buttonNb = 0; buttonNb < buttonsLabels.length; buttonNb++) {
649                     JButton currentButton = new JButton(buttonsLabels[buttonNb]);
650                     currentButton.addActionListener(this);
651                     if (buttonNb == 0) {
652                         defaultButton = currentButton;
653                     }
654                     /* Test added for bug 4347 fix */
655                     if (isWindows()) {
656                         buttons[buttonNb] = currentButton;
657                     } else {
658                         buttons[buttonsLabels.length - buttonNb - 1] = currentButton;
659                     }
660                 }
661             }
662         }
663         // Display
664         ((JScrollPane) objs[0]).setBorder(BorderFactory.createEmptyBorder());
665         final JPanel message = new JPanel(new BorderLayout());
666
667         /*
668          * If there is only one object to display then center it
669          * If 2 objects then add a header and a centered component
670          * If more then add a header and append all other objects to a centered container
671          */
672         if (objs.length > 1) {
673             message.add(objs[0], BorderLayout.NORTH);
674         } else {
675             message.add(objs[0], BorderLayout.CENTER);
676         }
677
678         if (objs.length == 2) {
679             message.add(objs[1], BorderLayout.CENTER);
680         }
681
682         if (objs.length > 2) {
683             // seems that this case is never called as x_message is no more available into Scilab.
684             final JPanel content = new JPanel();
685             for (int i = 1; i < objs.length; i++) {
686                 content.add(objs[i]);
687             }
688             message.add(content, BorderLayout.CENTER);
689         }
690
691         if (messageType != -1) {
692             setContentPane(new JOptionPane(message, messageType, JOptionPane.CANCEL_OPTION, null, buttons));
693         } else {
694             if (messageIcon == null) {
695                 messageIcon = scilabIcon;
696             }
697             setContentPane(new JOptionPane(message, messageType, JOptionPane.CANCEL_OPTION, messageIcon, buttons));
698         }
699         pack();
700         super.setModal(modal); /* Must call the JDialog class setModal */
701
702         if (parentWindow == null) {
703             if (ScilabConsole.isExistingConsole()) {
704                 setLocationRelativeTo((Component) ScilabConsole.getConsole().getAsSimpleConsole());
705             }
706         } else {
707             setLocationRelativeTo(parentWindow);
708         }
709
710         ScilabSwingUtilities.closeOnEscape(this);
711
712         if (defaultButton != null) {
713             getRootPane().setDefaultButton(defaultButton);
714             defaultButton.requestFocusInWindow();
715         }
716
717         setVisible(true);
718         doLayout();
719
720         // If the dialog is not modal and Scilab waits for an answer, have to wait...
721         if (!modal && scilabDialogType != X_MESSAGE_TYPE) {
722             synchronized (btnOK) {
723                 try {
724                     btnOK.wait();
725                 } catch (InterruptedException e) {
726                     e.printStackTrace();
727                 }
728             }
729         }
730     }
731
732     /**
733      * Action management
734      * @param ae the action event
735      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
736      */
737
738     @Override
739     public void actionPerformed(ActionEvent ae) {
740         if (ae.getSource() == btnOK) {
741             // For a x_dialog, get the user answer
742             if (scilabDialogType == X_DIALOG_TYPE) {
743                 userValue = textArea.getText();
744             } else if (scilabDialogType == X_MDIALOG_TYPE) {
745                 for (int textFieldIndex = 0; textFieldIndex < textFields.length; textFieldIndex++) {
746                     final Component c = textFields[textFieldIndex];
747                     if (c instanceof JTextField) {
748                         userValues[textFieldIndex] = ((JTextField) c).getText();
749                     } else if (c instanceof JCheckBox) {
750                         if (((JCheckBox) c).isSelected()) {
751                             userValues[textFieldIndex] = "%t";
752                         } else {
753                             userValues[textFieldIndex] = "%f";
754                         }
755                     }
756                 }
757                 userValue = ""; /* To make getValueSize return a non zero value */
758             } else if (scilabDialogType == X_CHOICES_TYPE) {
759
760                 // Get the selected button index of each button group
761                 for (int groupNum = 0; groupNum < buttonGroups.length; groupNum++) {
762                     Enumeration<AbstractButton> theButtons = buttonGroups[groupNum].getElements();
763                     for (int btnNum = 0; btnNum < buttonGroups[groupNum].getButtonCount(); btnNum++) {
764                         JToggleButton b = (JToggleButton) theButtons.nextElement();
765                         if (b.getModel() == buttonGroups[groupNum].getSelection()) {
766                             userSelectedButtons[groupNum] = btnNum + 1;
767                         }
768                     }
769                 }
770                 userValue = ""; /* To make getValueSize return a non zero value */
771             } else if (scilabDialogType == X_CHOOSE_TYPE) {
772                 selectedItem = listBox.getSelectedIndex() + 1;
773             }
774             selectedButton = 1;
775         } else if (ae.getSource() == btnCancel) {
776             selectedButton = 2;
777         } else if (buttonsLabels != null) { // User defined buttons
778             for (int index = 0; index < buttonsLabels.length; index++) {
779                 if (((JButton) ae.getSource()).getText().equals(buttonsLabels[index])) {
780                     selectedButton = index + 1;
781                     break;
782                 }
783             }
784         }
785         // Notify btnOK for not modal Dialogs
786         synchronized (btnOK) {
787             btnOK.notify();
788         }
789         // Destroy the Dialog
790         dispose();
791     }
792     /**
793      * Get the index of the button clicked
794      * @return the index of the button clicked
795      */
796     @Override
797     public int getSelectedButton() {
798         return selectedButton;
799     }
800
801     /**
802      * Set the indices of the default selected buttons (x_choices)
803      * @param indices the indices of the default selected buttons
804      */
805     @Override
806     public void setDefaultSelectedButtons(int[] indices) {
807         defaultSelectedButtons = indices;
808         scilabDialogType = X_CHOICES_TYPE;
809     }
810
811     /**
812      * Get the indices of the selected buttons (x_choices)
813      * @return the indices of the selected buttons
814      */
815     @Override
816     public int[] getUserSelectedButtons() {
817         return userSelectedButtons;
818     }
819
820     /**
821      * Set the labels of the buttons in the MessageBox
822      * @param labels the labels of the buttons
823      */
824     @Override
825     public void setButtonsLabels(String[] labels) {
826         buttonsLabels = labels;
827     }
828
829     /**
830      * Set the initial values of the editable zone in the MessageBox
831      * @param value the initial values
832      */
833     @Override
834     public void setInitialValue(String[] value) {
835         int line = 0;
836         initialValue = "";
837         for (line = 0; line < value.length - 1; line++) {
838             initialValue += value[line] + NEW_LINE;
839         }
840         initialValue += value[line];
841         initialValueSize = value.length;
842
843         scilabDialogType = X_DIALOG_TYPE;
844     }
845
846     /**
847      * Get the value of the editable zone in the MessageBox
848      * @return the value
849      */
850     @Override
851     public String[] getValue() {
852         if (scilabDialogType == X_MDIALOG_TYPE) {
853             return userValues;
854         } else {
855             return userValue.split(NEW_LINE);
856         }
857     }
858
859     /**
860      * Get the size of the value of the editable zone in the MessageBox
861      * @return the value size
862      */
863     @Override
864     public int getValueSize() {
865         if (userValue == null) {
866             return 0;
867         } else {
868             return userValue.split(NEW_LINE).length;
869         }
870     }
871
872     /**
873      * Set the items of the listbox in the MessageBox
874      * @param items the items to set
875      */
876     @Override
877     public void setListBoxItems(String[] items) {
878         listboxItems = items;
879
880         scilabDialogType = X_CHOOSE_TYPE;
881     }
882
883     /**
884      * Get the index of the selected item in the listbox in the MessageBox
885      * @return the index
886      */
887     @Override
888     public int getSelectedItem() {
889         return selectedItem;
890     }
891
892     /**
893      * Create the listbox to be displayed in a x_choose dialog
894      * @return the scrollpane containing the listbox
895      */
896     private JScrollPane createXchooseListBox() {
897         // Add the ListBox
898         listBox = new JList();
899         listBox.setLayoutOrientation(JList.VERTICAL);
900         listBox.setModel(new DefaultListModel());
901         listBox.addMouseListener(new MouseListener() {
902
903             @Override
904             public void mouseClicked(MouseEvent arg0) {
905                 if (arg0.getClickCount() == 2) {
906                     selectedItem = listBox.getSelectedIndex() + 1;
907                     // Notify btnOK for not modal Dialogs
908                     synchronized (btnOK) {
909                         btnOK.notify();
910                     }
911                     dispose();
912                 }
913             }
914
915             @Override
916             public void mouseEntered(MouseEvent arg0) {
917             }
918
919             @Override
920             public void mouseExited(MouseEvent arg0) {
921             }
922
923             @Override
924             public void mousePressed(MouseEvent arg0) {
925             }
926
927             @Override
928             public void mouseReleased(MouseEvent arg0) {
929             }
930
931         });
932         ((DefaultListModel) listBox.getModel()).clear();
933         for (int i = 0; i < listboxItems.length; i++) {
934             ((DefaultListModel) listBox.getModel()).addElement(listboxItems[i]);
935         }
936         listBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
937         JScrollPane scrollPane = new JScrollPane(listBox);
938         return  scrollPane;
939     }
940
941     /**
942      * Set the name of the lines labels in the editable zone in the MessageBox
943      * @param labels the labels
944      */
945     @Override
946     public void setLineLabels(String[] labels) {
947         scilabDialogType = X_MDIALOG_TYPE;
948         lineLabels = labels;
949     }
950
951     /**
952      * Set the name of the columns labels in the editable zone in the MessageBox
953      * @param labels the labels
954      */
955     @Override
956     public void setColumnLabels(String[] labels) {
957         columnLabels = labels;
958     }
959
960     /**
961      * Set the default values of a multi-value editable zone in the MessageBox
962      * @param values the values
963      */
964     @Override
965     public void setDefaultInput(String[] values) {
966         defaultInput = values;
967     }
968
969     /**
970      * Set a MessageBox modal or not
971      * @param status true to set the MessageBox modal and false else
972      */
973     @Override
974     public void setModal(boolean status) {
975         modal = status;
976     }
977
978
979     /**
980      * Set the MessageBox icon
981      * @param name the name of the icon
982      */
983     @Override
984     public void setIcon(String name) {
985         if (name.equals("error")) {
986             messageType = JOptionPane.ERROR_MESSAGE;
987         } else if (name.equals("hourglass")) {
988             messageIcon = hourglassIcon;
989         } else if (name.equals("info")) {
990             messageType = JOptionPane.INFORMATION_MESSAGE;
991         } else if (name.equals("passwd")) {
992             messageIcon = passwdIcon;
993         } else if (name.equals("question")) {
994             messageType = JOptionPane.QUESTION_MESSAGE;
995         } else if (name.equals("warning")) {
996             messageType = JOptionPane.WARNING_MESSAGE;
997         } else {
998             messageIcon = scilabIcon;
999         }
1000     }
1001
1002     private boolean isWindows() {
1003         return System.getProperty("os.name").toLowerCase().contains("windows");
1004     }
1005
1006     /**
1007      * Set the component used to set the location of the MessageBox (default is Scilab Console)
1008      * @param parent the parent
1009      */
1010     public void setParentForLocation(SimpleTab parent) {
1011         if (parent != null) {
1012             parentWindow = (Component) parent;
1013         } else {
1014             parentWindow = null;
1015         }
1016     }
1017
1018     /**
1019      * Set the component used to set the location of the MessageBox (default is Scilab Console)
1020      * @param parent
1021      */
1022     public void setParentForLocation(Component parent) {
1023         parentWindow = parent;
1024     }
1025
1026     /**
1027      * Set the component used to set the location of the MessageBox (default is Scilab Console)
1028      * @param parent
1029      */
1030     public void setParentForLocation(Tab parent) {
1031         setParentForLocation((Component) parent.getAsSimpleTab());
1032     }
1033 }