Merge remote-tracking branch 'origin/master' into uiwidget
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / uiwidget / UIComponent.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.gui.uiwidget;
14
15 import java.awt.BorderLayout;
16 import java.awt.Color;
17 import java.awt.Component;
18 import java.awt.Container;
19 import java.awt.Cursor;
20 import java.awt.Dimension;
21 import java.awt.Font;
22 import java.awt.GridBagLayout;
23 import java.awt.KeyEventDispatcher;
24 import java.awt.KeyboardFocusManager;
25 import java.awt.LayoutManager;
26 import java.awt.Point;
27 import java.awt.event.KeyEvent;
28 import java.awt.event.MouseAdapter;
29 import java.awt.font.TextAttribute;
30 import java.awt.geom.Rectangle2D;
31 import java.awt.image.BufferedImage;
32 import java.io.File;
33 import java.lang.reflect.Constructor;
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.TreeMap;
42
43 import javax.imageio.ImageIO;
44 import javax.swing.JComponent;
45 import javax.swing.JFrame;
46 import javax.swing.JPopupMenu;
47 import javax.swing.JScrollBar;
48 import javax.swing.JScrollPane;
49 import javax.swing.JTabbedPane;
50 import javax.swing.RootPaneContainer;
51 import javax.swing.ScrollPaneConstants;
52 import javax.swing.SwingUtilities;
53
54 import org.flexdock.view.View;
55 import org.scilab.modules.commons.ScilabCommonsUtils;
56 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
57 import org.scilab.modules.gui.utils.ScilabRelief;
58 import org.scilab.modules.types.ScilabType;
59 import org.scilab.modules.gui.uiwidget.callback.UICallback;
60 import org.scilab.modules.gui.uiwidget.components.NoLayout;
61 import org.scilab.modules.gui.uiwidget.components.UIFocusListener;
62 import org.scilab.modules.gui.uiwidget.components.UIMouseListener;
63 import org.scilab.modules.gui.uiwidget.components.UITab;
64 import org.scilab.modules.gui.uiwidget.components.UITools;
65 import org.xml.sax.Attributes;
66
67 /**
68  * Main class to handle Java components.
69  */
70 public abstract class UIComponent {
71
72     static {
73         ScilabCommonsUtils.loadOnUse("graphics");
74     }
75
76     private static final MouseAdapter NOMOUSE = new MouseAdapter() { };
77     private static final KeyEventDispatcher NOKEY = new KeyEventDispatcher() {
78         public boolean dispatchKeyEvent(KeyEvent e) {
79             return true;
80         }
81     };
82
83     private static int UID = 0;
84
85     protected Object component;
86     protected Object modifiableComponent;
87     private boolean thisOrComponent = true;
88     private String id;
89     private int uid;
90     protected UIComponent root;
91     protected UIComponent parent;
92     protected Map<String, UIButtonGroup> buttonGroups;
93     protected Map<String, UIComponent> children;
94     protected List<UIComponent> childrenList;
95     protected Map<String, Map<String, String>> style;
96     protected UIMouseListener mouseListener;
97     protected UIFocusListener focusListener;
98     protected String path;
99     protected Map<String, String> constraint;
100     protected Map<String, String> uistyle;
101     protected String tabTitle;
102     protected boolean enableEvents = true;
103     protected String relief;
104     protected UITools.FontUnit fontUnit = UITools.FontUnit.POINTS;
105
106     protected NoLayout.NoLayoutConstraint nolayoutconstraint;
107
108     /**
109      * Default empty constructor
110      */
111     protected UIComponent() { }
112
113     /**
114      * Constructor
115      * @param parent the parent UIComponent
116      */
117     public UIComponent(UIComponent parent) throws UIWidgetException {
118         this.parent = parent;
119         this.uid = UID++;
120
121         if (this.parent != null) {
122             this.root = this.parent.root;
123         } else {
124             this.root = this;
125         }
126         UILocator.add(this);
127         registerToParent();
128     }
129
130     /**
131      * Register this component to its parent
132      */
133     private final void registerToParent() {
134         if (!isRoot()) {
135             if (parent.childrenList == null) {
136                 parent.childrenList = new ArrayList<UIComponent>();
137             }
138             parent.childrenList.add(this);
139         }
140     }
141
142     /**
143      * Register id to parent
144      */
145     private final void registerIdToParent() {
146         if (parent != null && parent.path != null && id != null) {
147             if (parent.children == null) {
148                 parent.children = new HashMap<String, UIComponent>();
149             }
150
151             parent.children.put(id, this);
152         }
153     }
154
155     /**
156      * Get a Map from Attributes object
157      * @param attributes the attributes
158      * @return a Map containing the pairs attribute-name -- attribute-value
159      */
160     public static final StringMap getMapFromAttributes(Attributes attributes) {
161         final int len = attributes != null ? attributes.getLength() : 0;
162         StringMap map = new StringMap(len);
163         for (int i = 0; i < len; i++) {
164             map.put(attributes.getLocalName(i), attributes.getValue(i));
165         }
166
167         return map;
168     }
169
170     /**
171      * Construct an UIComponent
172      * @param pack the Java package name containing the component to instantiate
173      * @param name the UIComponent name
174      * @param attributes an array of length 2xN containing attributes name and value
175      * @param parent the parent UIComponent
176      * @return the newly constructed UIComponent
177      */
178     public static final UIComponent getUIComponent(String pack, String name, String[] attributes, UIComponent parent) throws UIWidgetException {
179         final int len = attributes != null ? (attributes.length % 2 == 0 ? attributes.length : attributes.length - 1) : 0;
180         StringMap map = new StringMap(len);
181         for (int i = 0; i < len; i += 2) {
182             map.put(attributes[i], attributes[i + 1]);
183         }
184
185         return getUIComponent(pack, name, map, parent, parent == null ? null : parent.style);
186     }
187
188     /**
189      * Construct an UIComponent
190      * @param pack the Java package name containing the component to instantiate
191      * @param name the UIComponent name
192      * @param attributes the attributes
193      * @param parent the parent UIComponent
194      * @return the newly constructed UIComponent
195      */
196     public static final UIComponent getUIComponent(String pack, String name, Attributes attributes, UIComponent parent, Map<String, Map<String, String>> style) throws UIWidgetException {
197         return getUIComponent(pack, name, getMapFromAttributes(attributes), parent, style);
198     }
199
200     /**
201      * Construct an UIComponent
202      * @param pack the Java package name containing the component to instantiate
203      * @param name the UIComponent name
204      * @param attributes the attributes
205      * @param parent the parent UIComponent
206      * @return the newly constructed UIComponent
207      */
208     public static final UIComponent getUIComponent(String pack, String name, ConvertableMap attributes, final UIComponent parent, Map<String, Map<String, String>> style) throws UIWidgetException {
209         try {
210             Class clazz = UIClassFinder.findClass(pack, name);
211             final Constructor constructor = clazz.getConstructor(UIComponent.class);
212             final UIComponent[] arr = new UIComponent[1];
213
214             if (SwingUtilities.isEventDispatchThread()) {
215                 arr[0] = (UIComponent) constructor.newInstance(parent);
216             } else {
217                 try {
218                     SwingUtilities.invokeAndWait(new Runnable() {
219                         public void run() {
220                             try {
221                                 arr[0] = (UIComponent) constructor.newInstance(parent);
222                             } catch (InvocationTargetException e) {
223                                 System.err.println(e.getCause());
224                                 e.getCause().printStackTrace();
225                             } catch (Exception e) {
226                                 System.err.println(e);
227                                 e.printStackTrace();
228                             }
229                         }
230                     });
231                 } catch (InvocationTargetException e) {
232                     System.err.println(e.getCause());
233                     e.getCause().printStackTrace();
234                     return null;
235                 } catch (Exception e) {
236                     System.err.println(e);
237                     e.printStackTrace();
238                     return null;
239                 }
240             }
241             UIComponent ui = arr[0];
242             String id = null;
243             if (attributes.containsKey("id")) {
244                 id = (String) attributes.get(String.class, "id", null);
245                 attributes.remove("id");
246             } else if (attributes.containsKey("tag")) {
247                 id = (String) attributes.get(String.class, "tag", null);
248                 attributes.remove("tag");
249             }
250             ui.setId(id);
251             ui.setMapStyle(style);
252             String tabTitle = (String) attributes.get(String.class, "tab-title", null);
253             if (tabTitle != null) {
254                 ui.setTabTitle(tabTitle);
255                 attributes.remove("tab-title");
256             }
257             ui.createNewInstance(attributes);
258             try {
259                 //ui.getPropertiesPairs();
260             } catch (Exception e) {
261                 e.printStackTrace();
262             }
263
264             return ui;
265         } catch (ClassNotFoundException e) {
266             throw new UIWidgetException("Cannot find the class " + pack + "." + name);
267         } catch (NoSuchMethodException e) {
268             throw new UIWidgetException("Cannot find a valid constructor in class " + pack + "." + name + ":\n" + e.getMessage());
269         } catch (SecurityException e) {
270             throw new UIWidgetException("Cannot find a valid constructor in class " + pack + "." + name + ":\n" + e.getMessage());
271         } catch (InstantiationException e) {
272             throw new UIWidgetException("Cannot instantiate the class " + pack + "." + name + ":\n" + e.getMessage());
273         } catch (IllegalAccessException e) {
274             throw new UIWidgetException("Cannot instantiate the class " + pack + "." + name + ":\n" + e.getMessage());
275         } catch (IllegalArgumentException e) {
276             throw new UIWidgetException("Cannot instantiate the class " + pack + "." + name + ":\n" + e.getMessage());
277         } catch (InvocationTargetException e) {
278             System.err.println(e);
279             e.getTargetException().printStackTrace();
280             throw new UIWidgetException("Cannot instantiate the class " + pack + "." + name + ":\n" + e.getCause());
281         }
282     }
283
284     public void setNoLayoutConstraint(double x, double y, double width, double height) {
285         if (nolayoutconstraint == null) {
286             nolayoutconstraint = new NoLayout.NoLayoutConstraint();
287         }
288         nolayoutconstraint.setPoint(x, y);
289         nolayoutconstraint.setDims(width, height);
290     }
291
292     public void setNoLayoutConstraint(double width, double height) {
293         if (nolayoutconstraint == null) {
294             nolayoutconstraint = new NoLayout.NoLayoutConstraint();
295             nolayoutconstraint.setPoint(0, 0);
296         }
297         nolayoutconstraint.setDims(width, height);
298     }
299
300     /**
301      * Create a new instance of this UIComponent
302      * @return the created instance
303      */
304     public abstract Object newInstance();
305
306     /**
307      * Get the backed component
308      * @return the component
309      */
310     public Object getComponent() {
311         return component;
312     }
313
314     /**
315      * Set the component
316      * @param o the component
317      */
318     public void setComponent(Object o) {
319         if (this.component != o) {
320             if (this.component != null) {
321                 this.modifiableComponent = null;
322             }
323             this.component = o;
324
325             initialize();
326         }
327     }
328
329     /**
330      * Initialize the component if mandatory
331      */
332     protected void initialize() {
333
334     }
335
336     /**
337      * Get the Scilab representation as used in %h_p.sci
338      * @return an array of string to be evstr
339      */
340     public String[] getScilabRepresentation() {
341         return null;
342     }
343
344     /**
345      * Enable events
346      * @param b if true events are enabled
347      */
348     public void setEnableEvents(boolean b) {
349         if (b != this.enableEvents) {
350             RootPaneContainer root = null;
351             if (component instanceof JComponent) {
352                 root = (RootPaneContainer) ((JComponent) component).getTopLevelAncestor();
353             } else if (component instanceof RootPaneContainer) {
354                 root = (RootPaneContainer) component;
355             }
356             if (root != null) {
357                 root.getGlassPane().setVisible(!b);
358                 if (b) {
359                     KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(NOKEY);
360                     root.getGlassPane().removeMouseListener(NOMOUSE);
361                 } else {
362                     KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(NOKEY);
363                     root.getGlassPane().addMouseListener(NOMOUSE);
364                 }
365             }
366             this.enableEvents = b;
367         }
368     }
369
370     /**
371      * Check if events are enabled
372      * @return true if the events are enabled
373      */
374     public boolean getEnableEvents() {
375         return this.enableEvents;
376     }
377
378     public void setScreenShot(String file) {
379         Component c = null;
380         if (component instanceof JFrame) {
381             c = ((JFrame) component).getRootPane();
382         } else if (component instanceof Component) {
383             c = (Component) component;
384         }
385
386         if (c != null) {
387             BufferedImage image = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_RGB);
388             c.paint(image.getGraphics());
389
390             try {
391                 ImageIO.write(image, "png", new File(file));
392             } catch (Exception e) {
393                 e.printStackTrace();
394             }
395         }
396     }
397
398     /**
399      * Set the cursor
400      * @param cursor the cursor
401      */
402     public void setCursor(Cursor cursor) {
403         if (component instanceof Component) {
404             ((Component) component).setCursor(cursor);
405         }
406     }
407
408     /**
409      * Get the cursor
410      * @return the cursor
411      */
412     public Cursor getCursor() {
413         if (component instanceof Component) {
414             return ((Component) component).getCursor();
415         }
416
417         return null;
418     }
419
420     /**
421      * Get the modifiable component (can be different of component, e.g. with a JScrollPane containing the component)xs
422      * @return the modfifiable component
423      */
424     public Object getModifiableComponent() {
425         return modifiableComponent == null ? component : modifiableComponent;
426     }
427
428     /**
429      * Get the modifiable component as a JComponent
430      * @return modifiable JComponent
431      */
432     public JComponent getModifiableJComponent() throws UIWidgetException {
433         Object c = getModifiableComponent();
434         if (c instanceof JComponent) {
435             return (JComponent) c;
436         }
437
438         throw new UIWidgetException("Not a JComponent");
439     }
440
441     /**
442      * Get the component as a JComponent
443      * @return the JComponent
444      */
445     public JComponent getJComponent() throws UIWidgetException {
446         Object c = getComponent();
447         if (c instanceof JComponent) {
448             return (JComponent) c;
449         }
450
451         throw new UIWidgetException("Not a JComponent");
452     }
453
454     /**
455      * Get the modifiable component as a Container
456      * @return the Container
457      */
458     public Container getModifiableContainer() throws UIWidgetException {
459         Object c = getModifiableComponent();
460         if (c instanceof Container) {
461             return (Container) c;
462         }
463
464         throw new UIWidgetException("Not a Container");
465     }
466
467     /**
468      * Get the component as a Container
469      * @return the Container
470      */
471     public Container getContainer() throws UIWidgetException {
472         Object c = getComponent();
473         if (c instanceof Container) {
474             return (Container) c;
475         }
476
477         throw new UIWidgetException("Not a Container");
478     }
479
480     /**
481      * Get the layout constraint
482      * @return the constraint
483      */
484     public Map<String, String> getLayoutConstraint() {
485         return this.constraint;
486     }
487
488     /**
489      * @return the UIComponent name
490      */
491     public String getType() {
492         return "UIWidget";
493     }
494
495     /**
496      * @return the UIComponent name
497      */
498     public String getStyle() {
499         return this.getClass().getSimpleName();
500     }
501
502     /**
503      * @return the component visibility
504      */
505     public boolean getHandleVisible() {
506         if (component instanceof Component) {
507             return ((Component) component).isVisible();
508         }
509
510         return false;
511     }
512
513     /**
514      * Set component visibility
515      * @param b true to make it visible
516      */
517     public void setHandleVisible(boolean b) {
518         if (component instanceof Component) {
519             ((Component) component).setVisible(b);
520         }
521     }
522
523     /**
524      * @return the uid
525      */
526     public int getUid() {
527         return uid;
528     }
529
530     /**
531      * Check the component validity
532      * @return true if the component is valid
533      */
534     public boolean isValid() {
535         return component != null;
536     }
537
538     /**
539      * Set the preferred size
540      * @param dim the preferred dimension
541      */
542     public void setPreferredSize(Dimension dim) throws UIWidgetException {
543         getContainer().setPreferredSize(dim);
544     }
545
546     /**
547      * Get the preferred size
548      * @return the preferred dimension
549      */
550     public Dimension getPreferredSize() throws UIWidgetException {
551         return getContainer().getPreferredSize();
552     }
553
554     /**
555      * Set the size
556      * @param d the size
557      */
558     public void setSize(Dimension d) throws UIWidgetException {
559         if (getComponent() instanceof Component) {
560             Component c = (Component) getComponent();
561             Container p = c.getParent();
562             if (p != null && p.getLayout() instanceof NoLayout) {
563                 setNoLayoutConstraint((double) d.width, (double) d.height);
564                 if (p != null && p.isVisible()) {
565                     p.invalidate();
566                     p.validate();
567                     p.repaint();
568                 }
569             } else {
570                 if (!c.getSize().equals(d)) {
571                     JFrame win = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, c);
572                     if (win != null) {
573                         win.setPreferredSize(null);
574                         if (c instanceof SwingScilabTab) {
575                             c.setPreferredSize(d);
576                         } else {
577                             c.setSize(d);
578                         }
579                         if (win.isVisible()) {
580                             win.invalidate();
581                             win.pack();
582                         }
583                     }
584                 }
585             }
586         }
587
588     }
589
590     /**
591      * Get the size
592      * @return the dimension
593      */
594     public Dimension getSize() throws UIWidgetException {
595         return getContainer().getSize();
596     }
597
598     /**
599      * Set the minimum size
600      * @param dim the minimum dimension
601      */
602     public void setMinimumSize(Dimension dim) throws UIWidgetException {
603         getContainer().setMinimumSize(dim);
604     }
605
606     /**
607      * Get the minimum size
608      * @return the minimum dimension
609      */
610     public Dimension getMinimumSize() throws UIWidgetException {
611         return getContainer().getMinimumSize();
612     }
613
614     /**
615      * Set the maximum size
616      * @param dim the maximum dimension
617      */
618     public void setMaximumSize(Dimension dim) throws UIWidgetException {
619         getContainer().setMaximumSize(dim);
620     }
621
622     /**
623      * Get the maximum size
624      * @return the maximum dimension
625      */
626     public Dimension getMaximumSize() throws UIWidgetException {
627         return getContainer().getMaximumSize();
628     }
629
630     /**
631      * Set the parent
632      * @param parent the parent
633      */
634     public void setParent(UIComponent parent) throws UIWidgetException {
635         if (parent != this.parent) {
636             if (this.parent != null && this.parent.children != null && id != null) {
637                 this.parent.children.remove(id);
638             }
639             if (this.parent != null && this.parent.childrenList != null) {
640                 this.parent.childrenList.remove(this);
641             }
642             if (isRoot() && buttonGroups != null) {
643                 if (parent.root.buttonGroups == null) {
644                     parent.root.buttonGroups = buttonGroups;
645                 } else {
646                     parent.root.buttonGroups.putAll(buttonGroups);
647                 }
648                 buttonGroups = null;
649             }
650
651             UILocator.removeFromCachedPaths(this);
652             this.parent = parent;
653             setRoot(parent == null ? this : parent.root);
654             invalidateUIPath();
655             registerToParent();
656             registerIdToParent();
657             if (isRoot()) {
658                 UILocator.addRoot(this);
659             } else {
660                 parent.add(this);
661             }
662         }
663     }
664
665     /**
666      * Set the root element
667      * @param root the root element
668      */
669     private void setRoot(final UIComponent root) {
670         this.root = root;
671         if (childrenList != null) {
672             for (UIComponent c : childrenList) {
673                 if (root == null) {
674                     c.setRoot(this);
675                 } else {
676                     c.setRoot(root);
677                 }
678             }
679         }
680     }
681
682     /**
683      * Set the parent with the given id
684      * @param parentId the id of the parent
685      */
686     public void setParent(String parentId) throws UIWidgetException {
687         UIComponent parent = UILocator.get(parentId);
688         if (parent != null) {
689             setParent(parent);
690         }
691     }
692
693     /**
694      * Set the id
695      * @param id the id to set
696      */
697     public void setId(String id) {
698         if ((id != null && !id.equals(this.id)) || (id == null && this.id != null)) {
699             if (!isRoot() && this.id != null && parent.children != null) {
700                 parent.children.remove(this.id);
701             }
702             UILocator.removeFromCachedPaths(this);
703             this.id = id;
704             invalidateUIPath();
705             if (isRoot()) {
706                 UILocator.addRoot(this);
707             } else {
708                 registerIdToParent();
709             }
710         }
711     }
712
713     /**
714      * Get the id of this UIComponent
715      *@return the id
716      */
717     public String getId() {
718         return this.id;
719     }
720
721     /**
722      * Set the tag (Scilab's UIControl compatibility)
723      * @param tag the tag
724      */
725     public void setTag(String tag) {
726         setId(tag);
727     }
728
729     /**
730      * Get the tag (id) of this UIComponent
731      *@return the tag
732      */
733     public String getTag() {
734         return getId();
735     }
736
737     /**
738      * Invalidate the path to this UIComponent
739      */
740     private void invalidateUIPath() {
741         UILocator.removeFromCachedPaths(this);
742         if (id != null) {
743             if (isRoot()) {
744                 path = "/" + id;
745             } else if (parent.path != null) {
746                 path = parent.path + "/" + id;
747             }
748
749             if (path != null) {
750                 if (children != null) {
751                     for (UIComponent ui : children.values()) {
752                         ui.invalidateUIPath();
753                     }
754                 } else {
755                     if (childrenList != null) {
756                         for (UIComponent child : childrenList) {
757                             child.registerIdToParent();
758                         }
759                         if (children != null) {
760                             for (UIComponent ui : children.values()) {
761                                 ui.invalidateUIPath();
762                             }
763                         }
764                     }
765                 }
766             }
767         }
768     }
769
770     /**
771      * Get the path to this UIComponent
772      * @return the path
773      */
774     public String getUIPath() {
775         return this.path;
776     }
777
778     /**
779      * Get the path to this UIComponent
780      * @return the path
781      */
782     public String getPath() {
783         return getUIPath();
784     }
785
786     /**
787      * Get the root id of this UIComponent
788      * @return the root id
789      */
790     public String getRootId() {
791         return getRoot().id;
792     }
793
794     /**
795      * Get the root element
796      * @return the root
797      */
798     public UIComponent getRoot() {
799         return root;
800     }
801
802     /**
803      * Add a button to a button-group
804      * @param name the name of the button-group
805      * @param button the button to add
806      */
807     public void addToButtonGroup(String name, UIComponent button) {
808         if (isRoot()) {
809             if (buttonGroups == null) {
810                 buttonGroups = new HashMap<String, UIButtonGroup>();
811             }
812             UIButtonGroup bg = buttonGroups.get(name);
813             if (bg == null) {
814                 bg = new UIButtonGroup();
815                 buttonGroups.put(name, bg);
816             }
817             bg.add(button);
818         }
819     }
820
821     /**
822      * Get the uicomponent which is selected in the group
823      * @param name the group name
824      * @return the selected component
825      */
826     protected UIComponent getSelectedInGroup(String name) {
827         if (getRoot().buttonGroups != null) {
828             UIButtonGroup group = getRoot().buttonGroups.get(name);
829             if (group != null) {
830                 return group.getSelected();
831             }
832         }
833
834         return null;
835     }
836
837     /**
838      * Remove a button from a button-group
839      * @param name the name of the button-group
840      * @param button the button to remove
841      */
842     public void removeFromButtonGroup(String name, UIComponent button) {
843         if (isRoot() && buttonGroups != null) {
844             UIButtonGroup bg = buttonGroups.get(name);
845             if (bg != null) {
846                 bg.remove(button);
847             }
848         }
849     }
850
851     /**
852      * Check if this UIComponent is a root element (no parent)
853      * @return true if it is a root element
854      */
855     public boolean isRoot() {
856         return parent == null;
857     }
858
859     /**
860      * Get the child with the given id
861      * @param if the child id
862      * @return the corresponding UIComponent
863      */
864     public UIComponent getUIComponent(final String id) {
865         if (children != null) {
866             return children.get(id);
867         }
868
869         return null;
870     }
871
872     /**
873      * Close this UIComponent
874      */
875     public void closeUIComponent() { }
876
877     /**
878      * Remove the UIComponent from differents cache and delete its children
879      */
880     public void remove() {
881         UIComponent oldParent = parent;
882         remove(true);
883
884         if (oldParent != null) {
885             if (oldParent.component instanceof JComponent) {
886                 JComponent jc = (JComponent) oldParent.component;
887                 jc.revalidate();
888                 jc.repaint();
889             }  else if (oldParent.component instanceof Container) {
890                 Container container = (Container) oldParent.component;
891                 container.invalidate();
892                 container.validate();
893                 container.repaint();
894             }
895         }
896     }
897
898     /**
899      * Remove the UIComponent from differents cache and delete its children
900      * @param removeFromParent if true remove this from its parent
901      */
902     private void remove(boolean removeFromParent) {
903         UserData.removeUIWidgetUserData(uid);
904         UILocator.remove(this);
905         UIComponent oldParent = parent;
906         if (childrenList != null) {
907             for (UIComponent ui : childrenList) {
908                 ui.remove(false);
909             }
910             childrenList = null;
911             children = null;
912         }
913         closeUIComponent();
914         if (removeFromParent && parent != null) {
915             if (parent.childrenList != null) {
916                 parent.childrenList.remove(this);
917             }
918             if (parent.children != null && id != null) {
919                 parent.children.remove(id);
920             }
921         }
922         parent = null;
923         if (mouseListener != null) {
924             mouseListener.addListenerToComponent(null);
925             mouseListener = null;
926         }
927         if (focusListener != null) {
928             focusListener.addListenerToComponent(null);
929             focusListener = null;
930         }
931         if (component instanceof JComponent) {
932             JComponent jc = (JComponent) component;
933             if (jc.getParent() != null) {
934                 jc.getParent().remove(jc);
935             }
936             jc.removeAll();
937         }
938         if (getModifiableComponent() != component && getModifiableComponent() instanceof JComponent) {
939             JComponent jc = (JComponent) getModifiableComponent();
940             if (jc.getParent() != null) {
941                 jc.getParent().remove(jc);
942             }
943             jc.removeAll();
944         }
945         buttonGroups = null;
946         component = null;
947         modifiableComponent = null;
948         root = null;
949     }
950
951     /**
952      * Set the map containing style element
953      */
954     private void setMapStyle(Map<String, Map<String, String>> style) {
955         this.style = style;
956     }
957
958     /**
959      * Finish the UIComponent creation
960      */
961     public void finish() {
962     }
963
964     /**
965      * Replace the component by another one
966      * @param c the new component
967      */
968     public void replaceBy(Component c) {
969         if (component instanceof Component) {
970             Component comp = (Component) component;
971             Container parent = comp.getParent();
972             if (parent != null) {
973                 boolean hasChanged = false;
974                 if ((parent instanceof View) && (c instanceof Container)) {
975                     // Flexdock needs a special treatment...
976                     View v = (View) parent;
977                     if (v.getContentPane() == comp) {
978                         v.setContentPane((Container) c);
979                         hasChanged = true;
980                     }
981                 }
982
983                 if (!hasChanged) {
984                     LayoutManager layout = parent.getLayout();
985                     Object constraint = null;
986                     if (layout instanceof GridBagLayout) {
987                         constraint = ((GridBagLayout) layout).getConstraints(comp);
988                     } else if (layout instanceof BorderLayout) {
989                         constraint = ((BorderLayout) layout).getConstraints(comp);
990                     } else if (layout instanceof NoLayout) {
991                         constraint = ((NoLayout) layout).getConstraints(comp);
992                     }
993
994                     if (constraint != null) {
995                         parent.remove(comp);
996                         parent.add(c, constraint);
997                     } else {
998                         int pos = parent.getComponentZOrder(comp);
999                         parent.remove(comp);
1000                         if (pos > parent.getComponentCount()) {
1001                             parent.add(c, -1);
1002                         } else {
1003                             parent.add(c, pos);
1004                         }
1005                     }
1006                 }
1007
1008                 parent.doLayout();
1009                 parent.repaint();
1010             }
1011             component = c;
1012         }
1013     }
1014
1015     /**
1016      * Get the parent UIComponent
1017      * @return the parent
1018      */
1019     public UIComponent getParent() {
1020         return parent;
1021     }
1022
1023     /**
1024      * Get the id of this UIComponent
1025      * @return the id
1026      */
1027     public String getID() {
1028         return id;
1029     }
1030
1031     /**
1032      * Check if the root element is visible
1033      * @return true if the root element is visible
1034      */
1035     public boolean isRootVisible() {
1036         if (isRoot()) {
1037             if (component instanceof Component) {
1038                 return ((Component) component).isVisible();
1039             }
1040             return false;
1041         } else {
1042             return root.isRootVisible();
1043         }
1044     }
1045
1046     /**
1047      * Get the children
1048      * @return the children as an array
1049      */
1050     public UIComponent[] getChildren() {
1051         if (childrenList != null && !childrenList.isEmpty()) {
1052             return childrenList.toArray(new UIComponent[childrenList.size()]);
1053         }
1054
1055         return null;
1056     }
1057
1058     /**
1059      * Get the uistyle
1060      * @return uistyle as String
1061      */
1062     public String getUIStyle() {
1063         if (uistyle != null) {
1064             String str = "";
1065             for (Map.Entry<String, String> entry : uistyle.entrySet()) {
1066                 str += entry.getKey() + ":" + entry.getValue();
1067             }
1068
1069             return str;
1070         }
1071
1072         return null;
1073     }
1074
1075     /**
1076      * Set the uistyle
1077      * @param style a String containing style definition as a CSS string
1078      */
1079     public void setUiStyle(String style) throws UIWidgetException {
1080         setUiStyle(StyleParser.parseLine(style));
1081     }
1082
1083     /**
1084      * Set the uistyle
1085      * @param style a map
1086      */
1087     public void setUiStyle(Map<String, String> style) throws UIWidgetException {
1088         this.uistyle = style;
1089         Object c = getModifiableComponent();
1090         if (c instanceof JComponent) {
1091             ((JComponent) c).setFont(UITools.getFont(((JComponent) c).getFont(), style));
1092         }
1093         for (String key : style.keySet()) {
1094             try {
1095                 setProperty(key, style.get(key));
1096             } catch (UIWidgetException e) { }
1097         }
1098     }
1099
1100     /**
1101      * Set the tab title if the component is in a JTabbedPane
1102      * @param title the tab title
1103      */
1104     public void setTabTitle(String title) throws UIWidgetException {
1105         if (parent instanceof UITab && title != null && component != null) {
1106             JComponent c = getJComponent();
1107             JTabbedPane tab = (JTabbedPane) ((UITab) parent).getJComponent();
1108             int index = tab.indexOfTabComponent(c);
1109             if (index != -1) {
1110                 tab.setTitleAt(index, title);
1111             }
1112         }
1113         this.tabTitle = title;
1114     }
1115
1116     /**
1117      * Get the tab title if the component is in a JTabbedPane
1118      * @return the tab title
1119      */
1120     public String getTabTitle() throws UIWidgetException {
1121         return tabTitle;
1122     }
1123
1124     /**
1125      * Set the tooltip text
1126      * @param text the tooltip text
1127      */
1128     public void setTooltip(String text) throws UIWidgetException {
1129         getModifiableJComponent().setToolTipText(text);
1130     }
1131
1132     /**
1133      * Get the tooltip text
1134      * @return the tooltip text
1135      */
1136     public String getTooltip() throws UIWidgetException {
1137         return getModifiableJComponent().getToolTipText();
1138     }
1139
1140     /**
1141      * Set the tooltip text
1142      * @param text the tooltip text
1143      */
1144     public void setTooltipString(String text) throws UIWidgetException {
1145         setTooltip(text);
1146     }
1147
1148     /**
1149      * Get the tooltip text
1150      * @return the tooltip text
1151      */
1152     public String getTooltipString() throws UIWidgetException {
1153         return getTooltip();
1154     }
1155
1156     /**
1157      * Set the foreground color
1158      * @param c the color
1159      */
1160     public void setColor(Color c) throws UIWidgetException {
1161         getModifiableJComponent().setForeground(c);
1162     }
1163
1164     /**
1165      * Get the foreground color
1166      * @return the foreground color
1167      */
1168     public Color getColor() throws UIWidgetException {
1169         return getModifiableJComponent().getForeground();
1170     }
1171
1172     /**
1173      * Set the font unit
1174      * @param name the font name
1175      */
1176     public void setFontUnits(UITools.FontUnit unit) throws UIWidgetException {
1177         // TODO: actuellement ds uic, fontunit est ignore et est dc egale a PIXELS
1178         double ratio = UITools.FontUnit.getRatio(fontUnit, UITools.FontUnit.PIXELS);//unit);
1179         if (ratio != 1) {
1180             this.fontUnit = unit;
1181             Font f = getFont();
1182             if (f != null) {
1183                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1184                 map.put(TextAttribute.SIZE, new Double(f.getSize2D() * ratio));
1185                 setFont(new Font(map));
1186             }
1187         }
1188     }
1189
1190     public String getFontUnits() {
1191         return UITools.FontUnit.getAsString(this.fontUnit);
1192     }
1193
1194     /**
1195      * Set the font name
1196      * @param name the font name
1197      */
1198     public void setFontName(String name) throws UIWidgetException {
1199         Font f = getFont();
1200         if (f != null) {
1201             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1202             map.put(TextAttribute.FAMILY, name);
1203             setFont(new Font(map));
1204         }
1205     }
1206
1207     /**
1208      * Get the font name
1209      * @return name the font name
1210      */
1211     public String getFontName() throws UIWidgetException {
1212         Font f = getFont();
1213         if (f != null) {
1214             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1215             return (String) map.get(TextAttribute.FAMILY);
1216         }
1217
1218         return null;
1219     }
1220
1221     /**
1222      * Set the font size
1223      * @param size the font size
1224      */
1225     public void setFontSize(double size) throws UIWidgetException {
1226         double ratio = UITools.FontUnit.getRatio(fontUnit);
1227         Font f = getFont();
1228         if (f != null) {
1229             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1230             map.put(TextAttribute.SIZE, (Double.isNaN(size) || size < 0 || Double.isInfinite(size)) ? new Double(12.0 * ratio) : new Double(size * ratio));
1231             setFont(new Font(map));
1232         }
1233     }
1234
1235     /**
1236      * Get the font size
1237      * @return the font size
1238      */
1239     public double getFontSize() throws UIWidgetException {
1240         Font f = getFont();
1241         if (f != null) {
1242             double ratio = UITools.FontUnit.getRatio(fontUnit);
1243             return Math.round(f.getSize2D() / ratio);
1244         }
1245
1246         return -1;
1247     }
1248
1249     /**
1250      * Set the font weight
1251      * @param weight the font weight
1252      */
1253     public void setFontWeight(UITools.FontWeight weight) throws UIWidgetException {
1254         if (weight != null) {
1255             Font f = getFont();
1256             if (f != null) {
1257                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1258                 map.put(TextAttribute.WEIGHT, weight.value());
1259                 setFont(new Font(map));
1260             }
1261         }
1262     }
1263
1264     /**
1265      * Get the font weight
1266      * @return the font weight
1267      */
1268     public String getFontWeight() throws UIWidgetException {
1269         Font f = getFont();
1270         if (f != null) {
1271             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1272             Float fl = (Float) map.get(TextAttribute.WEIGHT);
1273             return UITools.mapTextAttribute.get(fl);
1274         }
1275
1276         return null;
1277     }
1278
1279     /**
1280      * Set the font angle
1281      * @param angle the font angle
1282      */
1283     public void setFontAngle(String angle) throws UIWidgetException {
1284         if (angle != null && !angle.isEmpty()) {
1285             angle = angle.toLowerCase();
1286             boolean italic = angle.equals("italic") || angle.equals("oblique") || angle.equals("it");
1287             Font f = getFont();
1288             if (f != null) {
1289                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1290                 map.put(TextAttribute.POSTURE, italic ? TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR);
1291                 setFont(new Font(map));
1292             }
1293         }
1294     }
1295
1296     /**
1297      * Get the font angle
1298      * @return the font angle
1299      */
1300     public String getFontAngle() throws UIWidgetException {
1301         Font f = getFont();
1302         if (f != null) {
1303             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1304             Float fl = (Float) map.get(TextAttribute.POSTURE);
1305             if (fl == null || fl == TextAttribute.POSTURE_REGULAR) {
1306                 return "normal";
1307             } else {
1308                 return "italic";
1309             }
1310         }
1311
1312         return null;
1313     }
1314
1315     /**
1316      * Set the component relief
1317      * @param relief a string which represents the relief
1318      */
1319     public void setRelief(String relief) throws UIWidgetException {
1320         if (relief != null) {
1321             getJComponent().setBorder(ScilabRelief.getBorderFromRelief(relief));
1322             this.relief = relief;
1323         }
1324     }
1325
1326     /**
1327      * Get the relief
1328      * @return the relief
1329      */
1330     public String getRelief() {
1331         return this.relief;
1332     }
1333
1334     /**
1335      * Set the font
1336      * @param f the font
1337      */
1338     public void setFont(Font f) throws UIWidgetException {
1339         getModifiableJComponent().setFont(f);
1340         getJComponent().revalidate();
1341     }
1342
1343     /**
1344      * Get the font
1345      * @return the font
1346      */
1347     public Font getFont() throws UIWidgetException {
1348         return getModifiableJComponent().getFont();
1349     }
1350
1351     public void setUnits(String[] unit) throws UIWidgetException {
1352         if (unit != null) {
1353             boolean mustLayout = false;
1354             if (unit.length >= 4) {
1355                 final int[] units = new int[4];
1356                 for (int i = 0; i < 4; i++) {
1357                     if (unit[i].equals("%") || unit[i].equalsIgnoreCase("n") || unit[i].equalsIgnoreCase("normalized")) {
1358                         units[i] = 1;
1359                     } else if (unit[i].equals("pt") || unit[i].equalsIgnoreCase("points")) {
1360                         units[i] = 2;
1361                     } else {
1362                         units[i] = 0;
1363                     }
1364                 }
1365
1366                 if (this.nolayoutconstraint == null) {
1367                     this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1368                 }
1369
1370                 this.nolayoutconstraint.setUnit(units[0], units[1], units[2], units[3]);
1371                 mustLayout = true;
1372             } else if (unit.length == 1) {
1373                 int u = 0;
1374                 if (!unit[0].isEmpty()) {
1375                     if (unit[0].equalsIgnoreCase("points")) {
1376                         u = 2;
1377                     } else if (unit[0].equalsIgnoreCase("normalized")) {
1378                         u = 1;
1379                     }
1380                 }
1381
1382                 if (this.nolayoutconstraint == null) {
1383                     this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1384                 }
1385
1386                 this.nolayoutconstraint.setUnit(u, u, u, u);
1387                 mustLayout = true;
1388             }
1389
1390             if (mustLayout) {
1391                 Container p = getJComponent().getParent();
1392                 if (p != null && p.getLayout() instanceof NoLayout) {
1393                     p.invalidate();
1394                     p.doLayout();
1395                     p.repaint();
1396                 }
1397             }
1398         }
1399     }
1400
1401     /**
1402      * Get the position unit (when NoLayout has been set)
1403      * @return the units
1404      */
1405     public String[] getUnits() throws UIWidgetException {
1406         String[] ret;
1407         boolean allTheSame = true;
1408         for (int i = 1; i < 4; i++) {
1409             if (nolayoutconstraint.unit[i] != nolayoutconstraint.unit[0]) {
1410                 allTheSame = false;
1411                 break;
1412             }
1413         }
1414
1415         if (allTheSame) {
1416             ret = new String[1];
1417             switch (nolayoutconstraint.unit[0]) {
1418                 case 1:
1419                     ret[0] = "normalized";
1420                     break;
1421                 case 2:
1422                     ret[0] = "points";
1423                     break;
1424                 default:
1425                     ret[0] = "pixels";
1426                     break;
1427             }
1428         } else {
1429             ret = new String[4];
1430             for (int i = 0; i < 4; i++) {
1431                 switch (nolayoutconstraint.unit[i]) {
1432                     case 1:
1433                         ret[i] = "%";
1434                         break;
1435                     case 2:
1436                         ret[i] = "pt";
1437                         break;
1438                     default:
1439                         ret[i] = "px";
1440                         break;
1441                 }
1442             }
1443         }
1444
1445         return ret;
1446     }
1447
1448     /**
1449      * Get the constraint when no layout
1450      * @return the constraint
1451      */
1452     public NoLayout.NoLayoutConstraint getNoLayoutConstraint() {
1453         return nolayoutconstraint;
1454     }
1455
1456     private void setNoLayoutConstraint(Rectangle2D.Double r) {
1457         if (this.nolayoutconstraint == null) {
1458             this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1459         }
1460
1461         this.nolayoutconstraint.setPoint(r.x, r.y);
1462         this.nolayoutconstraint.setDims(r.width, r.height);
1463         this.nolayoutconstraint.setUnit(0, 0, 0, 0);
1464     }
1465
1466     /**
1467      * Set the location
1468      * @param p the location
1469      */
1470     public void setLocation(Point p) throws UIWidgetException {
1471         if (p != null) {
1472             Rectangle2D.Double pos = getPosition();
1473             if (pos != null) {
1474                 setPosition(new Rectangle2D.Double(p.x, p.y, pos.width, pos.height));
1475             }
1476         }
1477     }
1478
1479     /**
1480      * Set the position (when NoLayout has been set)
1481      * @param r the position
1482      */
1483     public void setPosition(Rectangle2D.Double r) throws UIWidgetException {
1484         if (r != null) {
1485             if (getComponent() == null) {
1486                 setNoLayoutConstraint(r);
1487                 return;
1488             }
1489
1490             if (getComponent() instanceof Component) {
1491                 Component c = (Component) getComponent();
1492                 Container p = c.getParent();
1493                 if (c instanceof JFrame) {
1494                     JFrame win = (JFrame) c;
1495                     win.setLocation((int) r.x, (int) r.y);
1496                     Dimension dim = win.getSize();
1497                     if (dim.width != (int) r.width || dim.height != (int) r.height) {
1498                         win.setPreferredSize(new Dimension((int) r.width, (int) r.height));
1499                         if (win.isVisible()) {
1500                             win.invalidate();
1501                             win.pack();
1502                             win.repaint();
1503                         }
1504                     }
1505                 } else if (p == null || p.getLayout() instanceof NoLayout) {
1506                     if (this.nolayoutconstraint == null) {
1507                         this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1508                     }
1509
1510                     this.nolayoutconstraint.setPoint(r.x, r.y);
1511                     if (this.nolayoutconstraint.bounds.width != r.width || this.nolayoutconstraint.bounds.height != r.height) {
1512                         this.nolayoutconstraint.setDims(r.width, r.height);
1513                         if (p == null) {
1514                             c.setSize((int) r.width, (int) r.height);
1515                             c.invalidate();
1516                             c.validate();
1517                         }
1518                     }
1519                     if (p != null && p.isVisible()) {
1520                         p.invalidate();
1521                         p.validate();
1522                         p.repaint();
1523                     }
1524                 } else if (p.getLayout() == null) {
1525                     c.setSize((int) r.width, (int) r.height);
1526                     c.invalidate();
1527                     c.validate();
1528                 }
1529             }
1530         }
1531     }
1532
1533     /**
1534      * Get the position
1535      * @return the position
1536      */
1537     public Rectangle2D.Double getPosition() throws UIWidgetException {
1538         if (getComponent() instanceof Component) {
1539             Component c = (Component) getComponent();
1540             Container p = c.getParent();
1541             if (p != null && p.getLayout() instanceof NoLayout) {
1542                 return this.nolayoutconstraint.bounds;
1543             }
1544
1545             Dimension d = c.getSize();
1546             Point pt = c.getLocation();
1547
1548             return new Rectangle2D.Double(pt.x, pt.y, d.width, d.height);
1549         }
1550
1551         return null;
1552     }
1553
1554     /**
1555      * Set the foreground color
1556      * @param c the color
1557      */
1558     public void setForegroundColor(Color c) throws UIWidgetException {
1559         if (c != null) {
1560             getModifiableJComponent().setForeground(c);
1561         }
1562     }
1563
1564     /**
1565      * Get the foreground color
1566      * @return the foreground color
1567      */
1568     public Color getForegroundColor() throws UIWidgetException {
1569         return getModifiableJComponent().getForeground();
1570     }
1571
1572     /**
1573      * Set the background color
1574      * @param c the color
1575      */
1576     public void setBackgroundColor(Color c) throws UIWidgetException {
1577         if (c != null) {
1578             getModifiableJComponent().setBackground(c);
1579         }
1580     }
1581
1582     /**
1583      * Get the background color
1584      * @return the background color
1585      */
1586     public Color getBackgroundColor() throws UIWidgetException {
1587         return getModifiableJComponent().getBackground();
1588     }
1589
1590     /**
1591      * Set the component scrollable or not
1592      * @param b if true the component will be scrollable
1593      */
1594     public void setScrollable(boolean b) {
1595         if (component instanceof JScrollPane) {
1596             JScrollPane scroll = (JScrollPane) component;
1597             if (b) {
1598                 scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
1599                 scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
1600             } else {
1601                 scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
1602                 scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
1603             }
1604         } else if (component instanceof JComponent && b) {
1605             JComponent c = (JComponent) component;
1606             JScrollPane scroll = new JScrollPane();
1607             replaceBy(scroll);
1608             scroll.getViewport().setView(c);
1609             modifiableComponent = c;
1610         }
1611     }
1612
1613     /**
1614      * Check if the component is scrollable
1615      * @return true if the component is scrollable
1616      */
1617     public boolean getScrollable() {
1618         return component instanceof JScrollPane && ((JScrollPane) component).getHorizontalScrollBarPolicy() == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
1619     }
1620
1621     /**
1622      * Set the horizontal block increment (pgup, pgdown in scroll)
1623      * @param blockIncrement the block increment
1624      */
1625     public void setHorizontalBlockIncrement(int blockIncrement) {
1626         if (component instanceof JScrollPane) {
1627             JScrollPane scroll = (JScrollPane) component;
1628             JScrollBar bar = scroll.getHorizontalScrollBar();
1629             if (bar != null) {
1630                 bar.setBlockIncrement(blockIncrement);
1631             }
1632         }
1633     }
1634
1635     /**
1636      * Get the horizontal block increment
1637      * @return block increment
1638      */
1639     public int getHorizontalBlockIncrement() {
1640         if (component instanceof JScrollPane) {
1641             JScrollPane scroll = (JScrollPane) component;
1642             JScrollBar bar = scroll.getHorizontalScrollBar();
1643             if (bar != null) {
1644                 return bar.getBlockIncrement();
1645             }
1646         }
1647
1648         return -1;
1649     }
1650
1651     /**
1652      * Set the vertical block increment (pgup, pgdown in scroll)
1653      * @param blockIncrement the block increment
1654      */
1655     public void setVerticalBlockIncrement(int blockIncrement) {
1656         if (component instanceof JScrollPane) {
1657             JScrollPane scroll = (JScrollPane) component;
1658             JScrollBar bar = scroll.getVerticalScrollBar();
1659             if (bar != null) {
1660                 bar.setBlockIncrement(blockIncrement);
1661             }
1662         }
1663     }
1664
1665     /**
1666      * Get the vertical block increment
1667      * @return block increment
1668      */
1669     public int getVerticalBlockIncrement() {
1670         if (component instanceof JScrollPane) {
1671             JScrollPane scroll = (JScrollPane) component;
1672             JScrollBar bar = scroll.getVerticalScrollBar();
1673             if (bar != null) {
1674                 return bar.getBlockIncrement();
1675             }
1676         }
1677
1678         return -1;
1679     }
1680
1681     /**
1682      * Set the horizontal unit increment (wheel in scroll)
1683      * @param unitIncrement the unit increment
1684      */
1685     public void setHorizontalUnitIncrement(int unitIncrement) {
1686         if (component instanceof JScrollPane) {
1687             JScrollPane scroll = (JScrollPane) component;
1688             JScrollBar bar = scroll.getHorizontalScrollBar();
1689             if (bar != null) {
1690                 bar.setUnitIncrement(unitIncrement);
1691             }
1692         }
1693     }
1694
1695     /**
1696      * Get the horizontal unit increment
1697      * @return unit increment
1698      */
1699     public int getHorizontalUnitIncrement() {
1700         if (component instanceof JScrollPane) {
1701             JScrollPane scroll = (JScrollPane) component;
1702             JScrollBar bar = scroll.getHorizontalScrollBar();
1703             if (bar != null) {
1704                 return bar.getUnitIncrement();
1705             }
1706         }
1707
1708         return -1;
1709     }
1710
1711     /**
1712      * Set the vertical unit increment (wheel in scroll)
1713      * @param unitIncrement the unit increment
1714      */
1715     public void setVerticalUnitIncrement(int unitIncrement) {
1716         if (component instanceof JScrollPane) {
1717             JScrollPane scroll = (JScrollPane) component;
1718             JScrollBar bar = scroll.getVerticalScrollBar();
1719             if (bar != null) {
1720                 bar.setUnitIncrement(unitIncrement);
1721             }
1722         }
1723     }
1724
1725     /**
1726      * Get the vertical unit increment
1727      * @return unit increment
1728      */
1729     public int getVerticalUnitIncrement() {
1730         if (component instanceof JScrollPane) {
1731             JScrollPane scroll = (JScrollPane) component;
1732             JScrollBar bar = scroll.getVerticalScrollBar();
1733             if (bar != null) {
1734                 return bar.getUnitIncrement();
1735             }
1736         }
1737
1738         return -1;
1739     }
1740
1741     /**
1742      * Set the horizontal scroll value
1743      * @param value the value
1744      */
1745     public void setHorizontalScrollValue(int value) {
1746         if (component instanceof JScrollPane) {
1747             JScrollPane scroll = (JScrollPane) component;
1748             JScrollBar bar = scroll.getHorizontalScrollBar();
1749             if (bar != null) {
1750                 bar.setValue(value);
1751             }
1752         }
1753     }
1754
1755     /**
1756      * Get the horizontal scroll value
1757      * @return the scroll value
1758      */
1759     public int getHorizontalScrollValue() {
1760         if (component instanceof JScrollPane) {
1761             JScrollPane scroll = (JScrollPane) component;
1762             JScrollBar bar = scroll.getHorizontalScrollBar();
1763             if (bar != null) {
1764                 return bar.getValue();
1765             }
1766         }
1767
1768         return -1;
1769     }
1770
1771     /**
1772      * Set the vertical scroll value
1773      * @param value the value
1774      */
1775     public void setVerticalScrollValue(int value) {
1776         if (component instanceof JScrollPane) {
1777             JScrollPane scroll = (JScrollPane) component;
1778             JScrollBar bar = scroll.getVerticalScrollBar();
1779             if (bar != null) {
1780                 bar.setValue(value);
1781             }
1782         }
1783     }
1784
1785     /**
1786      * Get the vertical scroll value
1787      * @return the scroll value
1788      */
1789     public int getVerticalScrollValue() {
1790         if (component instanceof JScrollPane) {
1791             JScrollPane scroll = (JScrollPane) component;
1792             JScrollBar bar = scroll.getVerticalScrollBar();
1793             if (bar != null) {
1794                 return bar.getValue();
1795             }
1796         }
1797
1798         return -1;
1799     }
1800
1801     /**
1802      * Set the component constraints
1803      * @param constraint a string containing layout constraints (CSS style)
1804      */
1805     public void setConstraint(String constraint) throws UIWidgetException {
1806         setConstraint(StyleParser.parseLine(constraint));
1807     }
1808
1809     /**
1810      * Set the component constraints
1811      * @param constraint a map containing layout constraints
1812      */
1813     public void setConstraint(Map<String, String> constraint) throws UIWidgetException {
1814         this.constraint = constraint;
1815         Container p = getJComponent().getParent();
1816         if (p != null && !(p.getLayout() instanceof NoLayout) && getParent() != null) {
1817             getParent().add(this);
1818             p.invalidate();
1819             p.validate();
1820         }
1821     }
1822
1823     /**
1824      * Get the constraint
1825      * @return constraint as String
1826      */
1827     public String getConstraint() {
1828         if (constraint != null) {
1829             String str = "";
1830             for (Map.Entry<String, String> entry : constraint.entrySet()) {
1831                 str += entry.getKey() + ":" + entry.getValue();
1832             }
1833
1834             return str;
1835         }
1836
1837         return null;
1838     }
1839
1840     /**
1841      * Set the layout
1842      * @param layout the layout informations (CSS style)
1843      */
1844     public void setLayout(String layout) throws UIWidgetException {
1845         getModifiableContainer().setLayout(UILayoutFactory.getLayout(getModifiableJComponent(), layout));
1846     }
1847
1848     /**
1849      * Enable or not the component
1850      * @param enable if true, the component is enabled
1851      */
1852     public void setEnable(boolean enable) throws UIWidgetException {
1853         getJComponent().setEnabled(enable);
1854     }
1855
1856     /**
1857      * Check if the component is enabled
1858      * @return true if the component is enabled
1859      */
1860     public boolean getEnable() throws UIWidgetException {
1861         return getJComponent().isEnabled();
1862     }
1863
1864     /**
1865      * Create a MouseListener on this component
1866      */
1867     private final void createMouseListener() throws UIWidgetException {
1868         if (mouseListener == null) {
1869             mouseListener = new UIMouseListener(this);
1870             mouseListener.newInstance();
1871             mouseListener.addListenerToComponent(getModifiableJComponent());
1872         }
1873     }
1874
1875     /**
1876      * Set onmouseclick action
1877      * @param command the command to execute
1878      */
1879     public void setOnmouseclick(String command) throws UIWidgetException {
1880         if (command != null && !command.isEmpty()) {
1881             createMouseListener();
1882             mouseListener.setOnmouseclick(command);
1883         }
1884     }
1885
1886     /**
1887      * Set onmouseover action
1888      * @param command the command to execute
1889      */
1890     public void setOnmouseover(String command) throws UIWidgetException {
1891         if (command != null && !command.isEmpty()) {
1892             createMouseListener();
1893             mouseListener.setOnmouseover(command);
1894         }
1895     }
1896
1897     /**
1898      * Set onmouseenter action
1899      * @param command the command to execute
1900      */
1901     public void setOnmouseenter(String command) throws UIWidgetException {
1902         if (command != null && !command.isEmpty()) {
1903             createMouseListener();
1904             mouseListener.setOnmouseenter(command);
1905         }
1906     }
1907
1908     /**
1909      * Set onmouseexit action
1910      * @param command the command to execute
1911      */
1912     public void setOnmouseexit(String command) throws UIWidgetException {
1913         if (command != null && !command.isEmpty()) {
1914             createMouseListener();
1915             mouseListener.setOnmouseexit(command);
1916         }
1917     }
1918
1919     /**
1920      * Set onmousepress action
1921      * @param command the command to execute
1922      */
1923     public void setOnmousepress(String command) throws UIWidgetException {
1924         if (command != null && !command.isEmpty()) {
1925             createMouseListener();
1926             mouseListener.setOnmousepress(command);
1927         }
1928     }
1929
1930     /**
1931      * Set onmouserelease action
1932      * @param command the command to execute
1933      */
1934     public void setOnmouserelease(String command) throws UIWidgetException {
1935         if (command != null && !command.isEmpty()) {
1936             createMouseListener();
1937             mouseListener.setOnmouserelease(command);
1938         }
1939     }
1940
1941     /**
1942      * Set onmousewheel action
1943      * @param command the command to execute
1944      */
1945     public void setOnmousewheel(String command) throws UIWidgetException {
1946         if (command != null && !command.isEmpty()) {
1947             createMouseListener();
1948             mouseListener.setOnmousewheel(command);
1949         }
1950     }
1951
1952     /**
1953      * Set onmousedrag action
1954      * @param command the command to execute
1955      */
1956     public void setOnmousedrag(String command) throws UIWidgetException {
1957         if (command != null && !command.isEmpty()) {
1958             createMouseListener();
1959             mouseListener.setOnmousedrag(command);
1960         }
1961     }
1962
1963     /**
1964      * Get onmouseclick action
1965      * @return the command to execute
1966      */
1967     public UICallback getOnmouseclick() {
1968         if (mouseListener != null) {
1969             return mouseListener.getOnmouseclick();
1970         }
1971
1972         return null;
1973     }
1974
1975     /**
1976      * Get onmouseover action
1977      * @return the command to execute
1978      */
1979     public UICallback getOnmouseover() {
1980         if (mouseListener != null) {
1981             return mouseListener.getOnmouseover();
1982         }
1983
1984         return null;
1985     }
1986
1987     /**
1988      * Get onmouseenter action
1989      * @return the command to execute
1990      */
1991     public UICallback getOnmouseenter() {
1992         if (mouseListener != null) {
1993             return mouseListener.getOnmouseenter();
1994         }
1995
1996         return null;
1997     }
1998
1999     /**
2000      * Get onmouseexit action
2001      * @return the command to execute
2002      */
2003     public UICallback getOnmouseexit() {
2004         if (mouseListener != null) {
2005             return mouseListener.getOnmouseexit();
2006         }
2007
2008         return null;
2009     }
2010
2011     /**
2012      * Get onmousepress action
2013      * @return the command to execute
2014      */
2015     public UICallback getOnmousepress() {
2016         if (mouseListener != null) {
2017             return mouseListener.getOnmousepress();
2018         }
2019
2020         return null;
2021     }
2022
2023     /**
2024      * Get onmouserelease action
2025      * @return the command to execute
2026      */
2027     public UICallback getOnmouserelease() {
2028         if (mouseListener != null) {
2029             return mouseListener.getOnmouserelease();
2030         }
2031
2032         return null;
2033     }
2034
2035     /**
2036      * Get onmousedrag action
2037      * @return the command to execute
2038      */
2039     public UICallback getOnmousedrag() {
2040         if (mouseListener != null) {
2041             return mouseListener.getOnmousedrag();
2042         }
2043
2044         return null;
2045     }
2046
2047     /**
2048      * Get onmousewheel action
2049      * @return the command to execute
2050      */
2051     public UICallback getOnmousewheel() {
2052         if (mouseListener != null) {
2053             return mouseListener.getOnmousewheel();
2054         }
2055
2056         return null;
2057     }
2058
2059     /**
2060      * Enable onmouseclick
2061      * @param b, if true the action is enabled
2062      */
2063     public void setOnmouseclickEnable(boolean b) {
2064         if (mouseListener != null) {
2065             mouseListener.setOnmouseclickEnable(b);
2066         }
2067     }
2068
2069     /**
2070      * Check if onmouseclick is enabled
2071      * @return true the action is enabled
2072      */
2073     public boolean getOnmouseclickEnable() {
2074         if (mouseListener != null) {
2075             return mouseListener.getOnmouseclickEnable();
2076         }
2077
2078         return false;
2079     }
2080
2081     /**
2082      * Enable onmouseover
2083      * @param b, if true the action is enabled
2084      */
2085     public void setOnmouseoverEnable(boolean b) {
2086         if (mouseListener != null) {
2087             mouseListener.setOnmouseoverEnable(b);
2088         }
2089     }
2090
2091     /**
2092      * Check if onmouseover is enabled
2093      * @return true the action is enabled
2094      */
2095     public boolean getOnmouseoverEnable() {
2096         if (mouseListener != null) {
2097             return mouseListener.getOnmouseoverEnable();
2098         }
2099
2100         return false;
2101     }
2102
2103     /**
2104      * Enable onmouseenter
2105      * @param b, if true the action is enabled
2106      */
2107     public void setOnmouseenterEnable(boolean b) {
2108         if (mouseListener != null) {
2109             mouseListener.setOnmouseenterEnable(b);
2110         }
2111     }
2112
2113     /**
2114      * Check if onmouseenter is enabled
2115      * @return true the action is enabled
2116      */
2117     public boolean getOnmouseenterEnable() {
2118         if (mouseListener != null) {
2119             return mouseListener.getOnmouseenterEnable();
2120         }
2121
2122         return false;
2123     }
2124
2125     /**
2126      * Enable onmouseexit
2127      * @param b, if true the action is enabled
2128      */
2129     public void setOnmouseexitEnable(boolean b) {
2130         if (mouseListener != null) {
2131             mouseListener.setOnmouseexitEnable(b);
2132         }
2133     }
2134
2135     /**
2136      * Check if onmouseexit is enabled
2137      * @return true the action is enabled
2138      */
2139     public boolean getOnmouseexitEnable() {
2140         if (mouseListener != null) {
2141             return mouseListener.getOnmouseexitEnable();
2142         }
2143
2144         return false;
2145     }
2146
2147     /**
2148      * Enable onmousepress
2149      * @param b, if true the action is enabled
2150      */
2151     public void setOnmousepressEnable(boolean b) {
2152         if (mouseListener != null) {
2153             mouseListener.setOnmousepressEnable(b);
2154         }
2155     }
2156
2157     /**
2158      * Check if onmousepress is enabled
2159      * @return true the action is enabled
2160      */
2161     public boolean getOnmousepressEnable() {
2162         if (mouseListener != null) {
2163             return mouseListener.getOnmousepressEnable();
2164         }
2165
2166         return false;
2167     }
2168
2169     /**
2170      * Enable onmouserelease
2171      * @param b, if true the action is enabled
2172      */
2173     public void setOnmousereleaseEnable(boolean b) {
2174         if (mouseListener != null) {
2175             mouseListener.setOnmousereleaseEnable(b);
2176         }
2177     }
2178
2179     /**
2180      * Check if onmouserelease is enabled
2181      * @return true the action is enabled
2182      */
2183     public boolean getOnmousereleaseEnable() {
2184         if (mouseListener != null) {
2185             return mouseListener.getOnmousereleaseEnable();
2186         }
2187
2188         return false;
2189     }
2190
2191     /**
2192      * Enable onmousewheel
2193      * @param b, if true the action is enabled
2194      */
2195     public void setOnmousewheelEnable(boolean b) {
2196         if (mouseListener != null) {
2197             mouseListener.setOnmousewheelEnable(b);
2198         }
2199     }
2200
2201     /**
2202      * Check if onmousewheel is enabled
2203      * @return true the action is enabled
2204      */
2205     public boolean getOnmousewheelEnable() {
2206         if (mouseListener != null) {
2207             return mouseListener.getOnmousewheelEnable();
2208         }
2209
2210         return false;
2211     }
2212
2213     /**
2214      * Enable onmousedrag
2215      * @param b, if true the action is enabled
2216      */
2217     public void setOnmousedragEnable(boolean b) {
2218         if (mouseListener != null) {
2219             mouseListener.setOnmousedragEnable(b);
2220         }
2221     }
2222
2223     /**
2224      * Check if onmousedrag is enabled
2225      * @return true the action is enabled
2226      */
2227     public boolean getOnmousedragEnable() {
2228         if (mouseListener != null) {
2229             return mouseListener.getOnmousedragEnable();
2230         }
2231
2232         return false;
2233     }
2234
2235     /**
2236      * Create a FocusListener on this component
2237      */
2238     private final void createFocusListener() throws UIWidgetException {
2239         if (focusListener == null) {
2240             focusListener = new UIFocusListener(this);
2241             focusListener.newInstance();
2242             focusListener.addListenerToComponent(getModifiableJComponent());
2243         }
2244     }
2245
2246     /**
2247      * Set onfocusgain action
2248      * @param command the command to execute
2249      */
2250     public void setOnfocusgain(String command) throws UIWidgetException {
2251         if (command != null && !command.isEmpty()) {
2252             createFocusListener();
2253             focusListener.setOnfocusgain(command);
2254         }
2255     }
2256
2257     /**
2258      * Set onfocusloss action
2259      * @param command the command to execute
2260      */
2261     public void setOnfocusloss(String command) throws UIWidgetException {
2262         if (command != null && !command.isEmpty()) {
2263             createFocusListener();
2264             focusListener.setOnfocusloss(command);
2265         }
2266     }
2267
2268     /**
2269      * Get onfocusgain action
2270      * @return the command to execute
2271      */
2272     public UICallback getOnfocusgain() {
2273         if (focusListener != null) {
2274             return focusListener.getOnfocusgain();
2275         }
2276
2277         return null;
2278     }
2279
2280     /**
2281      * Get onfocusloss action
2282      * @return the command to execute
2283      */
2284     public UICallback getOnfocusloss() {
2285         if (focusListener != null) {
2286             return focusListener.getOnfocusloss();
2287         }
2288
2289         return null;
2290     }
2291
2292     /**
2293      * Enable onfocusgain
2294      * @param b, if true the action is enabled
2295      */
2296     public void setOnfocusgainEnable(boolean b) {
2297         if (focusListener != null) {
2298             focusListener.setOnfocusgainEnable(b);
2299         }
2300     }
2301
2302     /**
2303      * Check if onfocusgain is enabled
2304      * @return true the action is enabled
2305      */
2306     public boolean getOnfocusgainEnable() {
2307         if (focusListener != null) {
2308             return focusListener.getOnfocusgainEnable();
2309         }
2310
2311         return false;
2312     }
2313
2314     /**
2315      * Enable onfocusloss
2316      * @param b, if true the action is enabled
2317      */
2318     public void setOnfocuslossEnable(boolean b) {
2319         if (focusListener != null) {
2320             focusListener.setOnfocuslossEnable(b);
2321         }
2322     }
2323
2324     /**
2325      * Check if onfocusloss is enabled
2326      * @return true the action is enabled
2327      */
2328     public boolean getOnfocuslossEnable() {
2329         if (focusListener != null) {
2330             return focusListener.getOnfocuslossEnable();
2331         }
2332
2333         return false;
2334     }
2335
2336     /**
2337      * Change the parent and update the dependencies
2338      * @param parent the parent
2339      */
2340     public void updateDependencies(UIComponent parent) throws UIWidgetException {
2341         setParent(parent);
2342     }
2343
2344     /**
2345      * Add a list of children
2346      * @param list the children
2347      */
2348     public void add(List<UIComponent> list) throws UIWidgetException {
2349         for (UIComponent uicomp : list) {
2350             add(uicomp);
2351         }
2352     }
2353
2354     /**
2355      * Add an UIComponent to the children list
2356      * @parent uicomp the child to add
2357      */
2358     public void add(final UIComponent uicomp) throws UIWidgetException {
2359         UIAccessTools.add(this, uicomp);
2360     }
2361
2362     /**
2363      * Add an UIListener
2364      * @parent uicomp the listener to add
2365      */
2366     public void addListener(final UIListener uicomp) throws UIWidgetException {
2367         uicomp.addListenerToComponent(getModifiableJComponent());
2368     }
2369
2370     /**
2371      * Add a popup menu
2372      * @param popup the popup menu
2373      */
2374     public void addPopupMenu(final JPopupMenu popup) {
2375         UIAccessTools.execOnEDT(new Runnable() {
2376             public void run() {
2377                 try {
2378                     getModifiableJComponent().setComponentPopupMenu(popup);
2379                 } catch (Exception e) {
2380
2381                 }
2382             }
2383         });
2384     }
2385
2386     /**
2387      * Set a property of this component
2388      * @param name the property name
2389      * @param value the property value
2390      */
2391     public void setProperty(final String name, final String value) throws UIWidgetException {
2392         try {
2393             if (thisOrComponent) {
2394                 setPropertyViaReflectionInThis(name, value);
2395             } else {
2396                 setPropertyViaReflectionInComponent(name, value);
2397             }
2398         } catch (Exception e) {
2399             if (thisOrComponent) {
2400                 setPropertyViaReflectionInComponent(name, value);
2401             } else {
2402                 setPropertyViaReflectionInThis(name, value);
2403             }
2404         }
2405     }
2406
2407     /**
2408      * Set a property (via relection) of this component
2409      * @param name the property name
2410      * @param value the property value
2411      */
2412     protected final void setPropertyViaReflectionInThis(final String name, final String value) throws UIWidgetException {
2413         UIAccessTools.setPropertyViaReflection(this, name, value);
2414     }
2415
2416     /**
2417      * Set a property (via relection) of the modifiable component
2418      * @param name the property name
2419      * @param value the property value
2420      */
2421     protected final void setPropertyViaReflectionInComponent(final String name, final String value) throws UIWidgetException {
2422         UIAccessTools.setPropertyViaReflection(getModifiableComponent(), name, value);
2423     }
2424
2425     /**
2426      * Set a property of this component
2427      * @param name the property name
2428      * @param value the property value
2429      */
2430     public void setProperty(final String name, final ScilabType value) throws UIWidgetException {
2431         try {
2432             if (thisOrComponent) {
2433                 setPropertyViaReflectionInThis(name, value);
2434             } else {
2435                 setPropertyViaReflectionInComponent(name, value);
2436             }
2437         } catch (Exception e) {
2438             if (thisOrComponent) {
2439                 setPropertyViaReflectionInComponent(name, value);
2440             } else {
2441                 setPropertyViaReflectionInThis(name, value);
2442             }
2443         }
2444     }
2445
2446     /**
2447      * Set a property of this component
2448      * @param name the property name
2449      * @param value the property value
2450      */
2451     public void setProperty(final List<String> names, final List<ScilabType> values) throws UIWidgetException {
2452         if (names != null && values != null) {
2453             final Object modifiableComponent = getModifiableComponent();
2454             final Class clazzThis = this.getClass();
2455             final Class clazzComp = modifiableComponent.getClass();
2456             final List<Object> objs = new ArrayList<Object>(names.size());
2457             final List<Method> methods = new ArrayList<Method>(names.size());
2458
2459             for (String name : names) {
2460                 String methodName = UIAccessTools.getSetterName(name);
2461                 Method method;
2462                 if (thisOrComponent) {
2463                     method = UIMethodFinder.findSetter(methodName, clazzThis);
2464                     if (method == null) {
2465                         method = UIMethodFinder.findSetter(methodName, clazzComp);
2466                         if (method == null) {
2467                             throw new UIWidgetException("No attribute " + name + " in " + clazzThis.getSimpleName());
2468                         }
2469                         objs.add(modifiableComponent);
2470                     } else {
2471                         objs.add(this);
2472                     }
2473                 } else {
2474                     method = UIMethodFinder.findSetter(methodName, clazzComp);
2475                     if (method == null) {
2476                         method = UIMethodFinder.findSetter(methodName, clazzThis);
2477                         if (method == null) {
2478                             throw new UIWidgetException("No attribute " + name + " in " + clazzThis.getSimpleName());
2479                         }
2480                         objs.add(this);
2481                     } else {
2482                         objs.add(modifiableComponent);
2483                     }
2484                 }
2485                 methods.add(method);
2486             }
2487
2488             UIAccessTools.execOnEDT(new Runnable() {
2489                 public void run() {
2490                     try {
2491                         for (int i = 0; i < objs.size(); i++) {
2492                             UIAccessTools.invokeSetter(methods.get(i), objs.get(i), values.get(i));
2493                         }
2494                     } catch (Exception e) {
2495                         System.err.println(e);
2496                     }
2497                 }
2498             });
2499         }
2500     }
2501
2502     /**
2503      * Set a property (via relection) of this component
2504      * @param name the property name
2505      * @param value the property value
2506      */
2507     protected final void setPropertyViaReflectionInThis(final String name, final ScilabType value) throws UIWidgetException {
2508         UIAccessTools.setPropertyViaReflection(this, name, value);
2509     }
2510
2511     /**
2512      * Set a property (via relection) of the modifiable component
2513      * @param name the property name
2514      * @param value the property value
2515      */
2516     protected final void setPropertyViaReflectionInComponent(final String name, final ScilabType value) throws UIWidgetException {
2517         UIAccessTools.setPropertyViaReflection(getModifiableComponent(), name, value);
2518     }
2519
2520     /**
2521      * Get the pairs property name -- method name
2522      * @return the pairs
2523      */
2524     public String[][] getPropertiesPairs() {
2525         Map<String, Method> map = new TreeMap<String, Method>();
2526         if (thisOrComponent) {
2527             UIMethodFinder.getSetter(getModifiableComponent().getClass(), map);
2528             UIMethodFinder.getSetter(this.getClass(), map);
2529         } else {
2530             UIMethodFinder.getSetter(this.getClass(), map);
2531             UIMethodFinder.getSetter(getModifiableComponent().getClass(), map);
2532         }
2533
2534         System.out.println(this.getClass() + ": (" + map.size() + " entries)");
2535         for (Map.Entry<String, Method> entry : map.entrySet()) {
2536             System.out.println(entry.getKey() + " --> " + entry.getValue());
2537         }
2538
2539         return null;
2540     }
2541
2542     /**
2543      * Get a property value
2544      * @param name the property name
2545      */
2546     public Object getProperty(final String name) throws UIWidgetException {
2547         try {
2548             if (thisOrComponent) {
2549                 return getPropertyViaReflectionInThis(name);
2550             } else {
2551                 return getPropertyViaReflectionInComponent(name);
2552             }
2553         } catch (Exception e) {
2554             if (thisOrComponent) {
2555                 return getPropertyViaReflectionInComponent(name);
2556             } else {
2557                 return getPropertyViaReflectionInThis(name);
2558             }
2559         }
2560     }
2561
2562     /**
2563      * Get a property value (via reflection)
2564      * @param name the property name
2565      */
2566     protected Object getPropertyViaReflectionInThis(final String name) throws UIWidgetException {
2567         return UIAccessTools.getPropertyViaReflection(this, name);
2568     }
2569
2570     /**
2571      * Get a property value (via reflection) in the modifiable component
2572      * @param name the property name
2573      */
2574     protected Object getPropertyViaReflectionInComponent(final String name) throws UIWidgetException {
2575         return UIAccessTools.getPropertyViaReflection(getModifiableComponent(), name);
2576     }
2577
2578     /**
2579      * Create a new instance
2580      * @param attributes the attributes
2581      */
2582     private void createNewInstance(final ConvertableMap attributes) throws UIWidgetException {
2583         Set<String> uselessAttrs = UIAccessTools.createNewInstance(this, attributes);
2584         if (uselessAttrs.contains("scrollable")) {
2585             boolean scrollable = (Boolean) attributes.get(boolean.class, "scrollable", false);
2586             if (scrollable && component instanceof JComponent) {
2587                 modifiableComponent = component;
2588                 if (SwingUtilities.isEventDispatchThread()) {
2589                     component = new JScrollPane((JComponent) modifiableComponent);
2590                 } else {
2591                     try {
2592                         SwingUtilities.invokeAndWait(new Runnable() {
2593                             public void run() {
2594                                 try {
2595                                     component = new JScrollPane((JComponent) modifiableComponent);
2596                                 } catch (Exception e) {
2597                                     System.err.println(e);
2598                                     e.printStackTrace();
2599                                 }
2600                             }
2601                         });
2602                     } catch (Exception e) {
2603                         System.err.println(e);
2604                         e.printStackTrace();
2605                     }
2606                 }
2607                 uselessAttrs.remove("scrollable");
2608             }
2609         }
2610
2611         if (uselessAttrs.contains("position")) {
2612             if (attributes instanceof StringMap) {
2613                 setNoLayoutConstraint(StringConverters.getObjectFromValue(Rectangle2D.Double.class, (String) attributes.get("position")));
2614             } else {
2615                 setNoLayoutConstraint(ScilabTypeConverters.getObjectFromValue(Rectangle2D.Double.class, (ScilabType) attributes.get("position")));
2616             }
2617             uselessAttrs.remove("position");
2618         }
2619
2620         setAttributesAndStyle(attributes, uselessAttrs);
2621     }
2622
2623     /**
2624      * Set the attributes and style
2625      * @param attributes the attributes
2626      * @param uselessAttrs the useless attributes
2627      */
2628     private void setAttributesAndStyle(final ConvertableMap attributes, final Set<String> uselessAttrs) {
2629         if (!uselessAttrs.isEmpty()) {
2630             UIAccessTools.execOnEDT(new Runnable() {
2631                 public void run() {
2632                     if (attributes instanceof StringMap) {
2633                         for (String attr : uselessAttrs) {
2634                             try {
2635                                 setProperty(attr, (String) attributes.get(attr));
2636                             } catch (UIWidgetException e) { }
2637                         }
2638                     } else {
2639                         for (String attr : uselessAttrs) {
2640                             try {
2641                                 setProperty(attr, (ScilabType) attributes.get(attr));
2642                             } catch (UIWidgetException e) { }
2643                         }
2644                     }
2645
2646                     if (component instanceof JComponent && nolayoutconstraint == null) {
2647                         JComponent jc = (JComponent) component;
2648                         Dimension d = jc.getPreferredSize();
2649                         setNoLayoutConstraint(0, 0, (double) d.width, (double) d.height);
2650                         nolayoutconstraint.setUnit(0, 0, 0, 0);
2651                     }
2652                 }
2653             });
2654         } else {
2655             if (component instanceof JComponent && nolayoutconstraint == null) {
2656                 UIAccessTools.execOnEDT(new Runnable() {
2657                     public void run() {
2658                         JComponent jc = (JComponent) component;
2659                         Dimension d = jc.getPreferredSize();
2660                         setNoLayoutConstraint(0, 0, (double) d.width, (double) d.height);
2661                         nolayoutconstraint.setUnit(0, 0, 0, 0);
2662                     }
2663                 });
2664             }
2665         }
2666
2667         if (style != null) {
2668             Map<String, String> elementStyle = null;
2669             if (id != null) {
2670                 elementStyle = style.get("#" + id);
2671             }
2672
2673             if (elementStyle == null) {
2674                 String styleClass = (String) attributes.get(String.class, "class", null);
2675                 if (styleClass != null) {
2676                     elementStyle = style.get(styleClass);
2677                 }
2678             }
2679             if (elementStyle == null) {
2680                 elementStyle = style.get("." + this.getClass().getSimpleName());
2681             }
2682
2683             final Map<String, String> es = elementStyle;
2684             if (elementStyle != null) {
2685                 UIAccessTools.execOnEDT(new Runnable() {
2686                     public void run() {
2687                         try {
2688                             setUiStyle(new HashMap<String, String>(es));
2689                         } catch (UIWidgetException e) {
2690                             System.err.println(e);
2691                             e.printStackTrace();
2692                         }
2693                     }
2694                 });
2695             }
2696         }
2697
2698     }
2699
2700     /**
2701      * {@inheritdoc}
2702      */
2703     protected void finalize() throws Throwable {
2704         UserData.removeUIWidgetUserData(uid);
2705         super.finalize();
2706     }
2707 }