7999f515b0c76e3692981ce3784cd0578f795752
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / uitable / SwingScilabUiTable.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - Han DONG
4  * Copyright (C) 2011 - DIGITEO - Vincent COUVERT
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16 package org.scilab.modules.gui.bridge.uitable;
17
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
21 import java.awt.Color;
22 import java.awt.Font;
23
24 import javax.swing.JLabel;
25 import javax.swing.JList;
26 import javax.swing.JScrollPane;
27 import javax.swing.JTable;
28 import javax.swing.UIManager;
29 import javax.swing.border.Border;
30
31 import javax.swing.event.TableModelEvent;
32 import javax.swing.event.TableModelListener;
33 import javax.swing.table.TableModel;
34
35 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
36 import org.scilab.modules.gui.SwingViewObject;
37 import org.scilab.modules.gui.SwingViewWidget;
38 import org.scilab.modules.gui.events.callback.CommonCallBack;
39 import org.scilab.modules.gui.menubar.MenuBar;
40 import org.scilab.modules.gui.textbox.TextBox;
41 import org.scilab.modules.gui.toolbar.ToolBar;
42 import org.scilab.modules.gui.utils.Position;
43 import org.scilab.modules.gui.utils.PositionConverter;
44 import org.scilab.modules.gui.utils.ScilabAlignment;
45 import org.scilab.modules.gui.utils.ScilabRelief;
46 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
47 import org.scilab.modules.gui.utils.Size;
48 import org.scilab.modules.gui.widget.Widget;
49
50 /**
51  * Swing implementation for Scilab UiTable in GUIs
52  * @author Han DONG
53  */
54 public class SwingScilabUiTable extends JScrollPane implements SwingViewObject, Widget {
55
56     private static final long serialVersionUID = -5497171010652701217L;
57
58     private Integer uid;
59
60     private Border defaultBorder = null;
61
62     private JTable uiTable;
63     private JList rowHeader;
64
65     private Object[] colNames = {};
66     private Object[] rowNames = {};
67     private Object[][] data = {};
68
69     private int nCol;
70     private int nRow;
71
72     private JLabel label;
73
74     /**
75      * Constructor
76      */
77     public SwingScilabUiTable() {
78         super();
79         getViewport().add(getUiTable());
80         setRowHeaderView(getCustomRowHeader());
81     }
82
83     /**
84      * Apply a new font for the uiTable.
85      * @param font new font to use.
86      */
87     public void setFont(Font font) {
88         getLabel().setFont(font);
89     }
90
91     /**
92      * To get the Font of the element.
93      * @return font the Font
94      */
95     public Font getFont() {
96         return getLabel().getFont();
97     }
98
99     /**
100      * To get the Foreground color of the element.
101      * @return color the Color
102      */
103     public Color getForeground() {
104         return getLabel().getForeground();
105     }
106
107     /**
108      * To set the Foreground color of the element.
109      * @param color the Color
110      */
111     public void setForeground(Color color) {
112         getLabel().setForeground(color);
113     }
114
115     /**
116      * To set the Background color of the element.
117      * @param color the Color
118      */
119     public void setBackground(Color color) {
120         getLabel().setBackground(color);
121     }
122
123     /**
124      * To get the Background color of the element.
125      * @return color the Color
126      */
127     public Color getBackground() {
128         return getLabel().getBackground();
129     }
130
131     /**
132      * Draws a swing Scilab PushButton
133      * @see org.scilab.modules.gui.uielement.UIElement#draw()
134      */
135     public void draw() {
136         this.setVisible(true);
137         this.doLayout();
138     }
139
140     /**
141      * Sets the visibility status of an UIElement
142      * @param newVisibleState the visibility status we want to set for the
143      * UIElement (true if the UIElement is visible, false if not)
144      */
145     public void setVisible(boolean newVisibleState) {
146         super.setVisible(newVisibleState);
147         //getLabel().setVisible(newVisibleState);
148     }
149
150     /**
151      * Gets the dimensions (width and height) of a swing Scilab element
152      * @return the dimensions of the element
153      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
154      */
155     public Size getDims() {
156         return new Size(getWidth(), getHeight());
157     }
158
159     /**
160      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab
161      * element
162      * @return the position of the element
163      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
164      */
165     public Position getPosition() {
166         return PositionConverter.javaToScilab(getLocation(), getSize(), getParent());
167     }
168
169     /**
170      * Sets the dimensions (width and height) of a swing Scilab element
171      * @param newSize the dimensions to set to the element
172      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
173      */
174     public void setDims(Size newSize) {
175         setSize(newSize.getWidth(), newSize.getHeight());
176     }
177
178     /**
179      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab
180      * element
181      * @param newPosition the position to set to the element
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      * Add a callback to the UiTable
191      * @param callback the callback to set.
192      */
193     public void setCallback(CommonCallBack callback) {
194         // Nothing to do...
195     }
196
197     /**
198      * Setter for MenuBar
199      * @param menuBarToAdd the MenuBar associated to the UiTable.
200      */
201     public void addMenuBar(MenuBar menuBarToAdd) {
202         /* Unimplemented for UiTables */
203         throw new UnsupportedOperationException();
204     }
205
206     /**
207      * Setter for ToolBar
208      * @param toolBarToAdd the ToolBar associated to the UiTable.
209      */
210     public void addToolBar(ToolBar toolBarToAdd) {
211         /* Unimplemented for UiTables */
212         throw new UnsupportedOperationException();
213     }
214
215     /**
216      * Getter for MenuBar
217      * @return MenuBar: the MenuBar associated to the UiTable.
218      */
219     public MenuBar getMenuBar() {
220         /* Unimplemented for UiTables */
221         throw new UnsupportedOperationException();
222     }
223
224     /**
225      * Getter for ToolBar
226      * @return ToolBar: the ToolBar associated to the UiTable.
227      */
228     public ToolBar getToolBar() {
229         /* Unimplemented for UiTables */
230         throw new UnsupportedOperationException();
231     }
232
233     /**
234      * Set the horizontal alignment for the UiTable text
235      * @param alignment the value for the alignment (See ScilabAlignment.java)
236      */
237     public void setHorizontalAlignment(String alignment) {
238         getLabel().setHorizontalAlignment(ScilabAlignment.toSwingAlignment(alignment));
239     }
240
241     /**
242      * Set the vertical alignment for the UiTable text
243      * @param alignment the value for the alignment (See ScilabAlignment.java)
244      */
245     public void setVerticalAlignment(String alignment) {
246         getLabel().setVerticalAlignment(ScilabAlignment.toSwingAlignment(alignment));
247     }
248
249     /**
250      * Set the Relief of the UiTable
251      * @param reliefType the type of the relief to set (See ScilabRelief.java)
252      */
253     public void setRelief(String reliefType) {
254         if (defaultBorder == null) {
255             defaultBorder = getBorder();
256         }
257         setBorder(ScilabRelief.getBorderFromRelief(reliefType, defaultBorder));
258     }
259
260     /**
261      * Destroy the UiTable
262      */
263     public void destroy() {
264         ScilabSwingUtilities.removeFromParent(this);
265     }
266
267     /**
268      * Setter for InfoBar
269      * @param infoBarToAdd the InfoBar associated to the UiTable.
270      */
271     public void addInfoBar(TextBox infoBarToAdd) {
272         /* Unimplemented for UiTables */
273         throw new UnsupportedOperationException();
274     }
275
276     /**
277      * Getter for InfoBar
278      * @return the InfoBar associated to the UiTable.
279      */
280     public TextBox getInfoBar() {
281         /* Unimplemented for UiTables */
282         throw new UnsupportedOperationException();
283     }
284
285     /**
286      * Create/Return the uiTable Java object
287      * @return the uiTable
288      */
289     private JTable getUiTable() {
290         if (uiTable == null) {
291             uiTable = createTable(data, colNames);
292             uiTable.setFillsViewportHeight(true);
293             if (uiTable.getGridColor().equals(Color.WHITE)) {
294                 uiTable.setGridColor(new Color(128, 128, 128));
295             }
296             uiTable.setShowHorizontalLines(true);
297             uiTable.setShowVerticalLines(true);
298         }
299         return uiTable;
300     }
301
302     /**
303      * Create/Return the rowHeader Java Object
304      * @return the rowHeader
305      */
306     private JList getCustomRowHeader() {
307         if (rowHeader == null) {
308             rowHeader = new JList(rowNames);
309             rowHeader.setFixedCellWidth(50);
310             rowHeader.setFixedCellHeight(uiTable.getRowHeight());
311             rowHeader.setCellRenderer(new RowHeaderRenderer(uiTable));
312         }
313         return rowHeader;
314     }
315
316     /**
317      * Create/Return the uiTable Java object
318      * @return the uiTable
319      */
320     private JLabel getLabel() {
321         if (label == null) {
322             label = new JLabel();
323         }
324         return label;
325     }
326
327     /**
328      * gets directory of image in image render
329      * @return the directory string
330      * @see org.scilab.modules.gui.text.SimpleText#getText()
331      */
332     public String getText() {
333         return getLabel().getText();
334     }
335
336     /**
337      * Sets the directory for image to render
338      * @param newText the new directory to image
339      */
340     public void setText(String newText) {
341         getLabel().setText(newText);
342     }
343
344     public void setEmptyText() {
345         setColumnNames(new String[] {""});
346         setRowNames(new String[] {""});
347         setData(new String[] {""});
348     }
349
350     /**
351      * Sets the column names for uitable
352      * @param names the String[] that contains column names
353      */
354     public void setColumnNames(String[] names) {
355         //updates table with new column names
356         nCol = names.length;
357         colNames = names;
358         uiTable = createTable(data, names);
359         getViewport().add(uiTable);
360         uiTable.doLayout();
361     }
362
363     /**
364      * Sets the row names for uitable
365      * @param names the String[] that contains row names
366      */
367     public void setRowNames(String[] names) {
368         //updates table with new row names
369         nRow = names.length;
370         rowNames = names;
371         rowHeader = new JList(names);
372         rowHeader.setFixedCellWidth(50);
373         rowHeader.setFixedCellHeight(uiTable.getRowHeight());
374         rowHeader.setCellRenderer(new RowHeaderRenderer(uiTable));
375         setRowHeaderView(rowHeader);
376         uiTable.doLayout();
377     }
378
379     /**
380      * Sets the Data for uitable
381      * @param text the String that contains row data delimited by a '|' and
382      * column data delimited by " ". Example: 1.26 3.47 | a b | d e | a b
383      */
384     public void setData(String[] text) {
385         //initializes data structure with number of rows and columns
386         if (nRow == 0) {
387             nRow = text.length / nCol;
388         }
389         data = new Object[nRow][nCol];
390         int i = 0;
391         int j = 0;
392         int nbElements = 0;
393
394         while (nbElements < text.length && i < nRow && j < nCol) {
395             data[i][j] = text[nbElements];
396             i++;
397             nbElements++;
398             if (i == nRow) {
399                 i = 0;
400                 j++;
401             }
402         }
403
404         //if no row names were provided, it will set numeric ones according to number of rows. (1, 2, 3, 4, ...)
405         if (nRow == 0) {
406             nRow = j;
407             rowNames = new Object[nRow];
408             for (int k = 0; k < nRow; k++) {
409                 rowNames[k] = k;
410             }
411             rowHeader = new JList(rowNames);
412             rowHeader.setFixedCellWidth(50);
413             rowHeader.setFixedCellHeight(uiTable.getRowHeight());
414             rowHeader.setCellRenderer(new RowHeaderRenderer(uiTable));
415             setRowHeaderView(rowHeader);
416         }
417
418         //adds and updates table with new data
419         uiTable = createTable(data, colNames);
420         getViewport().add(uiTable);
421         uiTable.doLayout();
422     }
423
424     /**
425      * Set the UID
426      * @param id the UID
427      */
428     public void setId(Integer id) {
429         uid = id;
430     }
431
432     /**
433      * To enable or disable editing on table.
434      * @param status status value either True or False
435      */
436     public void setEnabled(boolean status){
437         uiTable.setEnabled(status);
438     }
439
440     /**
441      * Get the UID
442      * @return the UID
443      */
444     public Integer getId() {
445         return uid;
446     }
447
448     /**
449      * Generic update method
450      * @param property property name
451      * @param value property value
452      */
453     public void update(int property, Object value) {
454         GraphicController controller = GraphicController.getController();
455
456         switch (property) {
457             case __GO_UI_STRING__: {
458                 // Update column names
459                 String[] stringValue = (String[]) value;
460                 if (stringValue.length == 0) {
461                     setColumnNames(new String[] {""});
462                     setRowNames(new String[] {""});
463                     setData(new String[] {""});
464                     return;
465                 }
466                 int colNb = ((Integer) controller.getProperty(uid, __GO_UI_STRING_COLNB__));
467                 String[] colNames = new String[colNb - 1];
468                 for (int k = 1; k < colNb; k++) {
469                     colNames[k - 1] = stringValue[k * (stringValue.length / colNb)];
470                 }
471
472                 setColumnNames(colNames);
473
474                 // Update row names
475                 String[] rowNames = new String[stringValue.length / colNb - 1];
476                 for (int k = 1; k < stringValue.length / colNb; k++) {
477                     rowNames[k - 1] = stringValue[k];
478                 }
479
480                 setRowNames(rowNames);
481
482                 // Update data
483                 String[] tableData = new String[rowNames.length * colNames.length];
484                 int kData = 0;
485                 for (int kCol = 1; kCol <= colNames.length; kCol++) {
486                     for (int kRow = 1; kRow <= rowNames.length; kRow++) {
487                         tableData[kData++] = stringValue[kCol * (stringValue.length / colNb) + kRow];
488                     }
489                 }
490
491                 if (tableData.length != 0) {
492                     setData(tableData);
493                 }
494                 break;
495             }
496             default: {
497                 SwingViewWidget.update(this, property, value);
498             }
499         }
500     }
501
502     public void resetBackground() {
503         Color color = (Color) UIManager.getLookAndFeelDefaults().get("ScrollPane.background");
504         if (color != null) {
505             setBackground(color);
506         }
507     }
508
509     public void resetForeground() {
510         Color color = (Color)UIManager.getLookAndFeelDefaults().get("ScrollPane.foreground");
511         if (color != null) {
512             setForeground(color);
513         }
514     }
515
516     /* Create a JTable and adds an event listener for updating table data */
517     private JTable createTable(Object[][] data, Object[] names) {
518         JTable table = new JTable(data, names);
519
520         table.getModel().addTableModelListener(new TableModelListener() {
521             public void tableChanged(TableModelEvent e) {
522                 int row = e.getFirstRow();
523                 int column = e.getColumn();
524                 Object data = ((TableModel)e.getSource()).getValueAt(row, column);
525
526                 String[] tableData = (String[]) GraphicController.getController().getProperty(uid, __GO_UI_STRING__);
527                 int ncols = (Integer) GraphicController.getController().getProperty(uid, __GO_UI_STRING_COLNB__);
528                 int nrows = tableData.length / ncols;
529                 tableData[(column + 1) * nrows + row + 1] = data.toString();
530                 GraphicController.getController().setProperty(uid, __GO_UI_STRING__, tableData);
531             }
532         });
533
534         return table;
535     }
536 }