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) 2011 - DIGITEO - Vincent Couvert
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
15 package org.scilab.modules.gui.bridge.popupmenu;
17 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_MAX__;
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_STRING_COLNB__;
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_STRING__;
20 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UI_VALUE__;
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.io.IOException;
27 import java.util.Arrays;
29 import javax.swing.DefaultComboBoxModel;
30 import javax.swing.Icon;
31 import javax.swing.JComboBox;
32 import javax.swing.JLabel;
33 import javax.swing.JList;
34 import javax.swing.ListCellRenderer;
35 import javax.swing.UIManager;
36 import javax.swing.border.Border;
38 import org.scilab.modules.commons.gui.FindIconHelper;
39 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
40 import org.scilab.modules.gui.SwingViewObject;
41 import org.scilab.modules.gui.SwingViewWidget;
42 import org.scilab.modules.gui.events.callback.CommonCallBack;
43 import org.scilab.modules.gui.menubar.MenuBar;
44 import org.scilab.modules.gui.popupmenu.SimplePopupMenu;
45 import org.scilab.modules.gui.textbox.TextBox;
46 import org.scilab.modules.gui.toolbar.ToolBar;
47 import org.scilab.modules.gui.utils.ColorBox;
48 import org.scilab.modules.gui.utils.Position;
49 import org.scilab.modules.gui.utils.PositionConverter;
50 import org.scilab.modules.gui.utils.ScilabRelief;
51 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
52 import org.scilab.modules.gui.utils.Size;
53 import org.scilab.modules.gui.utils.SwingScilabListItem;
56 * Swing implementation for Scilab PopupMenu in GUIs
57 * @author Vincent COUVERT
58 * @author Marouane BEN JELLOUL
60 public class SwingScilabPopupMenu extends JComboBox implements SwingViewObject, SimplePopupMenu {
62 private static final long serialVersionUID = -4366581303317502544L;
66 private CommonCallBack callback;
68 private ActionListener defaultActionListener;
70 private Border defaultBorder = null;
73 private ListCellRenderer defaultRenderer = null;
74 private ListCellRenderer listRenderer = null;
79 public SwingScilabPopupMenu() {
82 defaultRenderer = getRenderer();
83 listRenderer = new ListCellRenderer() {
84 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
85 JLabel label = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
87 if (value instanceof SwingScilabListItem) {
88 SwingScilabListItem item = (SwingScilabListItem) value;
90 label.setText(item.toString());
91 label.setIcon(item.getIcon());
93 //index == -1 is for selected item after click
94 //so let standard FG and BG
95 if (index != - 1 && isSelected == false && item.getBackground() != null) {
96 label.setBackground(item.getBackground());
99 if (index != - 1 && isSelected == false && item.getForeground() != null) {
100 label.setForeground(item.getForeground());
110 setRenderer(listRenderer);
111 /* Bug 3635 fixed: allow arrow keys to browse items */
112 putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
113 defaultActionListener = new ActionListener() {
114 public void actionPerformed(ActionEvent e) {
115 Double scilabIndices = (double) getUserSelectedIndex();
116 if (scilabIndices == -1) {
117 GraphicController.getController().setProperty(uid, __GO_UI_VALUE__, new Double[] {});
119 GraphicController.getController().setProperty(uid, __GO_UI_VALUE__, new Double[] {scilabIndices});
122 if (callback != null) {
123 callback.actionPerformed(null);
127 addActionListener(defaultActionListener);
131 * Draws a swing Scilab tab
132 * @see org.scilab.modules.gui.uielement.UIElement#draw()
135 this.setVisible(true);
139 * Gets the dimensions (width and height) of a swing Scilab tab
140 * @return the dimensions of the tab
141 * @see org.scilab.modules.gui.uielement.UIElement#getDims()
143 public Size getDims() {
144 return new Size(getWidth(), getHeight());
148 * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
149 * @return the position of the tab
150 * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
152 public Position getPosition() {
153 return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
157 * Sets the dimensions (width and height) of a swing Scilab tab
158 * @param newSize the dimensions we want to set to the tab
159 * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
161 public void setDims(Size newSize) {
162 setSize(newSize.getWidth(), newSize.getHeight());
163 doLayout(); /* Needed !! because PopupMenu is badly drawn else */
167 * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
168 * @param newPosition the position we want to set to the tab
169 * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
171 public void setPosition(Position newPosition) {
172 Position javaPosition = PositionConverter.scilabToJava(newPosition, getDims(), getParent());
173 setLocation(javaPosition.getX(), javaPosition.getY());
177 * Add a callback to the PopupMenu
178 * @param callback the callback to set.
180 public void setCallback(CommonCallBack callback) {
181 this.callback = callback;
186 * @param menuBarToAdd the MenuBar associated to the Tab.
188 public void addMenuBar(MenuBar menuBarToAdd) {
189 /* Unimplemented for PopupMenus */
190 throw new UnsupportedOperationException();
195 * @param toolBarToAdd the ToolBar associated to the Tab.
197 public void addToolBar(ToolBar toolBarToAdd) {
198 /* Unimplemented for PopupMenus */
199 throw new UnsupportedOperationException();
204 * @return MenuBar: the MenuBar associated to the Tab.
206 public MenuBar getMenuBar() {
207 /* Unimplemented for PopupMenus */
208 throw new UnsupportedOperationException();
213 * @return ToolBar: the ToolBar associated to the Tab.
215 public ToolBar getToolBar() {
216 /* Unimplemented for PopupMenus */
217 throw new UnsupportedOperationException();
221 * Get the text if the PopupMenu items
223 * @see org.scilab.modules.gui.widget.Widget#getText()
225 public String getText() {
226 /* Unimplemented for PopupMenus */
227 throw new UnsupportedOperationException();
231 * Set the text of the PopupMenu items
232 * @param text the text of the items
233 * @see org.scilab.modules.gui.widget.Widget#setText(java.lang.String)
235 public void setText(String text) {
236 /* Unimplemented for PopupMenus */
237 throw new UnsupportedOperationException();
241 * Set the horizontal alignment for the PopupMenu text
242 * @param alignment the value for the alignment (See ScilabAlignment.java)
244 public void setHorizontalAlignment(String alignment) {
245 // Nothing to do here
249 * Set the vertical alignment for the PopupMenu text
250 * @param alignment the value for the alignment (See ScilabAlignment.java)
252 public void setVerticalAlignment(String alignment) {
253 // Nothing to do here
257 * Set the selected index of the PopupMenu
258 * @param index the index of the item to be selected
260 public void setUserSelectedIndex(int index) {
261 /* Remove the listener to avoid the callback to be executed */
262 removeActionListener(defaultActionListener);
264 // Scilab indices in Value begin at 1 and Java indices begin at 0
265 if (index >= 0 && index <= getItemCount()) {
266 setSelectedIndex(index - 1);
269 /* Put back the listener */
270 addActionListener(defaultActionListener);
274 * Get the selected index of the PopupMenu
275 * @return the index of the item selected
277 public int getUserSelectedIndex() {
278 int index = getSelectedIndex();
287 * Get the text of all the PopupMenu items
288 * @return the text items
290 public String[] getAllItemsText() {
291 String[] retValue = new String[getItemCount()];
292 for (int i = 0; i < getItemCount(); i++) {
293 retValue[i] = getItemAt(i).toString();
300 * Get the number of items in the PopupMenu
301 * @return the number of items
303 public int getNumberOfItems() {
304 return getItemCount();
308 * Set the text of the PopupMenu items
309 * @param text the text of the items
311 public void setText(String[] text) {
312 DefaultComboBoxModel model = new DefaultComboBoxModel();
314 //get numbers of columns
315 GraphicController controller = GraphicController.getController();
316 Integer nbCol = (Integer) controller.getProperty(getId(), __GO_UI_STRING_COLNB__);
318 /* Remove the listener to avoid the callback to be executed */
319 removeActionListener(defaultActionListener);
321 boolean tryColorBox = true;
322 boolean tryColor = true;
323 boolean tryIcon = true;
324 int nbRow = text.length / nbCol;
326 for (int i = 0; i < nbRow; i++) {
329 Color background = null;
330 Color foreground = null;
333 // - 1st icon or colorBox
339 // - 1st icon or colorBox
348 // - 1st icon or colorBox
354 if (tryColorBox) { //color
356 Color color = Color.decode(text[i]);
357 icon = ColorBox.createColorBox(16, 16, color);
358 } catch (NumberFormatException e) {
360 model.removeAllElements();
361 //restart loop with icon
369 icon = FindIconHelper.loadIcon(text[i]);
370 } catch (IOException e) {
372 model.removeAllElements();
373 //restart loop with text only
382 if (tryColorBox || tryIcon) {
386 str = text[(nbRow * colIndex) + i];
387 if (nbCol > (1 + colIndex)) {
388 background = Color.decode(text[nbRow * (1 + colIndex) + i]);
389 if (nbCol > (2 + colIndex)) {
390 foreground = Color.decode(text[nbRow * (2 + colIndex) + i]);
394 //add item in list box
395 model.addElement(new SwingScilabListItem(str, icon, background, foreground));
396 } catch (NumberFormatException e) {
398 model.removeAllElements();
399 //restart loop with text only
404 for (int j = 0; j < nbCol; j++) {
405 model.addElement(new SwingScilabListItem(text[nbRow * j + i], icon, background, foreground));
410 //reset selected index
411 setSelectedIndex(-1);
414 //take care to add listener BEFORE set Property to avoid multiple remove and multiple add
415 addActionListener(defaultActionListener);
419 * Set the Relief of the PopupMenu
420 * @param reliefType the type of the relief to set (See ScilabRelief.java)
422 public void setRelief(String reliefType) {
423 if (defaultBorder == null) {
424 defaultBorder = getBorder();
426 setBorder(ScilabRelief.getBorderFromRelief(reliefType, defaultBorder));
430 * Destroy the PopupMenu
432 public void destroy() {
433 ScilabSwingUtilities.removeFromParent(this);
438 * @param infoBarToAdd the InfoBar associated to the PopupMenu.
440 public void addInfoBar(TextBox infoBarToAdd) {
441 /* Unimplemented for PopupMenus */
442 throw new UnsupportedOperationException();
447 * @return the InfoBar associated to the PopupMenu.
449 public TextBox getInfoBar() {
450 /* Unimplemented for PopupMenus */
451 throw new UnsupportedOperationException();
459 public void setId(Integer id) {
467 public Integer getId() {
472 * Generic update method
473 * @param property property name
474 * @param value property value
476 public void update(int property, Object value) {
478 case __GO_UI_STRING__: {
479 setText((String[]) value);
482 case __GO_UI_MAX__: {
483 Integer val = ((Double)value).intValue();
485 char[] chars = new char[val];
486 Arrays.fill(chars, '*');
487 String proto = new String(chars);
488 setPrototypeDisplayValue(proto);
492 case __GO_UI_VALUE__: {
493 Double[] doubleValue = ((Double[]) value);
495 //[] or 0 -> no selection
496 if (doubleValue.length == 0 || doubleValue[0] == 0) {
497 setUserSelectedIndex(0);
501 int[] intValue = new int[doubleValue.length];
502 for (int k = 0; k < doubleValue.length; k++) {
503 intValue[k] = doubleValue[k].intValue();
506 // Update selected items in the popupmenu
507 setUserSelectedIndex(intValue[0]);
511 SwingViewWidget.update(this, property, value);
517 public void resetBackground() {
518 Color color = (Color) UIManager.getLookAndFeelDefaults().get("ComboBox.background");
520 setBackground(color);
524 public void resetForeground() {
525 Color color = (Color)UIManager.getLookAndFeelDefaults().get("ComboBox.foreground");
527 setForeground(color);