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