9cb85a5b7e3fcc53c5f77d80c2ee500dfbc48d8a
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / listbox / SwingScilabListBox.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Vincent Couvert
4  * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
5  * Copyright (C) 2010-2011 - DIGITEO - Vincent COUVERT
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-en.txt
12  *
13  */
14
15 package org.scilab.modules.gui.bridge.listbox;
16
17 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_STRING__;
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_VALUE__;
19
20 import java.awt.Color;
21 import java.awt.Font;
22 import java.awt.event.MouseEvent;
23 import java.awt.event.MouseListener;
24 import java.util.StringTokenizer;
25
26 import javax.swing.DefaultListModel;
27 import javax.swing.JList;
28 import javax.swing.JScrollPane;
29 import javax.swing.ListSelectionModel;
30
31 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
32 import org.scilab.modules.gui.SwingViewWidget;
33 import org.scilab.modules.gui.SwingViewObject;
34 import org.scilab.modules.gui.events.callback.CommonCallBack;
35 import org.scilab.modules.gui.listbox.SimpleListBox;
36 import org.scilab.modules.gui.menubar.MenuBar;
37 import org.scilab.modules.gui.textbox.TextBox;
38 import org.scilab.modules.gui.toolbar.ToolBar;
39 import org.scilab.modules.gui.utils.Position;
40 import org.scilab.modules.gui.utils.PositionConverter;
41 import org.scilab.modules.gui.utils.ScilabRelief;
42 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
43 import org.scilab.modules.gui.utils.Size;
44
45 /**
46  * Swing implementation for Scilab ListBox in GUIs
47  * @author Vincent COUVERT
48  * @author Marouane BEN JELLOUL
49  */
50 public class SwingScilabListBox extends JScrollPane implements SwingViewObject, SimpleListBox {
51
52     private static final long serialVersionUID = 3507396207331058895L;
53
54     private static final String STRING_SEPARATOR = "|";
55
56     private String uid;
57
58     private CommonCallBack callback;
59
60     private MouseListener mouseListener;
61
62     /**
63      * the JList we use
64      */
65     private JList list;
66
67     /**
68      * Constructor
69      */
70     public SwingScilabListBox() {
71         super();
72         getViewport().add(getList());
73
74         mouseListener = new MouseListener() {
75             public void mouseClicked(MouseEvent e) {
76                 // Scilab indices in Value begin at 1 and Java indices begin at 0
77                 int[] javaIndices = getList().getSelectedIndices().clone();
78                 Double[] scilabIndices = new Double[javaIndices.length];
79                 for (int i = 0; i < getList().getSelectedIndices().length; i++) {
80                     scilabIndices[i] = (double) javaIndices[i] + 1;
81                 }
82                 GraphicController.getController().setProperty(uid, __GO_UI_VALUE__, scilabIndices);
83                 if (e.getButton() == MouseEvent.BUTTON1 && callback != null) {
84                     callback.actionPerformed(null);
85                 }
86             }
87             public void mouseEntered(MouseEvent arg0) { }
88             public void mouseExited(MouseEvent arg0) { }
89             public void mousePressed(MouseEvent arg0) { }
90             public void mouseReleased(MouseEvent arg0) { }
91         };
92         getList().addMouseListener(mouseListener);
93     }
94
95     /**
96      * To get the Background color of the element.
97      * @return color the Color
98      */
99     public Color getBackground() {
100         return getList().getBackground();
101     }
102
103     /**
104      * To get the Font of the element.
105      * @return font the Font
106      */
107     public Font getFont() {
108         return getList().getFont();
109     }
110
111     /**
112      * To get the Foreground color of the element.
113      * @return color the Color
114      */
115     public Color getForeground() {
116         return getList().getForeground();
117     }
118
119     /**
120      * To set the Background color of the element.
121      * @param color the Color
122      */
123     public void setBackground(Color color) {
124         getList().setBackground(color);
125     }
126
127     /**
128      * To set the Font of the element.
129      * @param font the Font
130      */
131     public void setFont(Font font) {
132         getList().setFont(font);
133     }
134
135     /**
136      * To set the Foreground color of the element.
137      * @param color the Color
138      */
139     public void setForeground(Color color) {
140         getList().setForeground(color);
141     }
142
143     /**
144      * Draws a swing Scilab tab
145      * @see org.scilab.modules.gui.uielement.UIElement#draw()
146      */
147     public void draw() {
148         this.setVisible(true);
149         this.doLayout();
150     }
151
152     /**
153      * Gets the dimensions (width and height) of a swing Scilab tab
154      * @return the dimensions of the tab
155      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
156      */
157     public Size getDims() {
158         return new Size(getWidth(), getHeight());
159     }
160
161     /**
162      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
163      * @return the position of the tab
164      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
165      */
166     public Position getPosition() {
167         return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
168     }
169
170     /**
171      * Sets the dimensions (width and height) of a swing Scilab tab
172      * @param newSize the dimensions we want to set to the tab
173      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
174      */
175     public void setDims(Size newSize) {
176         setSize(newSize.getWidth(), newSize.getHeight());
177     }
178
179     /**
180      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
181      * @param newPosition the position we want to set to the tab
182      * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
183      */
184     public void setPosition(Position newPosition) {
185         Position javaPosition = PositionConverter.scilabToJava(newPosition, getDims(), getParent());
186         setLocation(javaPosition.getX(), javaPosition.getY());
187     }
188
189     /**
190      * Sets the visibility status of an UIElement
191      * @param newVisibleState the visibility status we want to set for the UIElement
192      *                      (true if the UIElement is visible, false if not)
193      */
194     public void setVisible(boolean newVisibleState) {
195         super.setVisible(newVisibleState);
196         list.setVisible(newVisibleState);
197     }
198
199     /**
200      * Sets the enable status of an UIElement
201      * @param newEnableState the enable status we want to set for the UIElement
202      *                      (true if the UIElement is enabled, false if not)
203      */
204     public void setEnabled(boolean newEnableState) {
205         super.setEnabled(newEnableState);
206         getList().setEnabled(newEnableState);
207         if (newEnableState) {
208             if (mouseListener != null) {
209                 getList().addMouseListener(mouseListener);
210             }
211         } else {
212             if (mouseListener != null) {
213                 getList().removeMouseListener(mouseListener);
214             }
215         }
216     }
217
218     /**
219      * Add a callback to the CheckBox
220      * @param cb the callback to set.
221      */
222     public void setCallback(CommonCallBack cb) {
223         this.callback = cb;
224     }
225
226     /**
227      * Setter for MenuBar
228      * @param menuBarToAdd the MenuBar associated to the Tab.
229      */
230     public void addMenuBar(MenuBar menuBarToAdd) {
231         /* Unimplemented for ListBoxes */
232         throw new UnsupportedOperationException();
233     }
234
235     /**
236      * Setter for ToolBar
237      * @param toolBarToAdd the ToolBar associated to the Tab.
238      */
239     public void addToolBar(ToolBar toolBarToAdd) {
240         /* Unimplemented for ListBoxes */
241         throw new UnsupportedOperationException();
242     }
243
244     /**
245      * Getter for MenuBar
246      * @return MenuBar: the MenuBar associated to the Tab.
247      */
248     public MenuBar getMenuBar() {
249         /* Unimplemented for ListBoxes */
250         throw new UnsupportedOperationException();
251     }
252
253     /**
254      * Getter for ToolBar
255      * @return ToolBar: the ToolBar associated to the Tab.
256      */
257     public ToolBar getToolBar() {
258         /* Unimplemented for ListBoxes */
259         throw new UnsupportedOperationException();
260     }
261
262     /**
263      * Get the first item text
264      * @return the items
265      * @see org.scilab.modules.gui.widget.Widget#getText()
266      */
267     public String getText() {
268         /* Unimplemented for ListBoxes */
269         throw new UnsupportedOperationException();
270     }
271
272     /**
273      * Get the text of all the list items
274      * @return the items
275      * @see org.scilab.modules.gui.listbox.ListBox#getAllItemsText()
276      */
277     public String[] getAllItemsText() {
278         String[] retValue = new String[getList().getModel().getSize()];
279         for (int i = 0; i < getList().getModel().getSize(); i++) {
280             retValue[i] = (String) getList().getModel().getElementAt(i);
281         }
282         return retValue;
283     }
284
285     /**
286      * Get the number of items in the list
287      * @return the number of items
288      * @see org.scilab.modules.gui.listbox.ListBox#getNumberOfItems()
289      */
290     public int getNumberOfItems() {
291         return getList().getModel().getSize();
292     }
293
294     /**
295      * Set the text of the list items
296      * @param text the text of the items
297      * @see org.scilab.modules.gui.widget.Widget#setText(java.lang.String)
298      */
299     public void setText(String text) {
300         DefaultListModel model = new DefaultListModel();
301         model.addElement(text);
302         getList().setModel(model);
303         revalidate();
304     }
305
306     /**
307      * Set the text of the list items
308      * @param text the text of the items
309      * @see org.scilab.modules.gui.widget.Widget#setText(java.lang.String)
310      */
311     public void setText(String[] text) {
312         /* Do we need to update the strings */
313         /* Test performed to avoid loops when the model is updated from here */
314         boolean updateNeeded = false;
315         String[] previousText = getAllItemsText();
316         if (previousText.length != text.length) {
317             updateNeeded = true;
318         } else {
319             for (int k = 0; k < text.length; k++) {
320                 if (text[k].compareTo(previousText[k]) != 0) {
321                     updateNeeded = true;
322                     break;
323                 }
324             }
325         }
326         if (!updateNeeded) {
327             return;
328         }
329
330         final String[] textF = text;
331         DefaultListModel model = new DefaultListModel();
332         if (textF.length == 1 & text[0].contains(STRING_SEPARATOR)) {
333             StringTokenizer strTok = new StringTokenizer(textF[0], STRING_SEPARATOR);
334             while (strTok.hasMoreTokens()) {
335                 model.addElement(strTok.nextToken());
336             }
337             /* Update the model with the parsed string */
338             GraphicController.getController().setProperty(uid, __GO_UI_STRING__, getAllItemsText());
339         } else {
340             for (int i = 0; i < textF.length; i++) {
341                 model.addElement(textF[i]);
342             }
343         }
344         getList().setModel(model);
345         revalidate();
346     }
347
348     /**
349      * Set the horizontal alignment for the ListBox text
350      * @param alignment the value for the alignment (See ScilabAlignment.java)
351      */
352     public void setHorizontalAlignment(String alignment) {
353         // Nothing to do here
354     }
355
356     /**
357      * Set the vertical alignment for the ListBox text
358      * @param alignment the value for the alignment (See ScilabAlignment.java)
359      */
360     public void setVerticalAlignment(String alignment) {
361         // Nothing to do here
362     }
363
364     /**
365      * Set if more than one item can be selected in a ListBox
366      * @param status true if multiple selection is enabled
367      */
368     public void setMultipleSelectionEnabled(boolean status) {
369         if (status) {
370             getList().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
371         } else {
372             getList().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
373         }
374     }
375
376     /**
377      * Set the selected indices of the ListBox
378      * @param indices the indices of the items to be selected
379      */
380     public void setSelectedIndices(int[] indices) {
381         // Scilab indices in Value begin at 1 and Java indices begin at 0
382         int[] javaIndices = indices.clone();
383         for (int i = 0; i < javaIndices.length; i++) {
384             javaIndices[i] = javaIndices[i] - 1;
385         }
386
387         /* Remove the listener to avoid the callback to be executed */
388         if (mouseListener != null) {
389             getList().removeMouseListener(mouseListener);
390         }
391
392         getList().setSelectedIndices(javaIndices);
393
394         /* Put back the listener */
395         if (mouseListener != null) {
396             getList().addMouseListener(mouseListener);
397         }
398     }
399
400     /**
401      * Get the selected indices of the ListBox
402      * @return the indices of the items selected
403      */
404     public int[] getSelectedIndices() {
405         // Scilab indices in Value begin at 1 and Java indices begin at 0
406         int[] javaIndices = getList().getSelectedIndices().clone();
407         int[] scilabIndices = javaIndices.clone();
408         for (int i = 0; i < getList().getSelectedIndices().length; i++) {
409             scilabIndices[i] = scilabIndices[i] + 1;
410         }
411         return scilabIndices;
412     }
413
414     /**
415      * Get the number of items selected in the ListBox
416      * @return the number of items selected
417      */
418     public int getSelectionSize() {
419         return getList().getSelectedIndices().length;
420     }
421
422     /**
423      * Get or create the list component
424      * @return the list
425      */
426     private JList getList() {
427         if (list == null) {
428             list = new JList();
429             list.setLayoutOrientation(JList.VERTICAL);
430             list.setModel(new DefaultListModel());
431         }
432         return list;
433     }
434
435     /**
436      * Set the Relief of the ListBox
437      * @param reliefType the type of the relief to set (See ScilabRelief.java)
438      */
439     public void setRelief(String reliefType) {
440         setBorder(ScilabRelief.getBorderFromRelief(reliefType));
441     }
442
443     /**
444      * Destroy the ListBox
445      */
446     public void destroy() {
447         ScilabSwingUtilities.removeFromParent(this);
448     }
449
450     /**
451      * Setter for InfoBar
452      * @param infoBarToAdd the InfoBar associated to the ListBox.
453      */
454     public void addInfoBar(TextBox infoBarToAdd) {
455         /* Unimplemented for ListBoxes */
456         throw new UnsupportedOperationException();
457     }
458
459     /**
460      * Getter for InfoBar
461      * @return the InfoBar associated to the ListBox.
462      */
463     public TextBox getInfoBar() {
464         /* Unimplemented for ListBoxes */
465         throw new UnsupportedOperationException();
466     }
467
468     /**
469      * Adjusts the view so that the element given by index is displayed at the top of the ListBox.
470      * @param index the index of the element to be displayed at the top of the ListBox.
471      */
472     public void setListBoxTop(int index) {
473         if (index > 0) {
474             getViewport().setViewPosition(getList().getUI().indexToLocation(getList(), index - 1));
475             doLayout();
476         }
477     }
478
479     /**
480      * Gets the index of the element displayed at the top of the ListBox
481      * @return the index of the element displayed at the top of the ListBox
482      */
483     public int getListBoxTop() {
484         return getList().getUI().locationToIndex(getList(), getViewport().getViewPosition()) + 1;
485     }
486
487     /**
488      * Set the UID
489      * @param id the UID
490      */
491     public void setId(String id) {
492         uid = id;
493     }
494
495     /**
496      * Get the UID
497      * @return the UID
498      */
499     public String getId() {
500         return uid;
501     }
502
503     /**
504      * Generic update method
505      * @param property property name
506      * @param value property value
507      */
508     public void update(int property, Object value) {
509         SwingViewWidget.update(this, property, value);
510     }
511 }