* Rename style 'ImageRenderer' to 'Image'
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / tab / SwingScilabTab.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007-2008 - INRIA - Vincent Couvert
4  * Copyright (C) 2007 - INRIA - Bruno JOFRET
5  * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
6  * Copyright (C) 2011 - DIGITEO - Vincent Couvert
7  *
8  * This file must be used under the terms of the CeCILL.
9  * This source file is licensed as described in the file COPYING, which
10  * you should have received as part of this distribution.  The terms
11  * are also available at
12  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13  *
14  */
15
16 package org.scilab.modules.gui.bridge.tab;
17
18 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_AXES_SIZE__;
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_CALLBACK__;
20 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_CHILDREN__;
21 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_ID__;
22 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_NAME__;
23 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_POSITION__;
24 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_SIZE__;
25 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_TYPE__;
26 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UICHECKEDMENU__;
27 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UICHILDMENU__;
28 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UIMENU__;
29 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_UIPARENTMENU__;
30 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_INFO_MESSAGE__;
31
32 import java.awt.Color;
33 import java.awt.Component;
34 import java.awt.Container;
35 import java.awt.Dimension;
36 import java.awt.Graphics;
37 import java.awt.Image;
38 import java.awt.Point;
39 import java.awt.event.ComponentEvent;
40 import java.awt.event.ComponentListener;
41 import java.awt.event.FocusEvent;
42 import java.awt.event.FocusListener;
43 import java.awt.event.HierarchyBoundsListener;
44 import java.awt.event.HierarchyEvent;
45 import java.lang.reflect.InvocationTargetException;
46 import java.util.Iterator;
47
48 import javax.swing.Action;
49 import javax.swing.ImageIcon;
50 import javax.swing.SwingUtilities;
51
52 import org.flexdock.docking.DockingConstants;
53 import org.flexdock.docking.DockingPort;
54 import org.flexdock.docking.activation.ActiveDockableTracker;
55 import org.flexdock.docking.event.DockingEvent;
56 import org.flexdock.docking.props.PropertyChangeListenerFactory;
57 import org.flexdock.view.Titlebar;
58 import org.flexdock.view.View;
59 import org.scilab.modules.graphic_objects.figure.Figure;
60 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
61 import org.scilab.modules.gui.SwingView;
62 import org.scilab.modules.gui.SwingViewObject;
63 import org.scilab.modules.gui.bridge.canvas.SwingScilabCanvas;
64 import org.scilab.modules.gui.bridge.canvas.SwingScilabCanvasImpl;
65 import org.scilab.modules.gui.bridge.checkbox.SwingScilabCheckBox;
66 import org.scilab.modules.gui.bridge.console.SwingScilabConsole;
67 import org.scilab.modules.gui.bridge.editbox.SwingScilabEditBox;
68 import org.scilab.modules.gui.bridge.frame.SwingScilabFrame;
69 import org.scilab.modules.gui.bridge.helpbrowser.SwingScilabHelpBrowser;
70 import org.scilab.modules.gui.bridge.label.SwingScilabLabel;
71 import org.scilab.modules.gui.bridge.listbox.SwingScilabListBox;
72 import org.scilab.modules.gui.bridge.popupmenu.SwingScilabPopupMenu;
73 import org.scilab.modules.gui.bridge.pushbutton.SwingScilabPushButton;
74 import org.scilab.modules.gui.bridge.radiobutton.SwingScilabRadioButton;
75 import org.scilab.modules.gui.bridge.slider.SwingScilabSlider;
76 import org.scilab.modules.gui.bridge.tree.SwingScilabTree;
77 import org.scilab.modules.gui.bridge.uidisplaytree.SwingScilabUiDisplayTree;
78 import org.scilab.modules.gui.bridge.uiimage.SwingScilabUiImage;
79 import org.scilab.modules.gui.bridge.uitable.SwingScilabUiTable;
80 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
81 import org.scilab.modules.gui.canvas.Canvas;
82 import org.scilab.modules.gui.checkbox.CheckBox;
83 import org.scilab.modules.gui.console.Console;
84 import org.scilab.modules.gui.dockable.Dockable;
85 import org.scilab.modules.gui.editbox.EditBox;
86 import org.scilab.modules.gui.events.callback.CommonCallBack;
87 import org.scilab.modules.gui.events.callback.ScilabCloseCallBack;
88 import org.scilab.modules.gui.frame.Frame;
89 import org.scilab.modules.gui.helpbrowser.HelpBrowser;
90 import org.scilab.modules.gui.label.Label;
91 import org.scilab.modules.gui.listbox.ListBox;
92 import org.scilab.modules.gui.menubar.MenuBar;
93 import org.scilab.modules.gui.popupmenu.PopupMenu;
94 import org.scilab.modules.gui.pushbutton.PushButton;
95 import org.scilab.modules.gui.radiobutton.RadioButton;
96 import org.scilab.modules.gui.slider.Slider;
97 import org.scilab.modules.gui.tab.SimpleTab;
98 import org.scilab.modules.gui.textbox.TextBox;
99 import org.scilab.modules.gui.toolbar.ToolBar;
100 import org.scilab.modules.gui.tree.Tree;
101 import org.scilab.modules.gui.uidisplaytree.UiDisplayTree;
102 import org.scilab.modules.gui.uitable.UiTable;
103 import org.scilab.modules.gui.utils.BarUpdater;
104 import org.scilab.modules.gui.utils.Position;
105 import org.scilab.modules.gui.utils.SciClosingAction;
106 import org.scilab.modules.gui.utils.SciHelpOnComponentAction;
107 import org.scilab.modules.gui.utils.SciUndockingAction;
108 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
109 import org.scilab.modules.gui.utils.Size;
110 import org.scilab.modules.gui.utils.ToolBarBuilder;
111
112 /**
113  * Swing implementation for Scilab tabs in GUIs
114  * This implementation uses FlexDock package
115  * @author Bruno JOFRET
116  * @author Vincent COUVERT
117  * @author Marouane BEN JELLOUL
118  * @author Jean-Baptiste SILVY
119  */
120 public class SwingScilabTab extends View implements SwingViewObject, SimpleTab, FocusListener {
121
122     /** Use to put a component above any other object within its layer */
123     private static final int TOP_POSITION = 0;
124     /** Use to put a component below any other object within its layer */
125     private static final int BOTTOM_POSITION = -1;
126
127     private static final Image SCILAB_ICON = new ImageIcon(ScilabSwingUtilities.findIcon("scilab", "256x256")).getImage();
128
129     private static final long serialVersionUID = 1L;
130
131     private static final int VIEWPORT_SIZE = 4;
132
133     private static final String UNDOCK = "undock";
134     private static final String HELP = "help";
135
136     public static final String GRAPHICS_TOOLBAR_DESCRIPTOR = System.getenv("SCI") + "/modules/gui/etc/graphics_toolbar.xml";
137
138     private String id;
139
140     static {
141         PropertyChangeListenerFactory.addFactory(new BarUpdater.UpdateBarFactory());
142     }
143
144     private String parentWindowId;
145     private MenuBar menuBar;
146     private ToolBar toolBar;
147     private TextBox infoBar;
148     private String helpID;
149
150     /** Contains the canvas and widgets */
151     private SwingScilabAxes contentPane;
152
153     /** Scroll the axes */
154     private ScilabScrollPane scrolling;
155
156     private Image icon;
157
158     private Action closeAction;
159
160     /**
161      * Constructor
162      * @param name the name of the tab
163      * @param uuid an uuid to identify the tab
164      */
165     public SwingScilabTab(String name, String uuid) {
166         super(uuid, name, name);
167         //This button is "overloaded" when we add a callback
168         //this.addAction(DockingConstants.CLOSE_ACTION);
169         // Removed because make JOGL crash when "Unpin"
170         //this.addAction(DockingConstants.PIN_ACTION);
171         this.addAction(DockingConstants.ACTIVE_WINDOW);
172
173         // no need for an axes
174         contentPane = null;
175         scrolling = null;
176
177         this.setVisible(true);
178
179         getTitlebar().addFocusListener(this);
180         addFocusListener(this);
181         setCallback(null);
182     }
183
184     /**
185      * Create a graphic tab used to display a figure with 3D graphics and/or UIcontrols
186      * @param name name of the tab
187      * @param figureId id of the displayed figure
188      */
189     public SwingScilabTab(String name, int figureId) {
190         super(name, name, name);
191
192         // This button is "overloaded" when we add a callback
193         //this.addAction(DockingConstants.CLOSE_ACTION);
194         // Removed because make JOGL crash when "Unpin"
195         //this.addAction(DockingConstants.PIN_ACTION);
196         this.addAction(DockingConstants.ACTIVE_WINDOW);
197
198         // create the panel in which all the uiobjects will lie.
199         //contentPane = new SwingScilabAxes(figureId);
200
201         // add it inside a JSCrollPane
202         //scrolling = new SwingScilabScrollPane(contentPane);
203         //scrolling.setBackground(1, 0, 0);
204         // put in in the back of the tab
205         //setContentPane(scrolling.getAsContainer());
206
207         this.setVisible(true);
208
209         getTitlebar().addFocusListener(this);
210         addFocusListener(this);
211         setCallback(null);
212     }
213
214     /**
215      * Constructor
216      * @param name the name of the tab (used to identify it)
217      */
218     public SwingScilabTab(String name) {
219         this(name, name);
220     }
221
222     /**
223      * Set the associated help page
224      * @param helpID the xml id of the associated help page
225      */
226     public void setAssociatedXMLIDForHelp(String helpID) {
227         this.helpID = helpID;
228     }
229
230     /**
231      * Get the associated help page
232      * @return the xml id of the associated help page
233      */
234     public String getAssociatedXMLIDForHelp() {
235         return helpID;
236     }
237
238     public static void removeActions(SwingScilabTab tab) {
239         tab.setActionBlocked(DockingConstants.CLOSE_ACTION, true);
240         tab.setActionBlocked(UNDOCK, true);
241         tab.getTitlebar().revalidate();
242     }
243
244     public static void addActions(SwingScilabTab tab) {
245         tab.setActionBlocked(DockingConstants.CLOSE_ACTION, false);
246         tab.setActionBlocked(UNDOCK, false);
247         tab.getTitlebar().revalidate();
248     }
249
250     public SwingScilabTab(String figureTitle, int figureId, Figure figure) {
251         this(figureTitle, figureId);
252         /* OpenGL context */
253         SwingScilabCanvas canvas = new SwingScilabCanvas(figureId, figure);
254         setContentPane(canvas);
255         canvas.setVisible(true);
256
257         /* Manage figure_position property */
258         addHierarchyBoundsListener(new HierarchyBoundsListener() {
259             public void ancestorResized(HierarchyEvent arg0) {
260             }
261
262             public void ancestorMoved(HierarchyEvent e) {
263                 if (e.getChanged() instanceof SwingScilabWindow) {
264                     Position parentPosition =  SwingScilabWindow.allScilabWindows.get(parentWindowId).getPosition();
265                     Integer[] newPosition = new Integer[2];
266                     newPosition[0] = parentPosition.getX();
267                     newPosition[1] = parentPosition.getY();
268                     GraphicController.getController().setProperty(id, __GO_POSITION__, newPosition);
269                 }
270             }
271         });
272
273         /* Manage figure_size property */
274         addComponentListener(new ComponentListener() {
275
276             public void componentShown(ComponentEvent arg0) {
277             }
278
279             public void componentResized(ComponentEvent arg0) {
280                 /* Update the figure_size property */
281                 Size parentSize =  SwingScilabWindow.allScilabWindows.get(parentWindowId).getDims();
282                 Integer[] newSize = new Integer[2];
283                 newSize[0] = parentSize.getWidth();
284                 newSize[1] = parentSize.getHeight();
285                 GraphicController.getController().setProperty(id, __GO_SIZE__, newSize);
286                 /* Update the axes_size property */
287                 Dimension contentPaneSize = getContentPane().getSize();
288                 Integer[] newAxesSize = new Integer[2];
289                 newAxesSize[0] = contentPaneSize.width;
290                 newAxesSize[1] = contentPaneSize.height;
291                 GraphicController.getController().setProperty(id, __GO_AXES_SIZE__, newAxesSize);
292             }
293
294             public void componentMoved(ComponentEvent arg0) {
295             }
296
297             public void componentHidden(ComponentEvent arg0) {
298             }
299         });
300     }
301
302     /**
303      * @param e the FocusEvent
304      */
305     @Override
306     public void focusGained(FocusEvent e) {
307         //ActiveDockableTracker.requestDockableActivation(this);
308         if (contentPane != null) {
309             contentPane.requestFocus();
310         } else if (getContentPane() != null) {
311             getContentPane().requestFocus();
312         } else {
313             SwingScilabTab.this.requestFocusInWindow();
314         }
315     }
316
317     /**
318      * Call when the tab restoration is ended.
319      */
320     public void endedRestoration() { }
321
322     /**
323      * @return the window icon associated with this tab
324      */
325     public Image getWindowIcon() {
326         if (icon == null) {
327             return SCILAB_ICON;
328         } else {
329             return icon;
330         }
331     }
332
333     /**
334      * @param icon the window icon associated with this tab
335      */
336     public void setWindowIcon(Image icon) {
337         this.icon = icon;
338     }
339
340     /**
341      * @param the window icon associated with this tab
342      */
343     public void setWindowIcon(String iconName) {
344         setWindowIcon(new ImageIcon(ScilabSwingUtilities.findIcon(iconName, "256x256")).getImage());
345     }
346
347     /**
348      * @param e the FocusEvent
349      */
350     @Override
351     public void focusLost(FocusEvent e) { }
352
353     /**
354      * {@inheritDoc}
355      */
356     @Override
357     public void dockingComplete(DockingEvent evt) {
358         super.dockingComplete(evt);
359         DockingPort port = evt.getNewDockingPort();
360         Iterator iter = port.getDockables().iterator();
361
362         if (port.getDockables().size() > 1) {
363             while (iter.hasNext()) {
364                 Object d = iter.next();
365                 if (d instanceof SwingScilabTab) {
366                     SwingScilabTab view = (SwingScilabTab) d;
367                     addActions(view);
368                 }
369             }
370         } else {
371             removeActions(this);
372         }
373     }
374
375     /**
376      * Sets the Name of a swing Scilab tab
377      * @param newTabName the Name of the tab
378      * @see org.scilab.modules.gui.tab.Tab#setName()
379      */
380     @Override
381     public void setName(String newTabName) {
382         setTitle(newTabName, true);
383         getTitlePane().repaint();
384         SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this).setName(newTabName);
385     }
386
387     /**
388      * @return the UUID of the parent window
389      */
390     public String getParentWindowUUID() {
391         return ((SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this)).getUUID();
392     }
393
394     /**
395      * Gets the title of a swing Scilab tab
396      * @return the title of the tab
397      * @see org.scilab.modules.gui.tab.Tab#getTitle()
398      */
399     @Override
400     public String getName() {
401         return this.getTitle();
402     }
403
404     /**
405      * Paint immediately this component
406      */
407     public void paintImmediately() {
408         // paint all
409         paintImmediately(0, 0, getWidth(), getHeight());
410     }
411
412     /**
413      * Draws a swing Scilab tab
414      * @see org.scilab.modules.gui.uielement.UIElement#draw()
415      */
416     @Override
417     public void draw() {
418         if (SwingUtilities.isEventDispatchThread()) {
419             setVisible(true);
420             paintImmediately();
421         } else {
422             try {
423                 SwingUtilities.invokeAndWait(new Runnable() {
424                     @Override
425                     public void run() {
426                         setVisible(true);
427                         paintImmediately();
428                     }
429                 });
430             } catch (InterruptedException e) {
431                 e.printStackTrace();
432             } catch (InvocationTargetException e) {
433                 e.printStackTrace();
434             }
435         }
436
437     }
438
439     /**
440      * Gets the dimensions (width and height) of a swing Scilab tab
441      * @return the dimensions of the tab
442      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
443      */
444     @Override
445     public Size getDims() {
446         return new Size(this.getSize().width, this.getSize().height);
447     }
448
449     /**
450      * Get the size for the axes
451      * @return size of the axes in pixels
452      */
453     @Override
454     public Size getAxesSize() {
455         return new Size(contentPane.getWidth(), contentPane.getHeight());
456     }
457
458     /**
459      * @param newSize new size to set for the axes
460      */
461     @Override
462     public void setAxesSize(Size newSize) {
463         contentPane.setSize(new Dimension(newSize.getWidth(), newSize.getHeight()));
464     }
465
466     /**
467      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
468      * @return the position of the tab
469      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
470      */
471     @Override
472     public Position getPosition() {
473         return new Position(this.getX(), this.getY());
474     }
475
476     /**
477      * Sets the dimensions (width and height) of a swing Scilab tab
478      * @param newSize the dimensions we want to set to the tab
479      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
480      */
481     @Override
482     public void setDims(Size newSize) {
483         this.setSize(newSize.getWidth(), newSize.getHeight());
484     }
485
486     /**
487      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
488      * @param newPosition the position we want to set to the tab
489      * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
490      */
491     @Override
492     public void setPosition(Position newPosition) {
493         this.setLocation(newPosition.getX(), newPosition.getY());
494     }
495
496     /**
497      * Add a member (dockable element) to container and returns its index
498      * @param member the member to add
499      * @return index of member in ArrayList
500      */
501     @Override
502     public int addMember(Canvas member) {
503         int result;
504
505         if (SwingScilabCanvasImpl.isGLCanvasEnabled()) {
506             int[] currentView = getViewingRegion();
507             final SwingScilabTab thisF = this;
508             try {
509                 SwingUtilities.invokeAndWait(new Runnable() {
510                     @Override
511                     public void run() {
512                         scrolling = new AwtScilabScrollPane(contentPane, thisF);
513                         setContentPane(scrolling.getAsContainer());
514                         revalidate();
515
516                     }
517                 });
518             } catch (InterruptedException e) {
519                 e.printStackTrace();
520             } catch (InvocationTargetException e) {
521                 e.getCause().printStackTrace();
522             }
523             // set the canvas after doing every thing
524             result = contentPane.addMember(member);
525             // set the same viewport as before
526             setViewingRegion(currentView[0], currentView[1], currentView[2], currentView[2 + 1]);
527         } else {
528             result = contentPane.addMember(member);
529         }
530         return result;
531     }
532
533     /**
534      * We want to be able to remove directly a Canvas from a Tab.
535      * @param member canvas to remove
536      */
537     @Override
538     public void removeMember(Canvas member) {
539         contentPane.removeMember(member);
540         if (SwingScilabCanvasImpl.isGLCanvasEnabled()) {
541             try {
542                 SwingUtilities.invokeAndWait(new Runnable() {
543                     @Override
544                     public void run() {
545                         scrolling = new SwingScilabScrollPane(contentPane);
546                         setContentPane(scrolling.getAsContainer());
547                         revalidate();
548                     }
549                 });
550             } catch (InterruptedException e) {
551                 e.printStackTrace();
552             } catch (InvocationTargetException e) {
553                 e.getCause().printStackTrace();
554             }
555         }
556     }
557
558     /**
559      * Add a SwingViewObject (from SwingView.java) to container and returns its index
560      * @param member the member to add
561      */
562     public void addMember(SwingViewObject member) {
563         if (member instanceof SwingScilabFrame) {
564             this.add((Component) member, BOTTOM_POSITION);
565         } else {
566             this.add((Component) member, TOP_POSITION);
567         }
568     }
569
570     /**
571      * Add a member (dockable element) to container and returns its index
572      * @param member the member to add
573      * @return index of member in ArrayList
574      */
575     @Override
576     public int addMember(Console member) {
577         return this.addMember((SwingScilabConsole) member.getAsSimpleConsole());
578     }
579
580     /**
581      * Add a member (dockable element) to container and returns its index
582      * @param member the member to add
583      * @return index of member in ArrayList
584      */
585     private int addMember(SwingScilabConsole member) {
586         // replace the current content pane
587         this.setContentPane(member);
588         return this.getComponentZOrder(member);
589     }
590
591     /**
592      * Add a member (dockable element) to container and returns its index
593      * @param member the member to add
594      * @return index of member in ArrayList
595      */
596     @Override
597     public int addMember(HelpBrowser member) {
598         return this.addMember((SwingScilabHelpBrowser) member.getAsSimpleHelpBrowser());
599     }
600
601     /**
602      * Add a member (dockable element) to container and returns its index
603      * @param member the member to add
604      * @return index of member in ArrayList
605      */
606     private int addMember(SwingScilabHelpBrowser member) {
607         // replace the current content pane
608         this.setContentPane(member);
609         return this.getComponentZOrder(member);
610     }
611
612     /**
613      * Add a member (dockable element) to container and returns its index
614      * @param member the member to add
615      * @return index of member in ArrayList
616      */
617     @Override
618     public int addMember(Frame member) {
619         return this.addMember((SwingScilabFrame) member.getAsSimpleFrame());
620     }
621
622     /**
623      * Add a member (dockable element) to container and returns its index
624      * @param member the member to add
625      * @return index of member in ArrayList
626      */
627     private int addMember(SwingScilabFrame member) {
628         return contentPane.addFrame(member);
629     }
630
631     /**
632      * Remove a Frame from its container
633      * @param member the Frame to remove
634      */
635     @Override
636     public void removeMember(Frame member) {
637         this.removeMember((SwingScilabFrame) member.getAsSimpleFrame());
638     }
639
640     /**
641      * Remove a Frame from its container
642      * @param member the Frame to remove
643      */
644     private void removeMember(SwingScilabFrame member) {
645         contentPane.removeFrame(member);
646     }
647
648     /**
649      * Add a member (dockable element) to container and returns its index
650      * @param member the member to add
651      * @return index of member in ArrayList
652      */
653     @Override
654     public int addMember(PushButton member) {
655         return this.addMember((SwingScilabPushButton) member.getAsSimplePushButton());
656     }
657
658     /**
659      * Add a member (dockable element) to container and returns its index
660      * @param member the member to add
661      * @return index of member in ArrayList
662      */
663     private int addMember(SwingScilabPushButton member) {
664         int res = contentPane.addWidget(member);
665         repaint();
666         return res;
667     }
668
669     /**
670      * Remove a PushButton from its container
671      * @param member the PushButton to remove
672      */
673     @Override
674     public void removeMember(PushButton member) {
675         this.removeMember((SwingScilabPushButton) member.getAsSimplePushButton());
676     }
677
678     /**
679      * Remove a PushButton from its container
680      * @param member the PushButton to remove
681      */
682     private void removeMember(SwingScilabPushButton member) {
683         contentPane.remove(member);
684     }
685
686     /**
687      * Add a member (dockable element) to container and returns its index
688      * @param member the member to add
689      * @return index of member in ArrayList
690      */
691     @Override
692     public int addMember(EditBox member) {
693         return this.addMember((SwingScilabEditBox) member.getAsSimpleEditBox());
694     }
695
696     /**
697      * Add a member (dockable element) to container and returns its index
698      * @param member the member to add
699      * @return index of member in ArrayList
700      */
701     private int addMember(SwingScilabEditBox member) {
702         return contentPane.addWidget(member);
703     }
704
705     /**
706      * Remove an EditBox from its container
707      * @param member the EditBox to remove
708      */
709     @Override
710     public void removeMember(EditBox member) {
711         this.removeMember((SwingScilabEditBox) member.getAsSimpleEditBox());
712     }
713
714     /**
715      * Remove an EditBox from its container
716      * @param member the EditBox to remove
717      */
718     private void removeMember(SwingScilabEditBox member) {
719         contentPane.removeWidget(member);
720     }
721
722     /**
723      * Add a member (dockable element) to container and returns its index
724      * @param member the member to add
725      * @return index of member in ArrayList
726      */
727     @Override
728     public int addMember(Label member) {
729         return this.addMember((SwingScilabLabel) member.getAsSimpleLabel());
730     }
731
732     /**
733      * Add a member (dockable element) to container and returns its index
734      * @param member the member to add
735      * @return index of member in ArrayList
736      */
737     private int addMember(SwingScilabLabel member) {
738         return contentPane.addWidget(member);
739     }
740
741     /**
742      * Remove a Label from its container
743      * @param member the Label to remove
744      */
745     @Override
746     public void removeMember(Label member) {
747         this.removeMember((SwingScilabLabel) member.getAsSimpleLabel());
748     }
749
750     /**
751      * Remove a Label from its container
752      * @param member the Label to remove
753      */
754     private void removeMember(SwingScilabLabel member) {
755         contentPane.removeWidget(member);
756     }
757
758     /**
759      * Add a member (dockable element) to container and returns its index
760      * @param member the member to add
761      * @return index of member in ArrayList
762      */
763     @Override
764     public int addMember(CheckBox member) {
765         return this.addMember((SwingScilabCheckBox) member.getAsSimpleCheckBox());
766     }
767
768     /**
769      * Add a member (dockable element) to container and returns its index
770      * @param member the member to add
771      * @return index of member in ArrayList
772      */
773     private int addMember(SwingScilabCheckBox member) {
774         return contentPane.addWidget(member);
775     }
776
777     /**
778      * Remove a CheckBox from its container
779      * @param member the CheckBox to remove
780      */
781     @Override
782     public void removeMember(CheckBox member) {
783         this.removeMember((SwingScilabCheckBox) member.getAsSimpleCheckBox());
784     }
785
786     /**
787      * Remove a CheckBox from its container
788      * @param member the CheckBox to remove
789      */
790     private void removeMember(SwingScilabCheckBox member) {
791         contentPane.removeWidget(member);
792     }
793
794     /**
795      * Add a member (dockable element) to container and returns its index
796      * @param member the member to add
797      * @return index of member in ArrayList
798      */
799     @Override
800     public int addMember(RadioButton member) {
801         return this.addMember((SwingScilabRadioButton) member.getAsSimpleRadioButton());
802     }
803
804     /**
805      * Add a member (dockable element) to container and returns its index
806      * @param member the member to add
807      * @return index of member in ArrayList
808      */
809     private int addMember(SwingScilabRadioButton member) {
810         return contentPane.addWidget(member);
811     }
812
813     /**
814      * Remove a RadioButton from its container
815      * @param member the RadioButton to remove
816      */
817     @Override
818     public void removeMember(RadioButton member) {
819         this.removeMember((SwingScilabRadioButton) member.getAsSimpleRadioButton());
820     }
821
822     /**
823      * Remove a RadioButton from its container
824      * @param member the RadioButton to remove
825      */
826     private void removeMember(SwingScilabRadioButton member) {
827         contentPane.removeWidget(member);
828     }
829
830     /**
831      * Add a member (dockable element) to container and returns its index
832      * @param member the member to add
833      * @return index of member in ArrayList
834      */
835     private int addMember(SwingScilabUiImage member) {
836         return contentPane.addWidget(member);
837     }
838
839     /**
840      * Remove a Image from its container
841      * @param member the Image to remove
842      */
843     private void removeMember(SwingScilabUiImage member) {
844         contentPane.removeWidget(member);
845     }
846
847     /**
848      * Add a member (dockable element) to container and returns its index
849      * @param member the member to add
850      * @return index of member in ArrayList
851      */
852     public int addMember(UiDisplayTree member) {
853         return this.addMember((SwingScilabUiDisplayTree) member.getAsSimpleUiDisplayTree());
854     }
855
856     /**
857      * Add a member (dockable element) to container and returns its index
858      * @param member the member to add
859      * @return index of member in ArrayList
860      */
861     private int addMember(SwingScilabUiDisplayTree member) {
862         return contentPane.addWidget(member);
863     }
864
865     /**
866      * Remove a Tree from its container
867      * @param member the Tree to remove
868      */
869     public void removeMember(UiDisplayTree member) {
870         this.removeMember((SwingScilabUiDisplayTree) member.getAsSimpleUiDisplayTree());
871     }
872
873     /**
874      * Remove a Tree from its container
875      * @param member the Tree to remove
876      */
877     private void removeMember(SwingScilabUiDisplayTree member) {
878         contentPane.removeWidget(member);
879     }
880
881     /**
882      * Add a member (dockable element) to container and returns its index
883      * @param member the member to add
884      * @return index of member in ArrayList
885      */
886     public int addMember(UiTable member) {
887         return this.addMember((SwingScilabUiTable) member.getAsSimpleUiTable());
888     }
889
890     /**
891      * Add a member (dockable element) to container and returns its index
892      * @param member the member to add
893      * @return index of member in ArrayList
894      */
895     private int addMember(SwingScilabUiTable member) {
896         return contentPane.addWidget(member);
897     }
898
899     /**
900      * Remove a UiTable from its container
901      * @param member the UiTable to remove
902      */
903     public void removeMember(UiTable member) {
904         this.removeMember((SwingScilabUiTable) member.getAsSimpleUiTable());
905     }
906
907     /**
908      * Remove a UiTable from its container
909      * @param member the UiTable to remove
910      */
911     private void removeMember(SwingScilabUiTable member) {
912         contentPane.removeWidget(member);
913     }
914
915     /**
916      * Add a member (dockable element) to container and returns its index
917      * @param member the member to add
918      * @return index of member in ArrayList
919      */
920     public int addMember(Slider member) {
921         return this.addMember((SwingScilabSlider) member.getAsSimpleSlider());
922     }
923
924     /**
925      * Add a member (dockable element) to container and returns its index
926      * @param member the member to add
927      * @return index of member in ArrayList
928      */
929     private int addMember(SwingScilabSlider member) {
930         return contentPane.addWidget(member);
931     }
932
933     /**
934      * Remove a Slider from its container
935      * @param member the Slider to remove
936      */
937     @Override
938     public void removeMember(Slider member) {
939         this.removeMember((SwingScilabSlider) member.getAsSimpleSlider());
940     }
941
942     /**
943      * Remove a Slider from its container
944      * @param member the Slider to remove
945      */
946     private void removeMember(SwingScilabSlider member) {
947         contentPane.removeWidget(member);
948     }
949
950     /**
951      * Add a member (dockable element) to container and returns its index
952      * @param member the member to add
953      * @return index of member in ArrayList
954      */
955     @Override
956     public int addMember(ListBox member) {
957         return this.addMember((SwingScilabListBox) member.getAsSimpleListBox());
958     }
959
960     /**
961      * Add a member (dockable element) to container and returns its index
962      * @param member the member to add
963      * @return index of member in ArrayList
964      */
965     private int addMember(SwingScilabListBox member) {
966         return contentPane.addWidget(member);
967     }
968
969     /**
970      * Remove a ListBox from its container
971      * @param member the ListBox to remove
972      */
973     @Override
974     public void removeMember(ListBox member) {
975         this.removeMember((SwingScilabListBox) member.getAsSimpleListBox());
976     }
977
978     /**
979      * Remove a ListBox from its container
980      * @param member the ListBox to remove
981      */
982     private void removeMember(SwingScilabListBox member) {
983         contentPane.removeWidget(member);
984     }
985
986     /**
987      * Add a member (dockable element) to container and returns its index
988      * @param member the member to add
989      * @return index of member in ArrayList
990      */
991     @Override
992     public int addMember(PopupMenu member) {
993         return this.addMember((SwingScilabPopupMenu) member.getAsSimplePopupMenu());
994     }
995
996     /**
997      * Add a member (dockable element) to container and returns its index
998      * @param member the member to add
999      * @return index of member in ArrayList
1000      */
1001     private int addMember(SwingScilabPopupMenu member) {
1002         return contentPane.addWidget(member);
1003     }
1004
1005     /**
1006      * Remove a PopupMenu from its container
1007      * @param member the PopupMenu to remove
1008      */
1009     @Override
1010     public void removeMember(PopupMenu member) {
1011         this.removeMember((SwingScilabPopupMenu) member.getAsSimplePopupMenu());
1012     }
1013
1014     /**
1015      * Remove a PopupMenu from its container
1016      * @param member the PopupMenu to remove
1017      */
1018     private void removeMember(SwingScilabPopupMenu member) {
1019         contentPane.removeWidget(member);
1020     }
1021
1022     /**
1023      * Add a Tree member (dockable element) to container and returns its index
1024      * @param member the member to add
1025      * @return index of member in ArrayList
1026      */
1027     @Override
1028     public int addMember(Tree member) {
1029         return this.addMember((SwingScilabTree) member.getAsSimpleTree());
1030     }
1031
1032     /**
1033      * Add a Tree member (dockable element) to container and returns its index
1034      * @param member the member to add
1035      * @return index of member in ArrayList
1036      */
1037     public int addMember(SwingScilabTree member) {
1038         return contentPane.addWidget(member.getAsComponent());
1039     }
1040
1041     /**
1042      * Add a Tree member (dockable element) to container and returns its index
1043      * @param member the member to add
1044      * @return index of member in ArrayList
1045      */
1046     public int addTree(SwingScilabTree member) {
1047         this.setContentPane(member.getAsComponent());
1048         return this.getComponentZOrder(member.getAsComponent());
1049     }
1050
1051     /**
1052      * Remove a PopupMenu from its container
1053      * @param member the PopupMenu to remove
1054      */
1055     @Override
1056     public void removeMember(Tree member) {
1057         this.removeMember((SwingScilabTree) member.getAsSimpleTree());
1058     }
1059
1060     /**
1061      * Remove a PopupMenu from its container
1062      * @param member the PopupMenu to remove
1063      */
1064     private void removeMember(SwingScilabTree member) {
1065         contentPane.removeTree(member);
1066     }
1067
1068     /**
1069      * Add a member (dockable element) to container and returns its index
1070      * @param member the member to add
1071      * @return index of member in ArrayList
1072      */
1073     public int addMember(Dockable member) {
1074         // TODO Auto-generated method stub
1075         return 0;
1076     }
1077
1078     /**
1079      * Get the current status of the Tab in its parent
1080      * @return true is the tab is the tab currently "on top" in its parent
1081      */
1082     @Override
1083     public boolean isCurrentTab() {
1084         // TODO should not always return TRUE
1085         return true;
1086     }
1087
1088     /**
1089      * Get the parent window id for this tab
1090      * @return the id of the parent window
1091      */
1092     @Override
1093     public String getParentWindowId() {
1094         return this.parentWindowId;
1095     }
1096
1097     /**
1098      * Set the parent window id for this tab
1099      * @param id the id of the parent window
1100      */
1101     @Override
1102     public void setParentWindowId(String id) {
1103         this.parentWindowId = id;
1104     }
1105
1106     /**
1107      * Setter for MenuBar
1108      * @param newMenuBar : the MenuBar to set.
1109      * @see org.scilab.modules.gui.tab.SimpleTab#setMenuBar(org.scilab.modules.gui.menubar.MenuBar)
1110      */
1111     @Override
1112     public void setMenuBar(MenuBar newMenuBar) {
1113         this.menuBar = newMenuBar;
1114     }
1115
1116
1117     /**
1118      * Getter for MenuBar
1119      * @return MenuBar : the MenuBar associated to the Tab.
1120      * @see org.scilab.modules.gui.tab.SimpleTab#getMenuBar()
1121      */
1122     @Override
1123     public MenuBar getMenuBar() {
1124         return this.menuBar;
1125     }
1126
1127     /**
1128      * Setter for ToolBar
1129      * @param newToolBar : the ToolBar to set.
1130      * @see org.scilab.modules.gui.tab.SimpleTab#setToolBar(org.scilab.modules.gui.toolbar.ToolBar)
1131      */
1132     @Override
1133     public void setToolBar(ToolBar newToolBar) {
1134         this.toolBar = newToolBar;
1135     }
1136
1137     /**
1138      * Getter for ToolBar
1139      * @return ToolBar : the ToolBar associated to the Tab.
1140      * @see org.scilab.modules.gui.tab.SimpleTab#getToolBar()
1141      */
1142     @Override
1143     public ToolBar getToolBar() {
1144         return this.toolBar;
1145     }
1146
1147     /**
1148      * Setter for InfoBar
1149      * @param newInfoBar the InfoBar to set.
1150      */
1151     @Override
1152     public void setInfoBar(TextBox newInfoBar) {
1153         this.infoBar = newInfoBar;
1154     }
1155
1156     /**
1157      * Getter for InfoBar
1158      * @return the InfoBar associated to the Tab.
1159      */
1160     @Override
1161     public TextBox getInfoBar() {
1162         return this.infoBar;
1163     }
1164
1165     /**
1166      * Set the callback of the tab
1167      * @param callback the callback to set.
1168      */
1169     @Override
1170     public void setCallback(CommonCallBack callback) {
1171
1172         if (closeAction != null) {
1173             this.getTitlebar().removeAction(closeAction);
1174         }
1175
1176         if (callback != null) {
1177             closeAction = new SciClosingAction(this, callback);
1178         } else {
1179             closeAction = new SciClosingAction(this);
1180         }
1181
1182         closeAction.putValue(Action.NAME, DockingConstants.CLOSE_ACTION);
1183         ((Titlebar) getTitlePane()).removeAction(DockingConstants.CLOSE_ACTION);
1184         addAction(closeAction);
1185
1186         /* Undock button */
1187         SciUndockingAction undockAction = new SciUndockingAction(this);
1188         undockAction.putValue(Action.NAME, UNDOCK);
1189         ((Titlebar) getTitlePane()).removeAction(UNDOCK);
1190         addAction(undockAction);
1191
1192         /* Help button */
1193         SciHelpOnComponentAction helpAction = new SciHelpOnComponentAction(this);
1194         helpAction.putValue(Action.NAME, HELP);
1195         ((Titlebar) getTitlePane()).removeAction(HELP);
1196         addAction(helpAction);
1197     }
1198
1199     /**
1200      * Set this tab as the current tab of its parent Window
1201      */
1202     @Override
1203     public void setCurrent() {
1204         ActiveDockableTracker.requestDockableActivation(this);
1205     }
1206
1207     /**
1208      * Set the background color of the tab.
1209      * @param red red channel of the color
1210      * @param green green channel
1211      * @param blue blue channel
1212      */
1213     @Override
1214     public void setBackground(double red, double green, double blue) {
1215         Color newColor = new Color((float) red, (float) green, (float) blue);
1216         contentPane.setBackground(red, green, blue);
1217         scrolling.setBackground(red, green, blue);
1218         setBackground(newColor);
1219     }
1220
1221     /**
1222      * Get the part of the axes which is currently viewed
1223      * @return [x,y,w,h] array
1224      */
1225     @Override
1226     public int[] getViewingRegion() {
1227         return scrolling.getViewingRegion();
1228     }
1229
1230     /**
1231      * Specify a new viewport for the axes
1232      * For SwingScilabCanvas viewport can not be modified
1233      * since it match the parent tab size
1234      * @param posX X coordinate of upper left point of the viewport within the axes
1235      * @param posY Y coordinate of upper left point of the viewport within the axes
1236      * @param width width of the viewport
1237      * @param height height of the viewport
1238      */
1239     @Override
1240     public void setViewingRegion(int posX, int posY, int width, int height) {
1241         // Check that the canvas can be resized
1242         if (!scrolling.getAutoResizeMode()) {
1243             // don't set viewport size here it should always fit parent tab size
1244             // It seems that we must check the viewport size and positions
1245             // to get coherent values, otherwise the setViewPosition hangs...
1246             // there are three checks that must be performed for the two dimensions
1247             // - be sure that viewport position is greater than 0.
1248             // - if the viewport is larger than the canvas, then it can't be moved
1249             // - if the viewport is smaller than the canvas, then it should remains
1250             //   inside the canvas
1251
1252             int canvasWidth = contentPane.getWidth();
1253             int canvasHeight = contentPane.getHeight();
1254             int[] curViewedRegion = getViewingRegion();
1255             int viewportPosX = curViewedRegion[0];
1256             int viewPortPosY = curViewedRegion[1];
1257             int viewportWidth = curViewedRegion[2];
1258             int viewportHeight = curViewedRegion[VIEWPORT_SIZE - 1];
1259
1260             // use previous values as default ones
1261             int realPosX = 0;
1262             int realPosY = 0;
1263
1264
1265             if (viewportWidth <= canvasWidth) {
1266                 // viewport smaller than the canvas
1267                 // check that the viewport stays in the canvas
1268                 // the left most position is canvasWidth - viewporwidth
1269                 realPosX = Math.min(posX, canvasWidth - viewportWidth);
1270             } else {
1271                 // viewport larger than the canvas
1272                 // get previous position (should be 0)
1273                 realPosX = viewportPosX;
1274             }
1275             // last check, greater than 0
1276             realPosX = Math.max(0, realPosX);
1277
1278             if (viewportHeight <= canvasHeight) {
1279                 realPosY = Math.min(posY, canvasHeight - viewportHeight);
1280             } else {
1281                 realPosY = viewPortPosY;
1282             }
1283             realPosY = Math.max(0, realPosY);
1284
1285             // must be called on the Swing thread otherwise some JOGL corruption may appear
1286             final Point realPos = new Point(realPosX, realPosY);
1287             try {
1288                 SwingUtilities.invokeAndWait(new Runnable() {
1289                     @Override
1290                     public void run() {
1291                         scrolling.setViewPosition(realPos.x, realPos.y);
1292                     }
1293                 });
1294             } catch (InterruptedException e) {
1295                 e.printStackTrace();
1296             } catch (InvocationTargetException e) {
1297                 e.getCause().printStackTrace();
1298             }
1299
1300
1301         }
1302     }
1303
1304     /**
1305      * Set the event handler of the Canvas
1306      * @param funName the name of the Scilab function to call
1307      */
1308     @Override
1309     public void setEventHandler(String funName) {
1310         contentPane.setEventHandler(funName);
1311     }
1312
1313
1314     /**
1315      * Set the status of the event handler of the Canvas
1316      * @param status is true to set the event handler active
1317      */
1318     @Override
1319     public void setEventHandlerEnabled(boolean status) {
1320         contentPane.setEventHandlerEnabled(status);
1321     }
1322
1323     /**
1324      * Specify whether the canvas should fit the parent tab size
1325      * (and consequently the scrollpane size) or not
1326      * @param onOrOff true to enable autoresize mode
1327      */
1328     @Override
1329     public void setAutoResizeMode(boolean onOrOff) {
1330         scrolling.setAutoResizeMode(onOrOff);
1331     }
1332
1333     /**
1334      * @return whether the resize mode is on or off
1335      */
1336     @Override
1337     public boolean getAutoResizeMode() {
1338         return scrolling.getAutoResizeMode();
1339     }
1340
1341     /**
1342      * Get the displacement in pixel that should be used for rotating axes
1343      * @param displacement out parameter, [x,y] array of displacement in pixels
1344      * @return true if the displacement recording continue, false otherwise
1345      */
1346     @Override
1347     public boolean getRotationDisplacement(int[] displacement) {
1348         return contentPane.getRotationDisplacement(displacement);
1349     }
1350
1351     /**
1352      * Close the tab and disable it.
1353      */
1354     public void close() {
1355         setMenuBar(null);
1356         setToolBar(null);
1357         setInfoBar(null);
1358         setTitlebar(null);
1359         removeAll();
1360         setActive(false);
1361
1362         scrolling = null;
1363         contentPane = null;
1364
1365         // without this children canvas are not released.
1366         Container dummyContainer = new Container();
1367         this.setContentPane(dummyContainer);
1368     }
1369
1370     /**
1371      * Asynchronous stop of rotation tracking.
1372      */
1373     @Override
1374     public void stopRotationRecording() {
1375         contentPane.stopRotationRecording();
1376     }
1377
1378     /**
1379      * Redefine paint children to be sure that AWT components are well painted.
1380      *  @param g a Graphics
1381      */
1382     @Override
1383     public void paintChildren(Graphics g) {
1384         Component[] children = getComponents();
1385         for (int i = 0; i < children.length; i++) {
1386             // AWT children don't draw themselves automatically
1387             // so force their draw
1388             if (!children[i].isLightweight()) {
1389                 children[i].paint(g);
1390             }
1391         }
1392         super.paintChildren(g);
1393     }
1394
1395     /**
1396      * Update the tab after a modification of its properties
1397      * @param property the property name
1398      * @param value the property value
1399      * @see org.scilab.modules.gui.SwingViewObject#update(java.lang.String, java.lang.Object)
1400      */
1401     public void update(String property, Object value) {
1402         if (property.equals(__GO_NAME__)) {
1403             String name = ((String) value);
1404             Integer figureId = (Integer) GraphicController.getController().getProperty(getId(), __GO_ID__);
1405             updateTitle(name, figureId);
1406         } else if (property.equals(__GO_ID__)) {
1407             /* Update title */
1408             Integer figureId = ((Integer) value);
1409             String name = (String) GraphicController.getController().getProperty(getId(), __GO_NAME__);
1410             updateTitle(name, figureId);
1411
1412             /** Update tool bar */
1413             setToolBar(ToolBarBuilder.buildToolBar(GRAPHICS_TOOLBAR_DESCRIPTOR, figureId));
1414             SwingScilabWindow parentWindow = SwingScilabWindow.allScilabWindows.get(getParentWindowId());
1415             parentWindow.addToolBar(getToolBar());
1416
1417             /* Update callback */
1418             String closingCommand =
1419                 "if (get_figure_handle(" + figureId + ") <> []) then"
1420                 +      "  if (get(get_figure_handle(" + figureId + "), 'event_handler_enable') == 'on') then"
1421                 +      "    execstr(get(get_figure_handle(" + figureId + "), 'event_handler')+'(" + figureId + ", -1, -1, -1000)', 'errcatch', 'm');"
1422                 +      "  end;"
1423                 +      "  delete(get_figure_handle(" + figureId + "));"
1424                 +      "end;";
1425             setCallback(null);
1426             setCallback(ScilabCloseCallBack.create(getId(), closingCommand));
1427             /* Update menus callbacks */
1428             String[] children = (String[]) GraphicController.getController().getProperty(getId(), __GO_CHILDREN__);
1429             updateChildrenCallbacks(children, figureId);
1430         } else if (property.equals(__GO_SIZE__)) {
1431             Integer[] size = (Integer[]) value;
1432             SwingScilabWindow.allScilabWindows.get(parentWindowId).setDims(new Size(size[0], size[1]));
1433         } else if (property.equals(__GO_POSITION__)) {
1434             Integer[] position = (Integer[]) value;
1435             SwingScilabWindow.allScilabWindows.get(parentWindowId).setPosition(new Position(position[0], position[1]));
1436         } else if (property.equals(__GO_AXES_SIZE__)) {
1437             Integer[] axesSize = (Integer[]) value;
1438             Dimension oldAxesSize = getContentPane().getSize();
1439             if (oldAxesSize.getWidth() != axesSize[0] || oldAxesSize.getHeight() != axesSize[1]) {
1440                 // Autoresize == "on" management
1441                 // TODO manage scrolling in with autoresize mode set to "off"
1442                 // TODO manage tabs when there are docked (do not change the window size if more than one tab docked)
1443                 int deltaX = axesSize[0] - (int) oldAxesSize.getWidth();
1444                 int deltaY = axesSize[1] - (int) oldAxesSize.getHeight();
1445                 Size parentWindowSize = SwingScilabWindow.allScilabWindows.get(parentWindowId).getDims();
1446                 SwingScilabWindow.allScilabWindows.get(parentWindowId).setDims(
1447                     new Size(parentWindowSize.getWidth() + deltaX, parentWindowSize.getHeight() + deltaY));
1448             }
1449         } else if (property.equals(__GO_INFO_MESSAGE__)) {
1450             getInfoBar().setText((String) value);
1451         }
1452     }
1453
1454     /**
1455      * Update the menus callbacks when they are linked to the figure ID
1456      * @param children the children UID
1457      * @param parentFigureId the figure ID
1458      */
1459     private void updateChildrenCallbacks(String[] children, int parentFigureId) {
1460         for (int kChild = 0; kChild < children.length; kChild++) {
1461             String childType = (String) GraphicController.getController().getProperty(children[kChild], __GO_TYPE__);
1462             if (childType.equals(__GO_UIMENU__)
1463                     || childType.equals(__GO_UIPARENTMENU__)
1464                     || childType.equals(__GO_UICHILDMENU__)
1465                     || childType.equals(__GO_UICHECKEDMENU__)) {
1466                 String cb = (String) GraphicController.getController().getProperty(children[kChild], __GO_CALLBACK__);
1467                 SwingView.getFromId(children[kChild]).update(__GO_CALLBACK__, replaceFigureID(cb, parentFigureId));
1468                 String[] menuChildren = (String[]) GraphicController.getController().getProperty(children[kChild], __GO_CHILDREN__);
1469                 updateChildrenCallbacks(menuChildren, parentFigureId);
1470             }
1471         }
1472     }
1473
1474     /**
1475      * Replace pattern [SCILAB_FIGURE_ID] by the figure index
1476      * @param initialString string read in XML file
1477      * @param parentFigureId the figure ID
1478      * @return callback string
1479      */
1480     private String replaceFigureID(String initialString, Integer parentFigureId) {
1481         return initialString.replaceAll("\\[SCILAB_FIGURE_ID\\]", Integer.toString(parentFigureId));
1482     }
1483
1484     /**
1485      * Update the title of the Tab
1486      * @param figureName figure_name property
1487      * @param figureId figure_id property
1488      */
1489     private void updateTitle(String figureName, Integer figureId) {
1490         if ((figureName != null) && (figureId != null)) {
1491             String figureTitle = figureName.replaceFirst("%d", figureId.toString());
1492             setName(figureTitle);
1493         }
1494     }
1495
1496     /**
1497      * Get the tab UID
1498      * @return the UID
1499      * @see org.scilab.modules.gui.SwingViewObject#getId()
1500      */
1501     public String getId() {
1502         return id;
1503     }
1504
1505     /** Set the tab UID
1506      * @param id the UID
1507      * @see org.scilab.modules.gui.SwingViewObject#setId(java.lang.String)
1508      */
1509     public void setId(String id) {
1510         this.id = id;
1511     }
1512 }