UIW: fix font size issue (getter)
[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             fontUnit = UITools.FontUnit.PIXELS;
1093         }
1094         for (String key : style.keySet()) {
1095             try {
1096                 setProperty(key, style.get(key));
1097             } catch (UIWidgetException e) { }
1098         }
1099     }
1100
1101     /**
1102      * Set the tab title if the component is in a JTabbedPane
1103      * @param title the tab title
1104      */
1105     public void setTabTitle(String title) throws UIWidgetException {
1106         if (parent instanceof UITab && title != null && component != null) {
1107             JComponent c = getJComponent();
1108             JTabbedPane tab = (JTabbedPane) ((UITab) parent).getJComponent();
1109             int index = tab.indexOfTabComponent(c);
1110             if (index != -1) {
1111                 tab.setTitleAt(index, title);
1112             }
1113         }
1114         this.tabTitle = title;
1115     }
1116
1117     /**
1118      * Get the tab title if the component is in a JTabbedPane
1119      * @return the tab title
1120      */
1121     public String getTabTitle() throws UIWidgetException {
1122         return tabTitle;
1123     }
1124
1125     /**
1126      * Set the tooltip text
1127      * @param text the tooltip text
1128      */
1129     public void setTooltip(String text) throws UIWidgetException {
1130         getModifiableJComponent().setToolTipText(text);
1131     }
1132
1133     /**
1134      * Get the tooltip text
1135      * @return the tooltip text
1136      */
1137     public String getTooltip() throws UIWidgetException {
1138         return getModifiableJComponent().getToolTipText();
1139     }
1140
1141     /**
1142      * Set the tooltip text
1143      * @param text the tooltip text
1144      */
1145     public void setTooltipString(String text) throws UIWidgetException {
1146         setTooltip(text);
1147     }
1148
1149     /**
1150      * Get the tooltip text
1151      * @return the tooltip text
1152      */
1153     public String getTooltipString() throws UIWidgetException {
1154         return getTooltip();
1155     }
1156
1157     /**
1158      * Set the foreground color
1159      * @param c the color
1160      */
1161     public void setColor(Color c) throws UIWidgetException {
1162         getModifiableJComponent().setForeground(c);
1163     }
1164
1165     /**
1166      * Get the foreground color
1167      * @return the foreground color
1168      */
1169     public Color getColor() throws UIWidgetException {
1170         return getModifiableJComponent().getForeground();
1171     }
1172
1173     /**
1174      * Set the font unit
1175      * @param name the font name
1176      */
1177     public void setFontUnits(UITools.FontUnit unit) throws UIWidgetException {
1178         // TODO: actuellement ds uic, fontunit est ignore et est dc egale a PIXELS
1179         double ratio = UITools.FontUnit.getRatio(fontUnit, UITools.FontUnit.PIXELS);//unit);
1180         if (ratio != 1) {
1181             this.fontUnit = unit;
1182             Font f = getFont();
1183             if (f != null) {
1184                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1185                 map.put(TextAttribute.SIZE, new Double(f.getSize2D() * ratio));
1186                 setFont(new Font(map));
1187             }
1188         }
1189     }
1190
1191     public String getFontUnits() {
1192         return UITools.FontUnit.getAsString(this.fontUnit);
1193     }
1194
1195     /**
1196      * Set the font name
1197      * @param name the font name
1198      */
1199     public void setFontName(String name) throws UIWidgetException {
1200         Font f = getFont();
1201         if (f != null) {
1202             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1203             map.put(TextAttribute.FAMILY, name);
1204             setFont(new Font(map));
1205         }
1206     }
1207
1208     /**
1209      * Get the font name
1210      * @return name the font name
1211      */
1212     public String getFontName() throws UIWidgetException {
1213         Font f = getFont();
1214         if (f != null) {
1215             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1216             return (String) map.get(TextAttribute.FAMILY);
1217         }
1218
1219         return null;
1220     }
1221
1222     /**
1223      * Set the font size
1224      * @param size the font size
1225      */
1226     public void setFontSize(double size) throws UIWidgetException {
1227         double ratio = UITools.FontUnit.getRatio(fontUnit);
1228         Font f = getFont();
1229         if (f != null) {
1230             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1231             map.put(TextAttribute.SIZE, (Double.isNaN(size) || size < 0 || Double.isInfinite(size)) ? new Double(12.0 * ratio) : new Double(size * ratio));
1232             setFont(new Font(map));
1233         }
1234     }
1235
1236     /**
1237      * Get the font size
1238      * @return the font size
1239      */
1240     public double getFontSize() throws UIWidgetException {
1241         Font f = getFont();
1242         if (f != null) {
1243             double ratio = UITools.FontUnit.getRatio(fontUnit);
1244             return Math.round(f.getSize2D() / ratio);
1245         }
1246
1247         return -1;
1248     }
1249
1250     /**
1251      * Set the font weight
1252      * @param weight the font weight
1253      */
1254     public void setFontWeight(UITools.FontWeight weight) throws UIWidgetException {
1255         if (weight != null) {
1256             Font f = getFont();
1257             if (f != null) {
1258                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1259                 map.put(TextAttribute.WEIGHT, weight.value());
1260                 setFont(new Font(map));
1261             }
1262         }
1263     }
1264
1265     /**
1266      * Get the font weight
1267      * @return the font weight
1268      */
1269     public String getFontWeight() throws UIWidgetException {
1270         Font f = getFont();
1271         if (f != null) {
1272             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1273             Float fl = (Float) map.get(TextAttribute.WEIGHT);
1274             return UITools.mapTextAttribute.get(fl);
1275         }
1276
1277         return null;
1278     }
1279
1280     /**
1281      * Set the font angle
1282      * @param angle the font angle
1283      */
1284     public void setFontAngle(String angle) throws UIWidgetException {
1285         if (angle != null && !angle.isEmpty()) {
1286             angle = angle.toLowerCase();
1287             boolean italic = angle.equals("italic") || angle.equals("oblique") || angle.equals("it");
1288             Font f = getFont();
1289             if (f != null) {
1290                 Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1291                 map.put(TextAttribute.POSTURE, italic ? TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR);
1292                 setFont(new Font(map));
1293             }
1294         }
1295     }
1296
1297     /**
1298      * Get the font angle
1299      * @return the font angle
1300      */
1301     public String getFontAngle() throws UIWidgetException {
1302         Font f = getFont();
1303         if (f != null) {
1304             Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) f.getAttributes();
1305             Float fl = (Float) map.get(TextAttribute.POSTURE);
1306             if (fl == null || fl == TextAttribute.POSTURE_REGULAR) {
1307                 return "normal";
1308             } else {
1309                 return "italic";
1310             }
1311         }
1312
1313         return null;
1314     }
1315
1316     /**
1317      * Set the component relief
1318      * @param relief a string which represents the relief
1319      */
1320     public void setRelief(String relief) throws UIWidgetException {
1321         if (relief != null) {
1322             getJComponent().setBorder(ScilabRelief.getBorderFromRelief(relief));
1323             this.relief = relief;
1324         }
1325     }
1326
1327     /**
1328      * Get the relief
1329      * @return the relief
1330      */
1331     public String getRelief() {
1332         return this.relief;
1333     }
1334
1335     /**
1336      * Set the font
1337      * @param f the font
1338      */
1339     public void setFont(Font f) throws UIWidgetException {
1340         getModifiableJComponent().setFont(f);
1341         getJComponent().revalidate();
1342     }
1343
1344     /**
1345      * Get the font
1346      * @return the font
1347      */
1348     public Font getFont() throws UIWidgetException {
1349         return getModifiableJComponent().getFont();
1350     }
1351
1352     public void setUnits(String[] unit) throws UIWidgetException {
1353         if (unit != null) {
1354             boolean mustLayout = false;
1355             if (unit.length >= 4) {
1356                 final int[] units = new int[4];
1357                 for (int i = 0; i < 4; i++) {
1358                     if (unit[i].equals("%") || unit[i].equalsIgnoreCase("n") || unit[i].equalsIgnoreCase("normalized")) {
1359                         units[i] = 1;
1360                     } else if (unit[i].equals("pt") || unit[i].equalsIgnoreCase("points")) {
1361                         units[i] = 2;
1362                     } else {
1363                         units[i] = 0;
1364                     }
1365                 }
1366
1367                 if (this.nolayoutconstraint == null) {
1368                     this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1369                 }
1370
1371                 this.nolayoutconstraint.setUnit(units[0], units[1], units[2], units[3]);
1372                 mustLayout = true;
1373             } else if (unit.length == 1) {
1374                 int u = 0;
1375                 if (!unit[0].isEmpty()) {
1376                     if (unit[0].equalsIgnoreCase("points")) {
1377                         u = 2;
1378                     } else if (unit[0].equalsIgnoreCase("normalized")) {
1379                         u = 1;
1380                     }
1381                 }
1382
1383                 if (this.nolayoutconstraint == null) {
1384                     this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1385                 }
1386
1387                 this.nolayoutconstraint.setUnit(u, u, u, u);
1388                 mustLayout = true;
1389             }
1390
1391             if (mustLayout) {
1392                 Container p = getJComponent().getParent();
1393                 if (p != null && p.getLayout() instanceof NoLayout) {
1394                     p.invalidate();
1395                     p.doLayout();
1396                     p.repaint();
1397                 }
1398             }
1399         }
1400     }
1401
1402     /**
1403      * Get the position unit (when NoLayout has been set)
1404      * @return the units
1405      */
1406     public String[] getUnits() throws UIWidgetException {
1407         String[] ret;
1408         boolean allTheSame = true;
1409         for (int i = 1; i < 4; i++) {
1410             if (nolayoutconstraint.unit[i] != nolayoutconstraint.unit[0]) {
1411                 allTheSame = false;
1412                 break;
1413             }
1414         }
1415
1416         if (allTheSame) {
1417             ret = new String[1];
1418             switch (nolayoutconstraint.unit[0]) {
1419                 case 1:
1420                     ret[0] = "normalized";
1421                     break;
1422                 case 2:
1423                     ret[0] = "points";
1424                     break;
1425                 default:
1426                     ret[0] = "pixels";
1427                     break;
1428             }
1429         } else {
1430             ret = new String[4];
1431             for (int i = 0; i < 4; i++) {
1432                 switch (nolayoutconstraint.unit[i]) {
1433                     case 1:
1434                         ret[i] = "%";
1435                         break;
1436                     case 2:
1437                         ret[i] = "pt";
1438                         break;
1439                     default:
1440                         ret[i] = "px";
1441                         break;
1442                 }
1443             }
1444         }
1445
1446         return ret;
1447     }
1448
1449     /**
1450      * Get the constraint when no layout
1451      * @return the constraint
1452      */
1453     public NoLayout.NoLayoutConstraint getNoLayoutConstraint() {
1454         return nolayoutconstraint;
1455     }
1456
1457     private void setNoLayoutConstraint(Rectangle2D.Double r) {
1458         if (this.nolayoutconstraint == null) {
1459             this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1460         }
1461
1462         this.nolayoutconstraint.setPoint(r.x, r.y);
1463         this.nolayoutconstraint.setDims(r.width, r.height);
1464         this.nolayoutconstraint.setUnit(0, 0, 0, 0);
1465     }
1466
1467     /**
1468      * Set the location
1469      * @param p the location
1470      */
1471     public void setLocation(Point p) throws UIWidgetException {
1472         if (p != null) {
1473             Rectangle2D.Double pos = getPosition();
1474             if (pos != null) {
1475                 setPosition(new Rectangle2D.Double(p.x, p.y, pos.width, pos.height));
1476             }
1477         }
1478     }
1479
1480     /**
1481      * Set the position (when NoLayout has been set)
1482      * @param r the position
1483      */
1484     public void setPosition(Rectangle2D.Double r) throws UIWidgetException {
1485         if (r != null) {
1486             if (getComponent() == null) {
1487                 setNoLayoutConstraint(r);
1488                 return;
1489             }
1490
1491             if (getComponent() instanceof Component) {
1492                 Component c = (Component) getComponent();
1493                 Container p = c.getParent();
1494                 if (c instanceof JFrame) {
1495                     JFrame win = (JFrame) c;
1496                     win.setLocation((int) r.x, (int) r.y);
1497                     Dimension dim = win.getSize();
1498                     if (dim.width != (int) r.width || dim.height != (int) r.height) {
1499                         win.setPreferredSize(new Dimension((int) r.width, (int) r.height));
1500                         if (win.isVisible()) {
1501                             win.invalidate();
1502                             win.pack();
1503                             win.repaint();
1504                         }
1505                     }
1506                 } else if (p == null || p.getLayout() instanceof NoLayout) {
1507                     if (this.nolayoutconstraint == null) {
1508                         this.nolayoutconstraint = new NoLayout.NoLayoutConstraint();
1509                     }
1510
1511                     this.nolayoutconstraint.setPoint(r.x, r.y);
1512                     if (this.nolayoutconstraint.bounds.width != r.width || this.nolayoutconstraint.bounds.height != r.height) {
1513                         this.nolayoutconstraint.setDims(r.width, r.height);
1514                         if (p == null) {
1515                             c.setSize((int) r.width, (int) r.height);
1516                             c.invalidate();
1517                             c.validate();
1518                         }
1519                     }
1520                     if (p != null && p.isVisible()) {
1521                         p.invalidate();
1522                         p.validate();
1523                         p.repaint();
1524                     }
1525                 } else if (p.getLayout() == null) {
1526                     c.setSize((int) r.width, (int) r.height);
1527                     c.invalidate();
1528                     c.validate();
1529                 }
1530             }
1531         }
1532     }
1533
1534     /**
1535      * Get the position
1536      * @return the position
1537      */
1538     public Rectangle2D.Double getPosition() throws UIWidgetException {
1539         if (getComponent() instanceof Component) {
1540             Component c = (Component) getComponent();
1541             Container p = c.getParent();
1542             if (p != null && p.getLayout() instanceof NoLayout) {
1543                 return this.nolayoutconstraint.bounds;
1544             }
1545
1546             Dimension d = c.getSize();
1547             Point pt = c.getLocation();
1548
1549             return new Rectangle2D.Double(pt.x, pt.y, d.width, d.height);
1550         }
1551
1552         return null;
1553     }
1554
1555     /**
1556      * Set the foreground color
1557      * @param c the color
1558      */
1559     public void setForegroundColor(Color c) throws UIWidgetException {
1560         if (c != null) {
1561             getModifiableJComponent().setForeground(c);
1562         }
1563     }
1564
1565     /**
1566      * Get the foreground color
1567      * @return the foreground color
1568      */
1569     public Color getForegroundColor() throws UIWidgetException {
1570         return getModifiableJComponent().getForeground();
1571     }
1572
1573     /**
1574      * Set the background color
1575      * @param c the color
1576      */
1577     public void setBackgroundColor(Color c) throws UIWidgetException {
1578         if (c != null) {
1579             getModifiableJComponent().setBackground(c);
1580         }
1581     }
1582
1583     /**
1584      * Get the background color
1585      * @return the background color
1586      */
1587     public Color getBackgroundColor() throws UIWidgetException {
1588         return getModifiableJComponent().getBackground();
1589     }
1590
1591     /**
1592      * Set the component scrollable or not
1593      * @param b if true the component will be scrollable
1594      */
1595     public void setScrollable(boolean b) {
1596         if (component instanceof JScrollPane) {
1597             JScrollPane scroll = (JScrollPane) component;
1598             if (b) {
1599                 scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
1600                 scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
1601             } else {
1602                 scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
1603                 scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
1604             }
1605         } else if (component instanceof JComponent && b) {
1606             JComponent c = (JComponent) component;
1607             JScrollPane scroll = new MyScrollPane();
1608             replaceBy(scroll);
1609             scroll.getViewport().setView(c);
1610             modifiableComponent = c;
1611         }
1612     }
1613
1614     /**
1615      * Check if the component is scrollable
1616      * @return true if the component is scrollable
1617      */
1618     public boolean getScrollable() {
1619         return component instanceof JScrollPane && ((JScrollPane) component).getHorizontalScrollBarPolicy() == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
1620     }
1621
1622     /**
1623      * Set the horizontal block increment (pgup, pgdown in scroll)
1624      * @param blockIncrement the block increment
1625      */
1626     public void setHorizontalBlockIncrement(int blockIncrement) {
1627         if (component instanceof JScrollPane) {
1628             JScrollPane scroll = (JScrollPane) component;
1629             JScrollBar bar = scroll.getHorizontalScrollBar();
1630             if (bar != null) {
1631                 bar.setBlockIncrement(blockIncrement);
1632             }
1633         }
1634     }
1635
1636     /**
1637      * Get the horizontal block increment
1638      * @return block increment
1639      */
1640     public int getHorizontalBlockIncrement() {
1641         if (component instanceof JScrollPane) {
1642             JScrollPane scroll = (JScrollPane) component;
1643             JScrollBar bar = scroll.getHorizontalScrollBar();
1644             if (bar != null) {
1645                 return bar.getBlockIncrement();
1646             }
1647         }
1648
1649         return -1;
1650     }
1651
1652     /**
1653      * Set the vertical block increment (pgup, pgdown in scroll)
1654      * @param blockIncrement the block increment
1655      */
1656     public void setVerticalBlockIncrement(int blockIncrement) {
1657         if (component instanceof JScrollPane) {
1658             JScrollPane scroll = (JScrollPane) component;
1659             JScrollBar bar = scroll.getVerticalScrollBar();
1660             if (bar != null) {
1661                 bar.setBlockIncrement(blockIncrement);
1662             }
1663         }
1664     }
1665
1666     /**
1667      * Get the vertical block increment
1668      * @return block increment
1669      */
1670     public int getVerticalBlockIncrement() {
1671         if (component instanceof JScrollPane) {
1672             JScrollPane scroll = (JScrollPane) component;
1673             JScrollBar bar = scroll.getVerticalScrollBar();
1674             if (bar != null) {
1675                 return bar.getBlockIncrement();
1676             }
1677         }
1678
1679         return -1;
1680     }
1681
1682     /**
1683      * Set the horizontal unit increment (wheel in scroll)
1684      * @param unitIncrement the unit increment
1685      */
1686     public void setHorizontalUnitIncrement(int unitIncrement) {
1687         if (component instanceof JScrollPane) {
1688             JScrollPane scroll = (JScrollPane) component;
1689             JScrollBar bar = scroll.getHorizontalScrollBar();
1690             if (bar != null) {
1691                 bar.setUnitIncrement(unitIncrement);
1692             }
1693         }
1694     }
1695
1696     /**
1697      * Get the horizontal unit increment
1698      * @return unit increment
1699      */
1700     public int getHorizontalUnitIncrement() {
1701         if (component instanceof JScrollPane) {
1702             JScrollPane scroll = (JScrollPane) component;
1703             JScrollBar bar = scroll.getHorizontalScrollBar();
1704             if (bar != null) {
1705                 return bar.getUnitIncrement();
1706             }
1707         }
1708
1709         return -1;
1710     }
1711
1712     /**
1713      * Set the vertical unit increment (wheel in scroll)
1714      * @param unitIncrement the unit increment
1715      */
1716     public void setVerticalUnitIncrement(int unitIncrement) {
1717         if (component instanceof JScrollPane) {
1718             JScrollPane scroll = (JScrollPane) component;
1719             JScrollBar bar = scroll.getVerticalScrollBar();
1720             if (bar != null) {
1721                 bar.setUnitIncrement(unitIncrement);
1722             }
1723         }
1724     }
1725
1726     /**
1727      * Get the vertical unit increment
1728      * @return unit increment
1729      */
1730     public int getVerticalUnitIncrement() {
1731         if (component instanceof JScrollPane) {
1732             JScrollPane scroll = (JScrollPane) component;
1733             JScrollBar bar = scroll.getVerticalScrollBar();
1734             if (bar != null) {
1735                 return bar.getUnitIncrement();
1736             }
1737         }
1738
1739         return -1;
1740     }
1741
1742     /**
1743      * Set the horizontal scroll value
1744      * @param value the value
1745      */
1746     public void setHorizontalScrollValue(int value) {
1747         if (component instanceof MyScrollPane) {
1748             MyScrollPane scroll = (MyScrollPane) component;
1749             JScrollBar bar = scroll.getHorizontalScrollBar();
1750             if (bar != null) {
1751                 final int width = scroll.getViewport().getView().getPreferredSize().width;
1752                 if (width != bar.getMaximum()) {
1753                     scroll.hvalue = value;
1754                 } else {
1755                     bar.setValue(value);
1756                 }
1757             }
1758         }
1759     }
1760
1761     /**
1762      * Get the horizontal scroll value
1763      * @return the scroll value
1764      */
1765     public int getHorizontalScrollValue() {
1766         if (component instanceof JScrollPane) {
1767             JScrollPane scroll = (JScrollPane) component;
1768             JScrollBar bar = scroll.getHorizontalScrollBar();
1769             if (bar != null) {
1770                 return bar.getValue();
1771             }
1772         }
1773
1774         return -1;
1775     }
1776
1777     /**
1778      * Set the vertical scroll value
1779      * @param value the value
1780      */
1781     public void setVerticalScrollValue(int value) {
1782         if (component instanceof MyScrollPane) {
1783             MyScrollPane scroll = (MyScrollPane) component;;
1784             JScrollBar bar = scroll.getVerticalScrollBar();
1785             if (bar != null) {
1786                 final int height = scroll.getViewport().getView().getPreferredSize().height;
1787                 if (height != bar.getMaximum()) {
1788                     scroll.vvalue = value;
1789                 } else {
1790                     bar.setValue(value);
1791                 }
1792             }
1793         }
1794     }
1795
1796     /**
1797      * Get the vertical scroll value
1798      * @return the scroll value
1799      */
1800     public int getVerticalScrollValue() {
1801         if (component instanceof JScrollPane) {
1802             JScrollPane scroll = (JScrollPane) component;
1803             JScrollBar bar = scroll.getVerticalScrollBar();
1804             if (bar != null) {
1805                 return bar.getValue();
1806             }
1807         }
1808
1809         return -1;
1810     }
1811
1812     /**
1813      * Set the component constraints
1814      * @param constraint a string containing layout constraints (CSS style)
1815      */
1816     public void setConstraint(String constraint) throws UIWidgetException {
1817         setConstraint(StyleParser.parseLine(constraint));
1818     }
1819
1820     /**
1821      * Set the component constraints
1822      * @param constraint a map containing layout constraints
1823      */
1824     public void setConstraint(Map<String, String> constraint) throws UIWidgetException {
1825         this.constraint = constraint;
1826         Container p = getJComponent().getParent();
1827         if (p != null && !(p.getLayout() instanceof NoLayout) && getParent() != null) {
1828             getParent().add(this);
1829             p.invalidate();
1830             p.validate();
1831         }
1832     }
1833
1834     /**
1835      * Get the constraint
1836      * @return constraint as String
1837      */
1838     public String getConstraint() {
1839         if (constraint != null) {
1840             String str = "";
1841             for (Map.Entry<String, String> entry : constraint.entrySet()) {
1842                 str += entry.getKey() + ":" + entry.getValue();
1843             }
1844
1845             return str;
1846         }
1847
1848         return null;
1849     }
1850
1851     /**
1852      * Set the layout
1853      * @param layout the layout informations (CSS style)
1854      */
1855     public void setLayout(String layout) throws UIWidgetException {
1856         getModifiableContainer().setLayout(UILayoutFactory.getLayout(getModifiableJComponent(), layout));
1857     }
1858
1859     /**
1860      * Enable or not the component
1861      * @param enable if true, the component is enabled
1862      */
1863     public void setEnable(boolean enable) throws UIWidgetException {
1864         getJComponent().setEnabled(enable);
1865     }
1866
1867     /**
1868      * Check if the component is enabled
1869      * @return true if the component is enabled
1870      */
1871     public boolean getEnable() throws UIWidgetException {
1872         return getJComponent().isEnabled();
1873     }
1874
1875     /**
1876      * Create a MouseListener on this component
1877      */
1878     private final void createMouseListener() throws UIWidgetException {
1879         if (mouseListener == null) {
1880             mouseListener = new UIMouseListener(this);
1881             mouseListener.newInstance();
1882             mouseListener.addListenerToComponent(getModifiableJComponent());
1883         }
1884     }
1885
1886     /**
1887      * Set onmouseclick action
1888      * @param command the command to execute
1889      */
1890     public void setOnmouseclick(String command) throws UIWidgetException {
1891         if (command != null && !command.isEmpty()) {
1892             createMouseListener();
1893             mouseListener.setOnmouseclick(command);
1894         }
1895     }
1896
1897     /**
1898      * Set onmouseover action
1899      * @param command the command to execute
1900      */
1901     public void setOnmouseover(String command) throws UIWidgetException {
1902         if (command != null && !command.isEmpty()) {
1903             createMouseListener();
1904             mouseListener.setOnmouseover(command);
1905         }
1906     }
1907
1908     /**
1909      * Set onmouseenter action
1910      * @param command the command to execute
1911      */
1912     public void setOnmouseenter(String command) throws UIWidgetException {
1913         if (command != null && !command.isEmpty()) {
1914             createMouseListener();
1915             mouseListener.setOnmouseenter(command);
1916         }
1917     }
1918
1919     /**
1920      * Set onmouseexit action
1921      * @param command the command to execute
1922      */
1923     public void setOnmouseexit(String command) throws UIWidgetException {
1924         if (command != null && !command.isEmpty()) {
1925             createMouseListener();
1926             mouseListener.setOnmouseexit(command);
1927         }
1928     }
1929
1930     /**
1931      * Set onmousepress action
1932      * @param command the command to execute
1933      */
1934     public void setOnmousepress(String command) throws UIWidgetException {
1935         if (command != null && !command.isEmpty()) {
1936             createMouseListener();
1937             mouseListener.setOnmousepress(command);
1938         }
1939     }
1940
1941     /**
1942      * Set onmouserelease action
1943      * @param command the command to execute
1944      */
1945     public void setOnmouserelease(String command) throws UIWidgetException {
1946         if (command != null && !command.isEmpty()) {
1947             createMouseListener();
1948             mouseListener.setOnmouserelease(command);
1949         }
1950     }
1951
1952     /**
1953      * Set onmousewheel action
1954      * @param command the command to execute
1955      */
1956     public void setOnmousewheel(String command) throws UIWidgetException {
1957         if (command != null && !command.isEmpty()) {
1958             createMouseListener();
1959             mouseListener.setOnmousewheel(command);
1960         }
1961     }
1962
1963     /**
1964      * Set onmousedrag action
1965      * @param command the command to execute
1966      */
1967     public void setOnmousedrag(String command) throws UIWidgetException {
1968         if (command != null && !command.isEmpty()) {
1969             createMouseListener();
1970             mouseListener.setOnmousedrag(command);
1971         }
1972     }
1973
1974     /**
1975      * Get onmouseclick action
1976      * @return the command to execute
1977      */
1978     public UICallback getOnmouseclick() {
1979         if (mouseListener != null) {
1980             return mouseListener.getOnmouseclick();
1981         }
1982
1983         return null;
1984     }
1985
1986     /**
1987      * Get onmouseover action
1988      * @return the command to execute
1989      */
1990     public UICallback getOnmouseover() {
1991         if (mouseListener != null) {
1992             return mouseListener.getOnmouseover();
1993         }
1994
1995         return null;
1996     }
1997
1998     /**
1999      * Get onmouseenter action
2000      * @return the command to execute
2001      */
2002     public UICallback getOnmouseenter() {
2003         if (mouseListener != null) {
2004             return mouseListener.getOnmouseenter();
2005         }
2006
2007         return null;
2008     }
2009
2010     /**
2011      * Get onmouseexit action
2012      * @return the command to execute
2013      */
2014     public UICallback getOnmouseexit() {
2015         if (mouseListener != null) {
2016             return mouseListener.getOnmouseexit();
2017         }
2018
2019         return null;
2020     }
2021
2022     /**
2023      * Get onmousepress action
2024      * @return the command to execute
2025      */
2026     public UICallback getOnmousepress() {
2027         if (mouseListener != null) {
2028             return mouseListener.getOnmousepress();
2029         }
2030
2031         return null;
2032     }
2033
2034     /**
2035      * Get onmouserelease action
2036      * @return the command to execute
2037      */
2038     public UICallback getOnmouserelease() {
2039         if (mouseListener != null) {
2040             return mouseListener.getOnmouserelease();
2041         }
2042
2043         return null;
2044     }
2045
2046     /**
2047      * Get onmousedrag action
2048      * @return the command to execute
2049      */
2050     public UICallback getOnmousedrag() {
2051         if (mouseListener != null) {
2052             return mouseListener.getOnmousedrag();
2053         }
2054
2055         return null;
2056     }
2057
2058     /**
2059      * Get onmousewheel action
2060      * @return the command to execute
2061      */
2062     public UICallback getOnmousewheel() {
2063         if (mouseListener != null) {
2064             return mouseListener.getOnmousewheel();
2065         }
2066
2067         return null;
2068     }
2069
2070     /**
2071      * Enable onmouseclick
2072      * @param b, if true the action is enabled
2073      */
2074     public void setOnmouseclickEnable(boolean b) {
2075         if (mouseListener != null) {
2076             mouseListener.setOnmouseclickEnable(b);
2077         }
2078     }
2079
2080     /**
2081      * Check if onmouseclick is enabled
2082      * @return true the action is enabled
2083      */
2084     public boolean getOnmouseclickEnable() {
2085         if (mouseListener != null) {
2086             return mouseListener.getOnmouseclickEnable();
2087         }
2088
2089         return false;
2090     }
2091
2092     /**
2093      * Enable onmouseover
2094      * @param b, if true the action is enabled
2095      */
2096     public void setOnmouseoverEnable(boolean b) {
2097         if (mouseListener != null) {
2098             mouseListener.setOnmouseoverEnable(b);
2099         }
2100     }
2101
2102     /**
2103      * Check if onmouseover is enabled
2104      * @return true the action is enabled
2105      */
2106     public boolean getOnmouseoverEnable() {
2107         if (mouseListener != null) {
2108             return mouseListener.getOnmouseoverEnable();
2109         }
2110
2111         return false;
2112     }
2113
2114     /**
2115      * Enable onmouseenter
2116      * @param b, if true the action is enabled
2117      */
2118     public void setOnmouseenterEnable(boolean b) {
2119         if (mouseListener != null) {
2120             mouseListener.setOnmouseenterEnable(b);
2121         }
2122     }
2123
2124     /**
2125      * Check if onmouseenter is enabled
2126      * @return true the action is enabled
2127      */
2128     public boolean getOnmouseenterEnable() {
2129         if (mouseListener != null) {
2130             return mouseListener.getOnmouseenterEnable();
2131         }
2132
2133         return false;
2134     }
2135
2136     /**
2137      * Enable onmouseexit
2138      * @param b, if true the action is enabled
2139      */
2140     public void setOnmouseexitEnable(boolean b) {
2141         if (mouseListener != null) {
2142             mouseListener.setOnmouseexitEnable(b);
2143         }
2144     }
2145
2146     /**
2147      * Check if onmouseexit is enabled
2148      * @return true the action is enabled
2149      */
2150     public boolean getOnmouseexitEnable() {
2151         if (mouseListener != null) {
2152             return mouseListener.getOnmouseexitEnable();
2153         }
2154
2155         return false;
2156     }
2157
2158     /**
2159      * Enable onmousepress
2160      * @param b, if true the action is enabled
2161      */
2162     public void setOnmousepressEnable(boolean b) {
2163         if (mouseListener != null) {
2164             mouseListener.setOnmousepressEnable(b);
2165         }
2166     }
2167
2168     /**
2169      * Check if onmousepress is enabled
2170      * @return true the action is enabled
2171      */
2172     public boolean getOnmousepressEnable() {
2173         if (mouseListener != null) {
2174             return mouseListener.getOnmousepressEnable();
2175         }
2176
2177         return false;
2178     }
2179
2180     /**
2181      * Enable onmouserelease
2182      * @param b, if true the action is enabled
2183      */
2184     public void setOnmousereleaseEnable(boolean b) {
2185         if (mouseListener != null) {
2186             mouseListener.setOnmousereleaseEnable(b);
2187         }
2188     }
2189
2190     /**
2191      * Check if onmouserelease is enabled
2192      * @return true the action is enabled
2193      */
2194     public boolean getOnmousereleaseEnable() {
2195         if (mouseListener != null) {
2196             return mouseListener.getOnmousereleaseEnable();
2197         }
2198
2199         return false;
2200     }
2201
2202     /**
2203      * Enable onmousewheel
2204      * @param b, if true the action is enabled
2205      */
2206     public void setOnmousewheelEnable(boolean b) {
2207         if (mouseListener != null) {
2208             mouseListener.setOnmousewheelEnable(b);
2209         }
2210     }
2211
2212     /**
2213      * Check if onmousewheel is enabled
2214      * @return true the action is enabled
2215      */
2216     public boolean getOnmousewheelEnable() {
2217         if (mouseListener != null) {
2218             return mouseListener.getOnmousewheelEnable();
2219         }
2220
2221         return false;
2222     }
2223
2224     /**
2225      * Enable onmousedrag
2226      * @param b, if true the action is enabled
2227      */
2228     public void setOnmousedragEnable(boolean b) {
2229         if (mouseListener != null) {
2230             mouseListener.setOnmousedragEnable(b);
2231         }
2232     }
2233
2234     /**
2235      * Check if onmousedrag is enabled
2236      * @return true the action is enabled
2237      */
2238     public boolean getOnmousedragEnable() {
2239         if (mouseListener != null) {
2240             return mouseListener.getOnmousedragEnable();
2241         }
2242
2243         return false;
2244     }
2245
2246     /**
2247      * Create a FocusListener on this component
2248      */
2249     private final void createFocusListener() throws UIWidgetException {
2250         if (focusListener == null) {
2251             focusListener = new UIFocusListener(this);
2252             focusListener.newInstance();
2253             focusListener.addListenerToComponent(getModifiableJComponent());
2254         }
2255     }
2256
2257     /**
2258      * Set onfocusgain action
2259      * @param command the command to execute
2260      */
2261     public void setOnfocusgain(String command) throws UIWidgetException {
2262         if (command != null && !command.isEmpty()) {
2263             createFocusListener();
2264             focusListener.setOnfocusgain(command);
2265         }
2266     }
2267
2268     /**
2269      * Set onfocusloss action
2270      * @param command the command to execute
2271      */
2272     public void setOnfocusloss(String command) throws UIWidgetException {
2273         if (command != null && !command.isEmpty()) {
2274             createFocusListener();
2275             focusListener.setOnfocusloss(command);
2276         }
2277     }
2278
2279     /**
2280      * Get onfocusgain action
2281      * @return the command to execute
2282      */
2283     public UICallback getOnfocusgain() {
2284         if (focusListener != null) {
2285             return focusListener.getOnfocusgain();
2286         }
2287
2288         return null;
2289     }
2290
2291     /**
2292      * Get onfocusloss action
2293      * @return the command to execute
2294      */
2295     public UICallback getOnfocusloss() {
2296         if (focusListener != null) {
2297             return focusListener.getOnfocusloss();
2298         }
2299
2300         return null;
2301     }
2302
2303     /**
2304      * Enable onfocusgain
2305      * @param b, if true the action is enabled
2306      */
2307     public void setOnfocusgainEnable(boolean b) {
2308         if (focusListener != null) {
2309             focusListener.setOnfocusgainEnable(b);
2310         }
2311     }
2312
2313     /**
2314      * Check if onfocusgain is enabled
2315      * @return true the action is enabled
2316      */
2317     public boolean getOnfocusgainEnable() {
2318         if (focusListener != null) {
2319             return focusListener.getOnfocusgainEnable();
2320         }
2321
2322         return false;
2323     }
2324
2325     /**
2326      * Enable onfocusloss
2327      * @param b, if true the action is enabled
2328      */
2329     public void setOnfocuslossEnable(boolean b) {
2330         if (focusListener != null) {
2331             focusListener.setOnfocuslossEnable(b);
2332         }
2333     }
2334
2335     /**
2336      * Check if onfocusloss is enabled
2337      * @return true the action is enabled
2338      */
2339     public boolean getOnfocuslossEnable() {
2340         if (focusListener != null) {
2341             return focusListener.getOnfocuslossEnable();
2342         }
2343
2344         return false;
2345     }
2346
2347     /**
2348      * Change the parent and update the dependencies
2349      * @param parent the parent
2350      */
2351     public void updateDependencies(UIComponent parent) throws UIWidgetException {
2352         setParent(parent);
2353     }
2354
2355     /**
2356      * Add a list of children
2357      * @param list the children
2358      */
2359     public void add(List<UIComponent> list) throws UIWidgetException {
2360         for (UIComponent uicomp : list) {
2361             add(uicomp);
2362         }
2363     }
2364
2365     /**
2366      * Add an UIComponent to the children list
2367      * @parent uicomp the child to add
2368      */
2369     public void add(final UIComponent uicomp) throws UIWidgetException {
2370         UIAccessTools.add(this, uicomp);
2371     }
2372
2373     /**
2374      * Add an UIListener
2375      * @parent uicomp the listener to add
2376      */
2377     public void addListener(final UIListener uicomp) throws UIWidgetException {
2378         uicomp.addListenerToComponent(getModifiableJComponent());
2379     }
2380
2381     /**
2382      * Add a popup menu
2383      * @param popup the popup menu
2384      */
2385     public void addPopupMenu(final JPopupMenu popup) {
2386         UIAccessTools.execOnEDT(new Runnable() {
2387             public void run() {
2388                 try {
2389                     getModifiableJComponent().setComponentPopupMenu(popup);
2390                 } catch (Exception e) {
2391
2392                 }
2393             }
2394         });
2395     }
2396
2397     /**
2398      * Set a property of this component
2399      * @param name the property name
2400      * @param value the property value
2401      */
2402     public void setProperty(final String name, final String value) throws UIWidgetException {
2403         try {
2404             if (thisOrComponent) {
2405                 setPropertyViaReflectionInThis(name, value);
2406             } else {
2407                 setPropertyViaReflectionInComponent(name, value);
2408             }
2409         } catch (Exception e) {
2410             if (thisOrComponent) {
2411                 setPropertyViaReflectionInComponent(name, value);
2412             } else {
2413                 setPropertyViaReflectionInThis(name, value);
2414             }
2415         }
2416     }
2417
2418     /**
2419      * Set a property (via relection) of this component
2420      * @param name the property name
2421      * @param value the property value
2422      */
2423     protected final void setPropertyViaReflectionInThis(final String name, final String value) throws UIWidgetException {
2424         UIAccessTools.setPropertyViaReflection(this, name, value);
2425     }
2426
2427     /**
2428      * Set a property (via relection) of the modifiable component
2429      * @param name the property name
2430      * @param value the property value
2431      */
2432     protected final void setPropertyViaReflectionInComponent(final String name, final String value) throws UIWidgetException {
2433         UIAccessTools.setPropertyViaReflection(getModifiableComponent(), name, value);
2434     }
2435
2436     /**
2437      * Set a property of this component
2438      * @param name the property name
2439      * @param value the property value
2440      */
2441     public void setProperty(final String name, final ScilabType value) throws UIWidgetException {
2442         try {
2443             if (thisOrComponent) {
2444                 setPropertyViaReflectionInThis(name, value);
2445             } else {
2446                 setPropertyViaReflectionInComponent(name, value);
2447             }
2448         } catch (Exception e) {
2449             if (thisOrComponent) {
2450                 setPropertyViaReflectionInComponent(name, value);
2451             } else {
2452                 setPropertyViaReflectionInThis(name, value);
2453             }
2454         }
2455     }
2456
2457     /**
2458      * Set a property of this component
2459      * @param name the property name
2460      * @param value the property value
2461      */
2462     public void setProperty(final List<String> names, final List<ScilabType> values) throws UIWidgetException {
2463         if (names != null && values != null) {
2464             final Object modifiableComponent = getModifiableComponent();
2465             final Class clazzThis = this.getClass();
2466             final Class clazzComp = modifiableComponent.getClass();
2467             final List<Object> objs = new ArrayList<Object>(names.size());
2468             final List<Method> methods = new ArrayList<Method>(names.size());
2469
2470             for (String name : names) {
2471                 String methodName = UIAccessTools.getSetterName(name);
2472                 Method method;
2473                 if (thisOrComponent) {
2474                     method = UIMethodFinder.findSetter(methodName, clazzThis);
2475                     if (method == null) {
2476                         method = UIMethodFinder.findSetter(methodName, clazzComp);
2477                         if (method == null) {
2478                             throw new UIWidgetException("No attribute " + name + " in " + clazzThis.getSimpleName());
2479                         }
2480                         objs.add(modifiableComponent);
2481                     } else {
2482                         objs.add(this);
2483                     }
2484                 } else {
2485                     method = UIMethodFinder.findSetter(methodName, clazzComp);
2486                     if (method == null) {
2487                         method = UIMethodFinder.findSetter(methodName, clazzThis);
2488                         if (method == null) {
2489                             throw new UIWidgetException("No attribute " + name + " in " + clazzThis.getSimpleName());
2490                         }
2491                         objs.add(this);
2492                     } else {
2493                         objs.add(modifiableComponent);
2494                     }
2495                 }
2496                 methods.add(method);
2497             }
2498
2499             UIAccessTools.execOnEDT(new Runnable() {
2500                 public void run() {
2501                     try {
2502                         for (int i = 0; i < objs.size(); i++) {
2503                             UIAccessTools.invokeSetter(methods.get(i), objs.get(i), values.get(i));
2504                         }
2505                     } catch (Exception e) {
2506                         System.err.println(e);
2507                     }
2508                 }
2509             });
2510         }
2511     }
2512
2513     /**
2514      * Set a property (via relection) of this component
2515      * @param name the property name
2516      * @param value the property value
2517      */
2518     protected final void setPropertyViaReflectionInThis(final String name, final ScilabType value) throws UIWidgetException {
2519         UIAccessTools.setPropertyViaReflection(this, name, value);
2520     }
2521
2522     /**
2523      * Set a property (via relection) of the modifiable component
2524      * @param name the property name
2525      * @param value the property value
2526      */
2527     protected final void setPropertyViaReflectionInComponent(final String name, final ScilabType value) throws UIWidgetException {
2528         UIAccessTools.setPropertyViaReflection(getModifiableComponent(), name, value);
2529     }
2530
2531     /**
2532      * Get the pairs property name -- method name
2533      * @return the pairs
2534      */
2535     public String[][] getPropertiesPairs() {
2536         Map<String, Method> map = new TreeMap<String, Method>();
2537         if (thisOrComponent) {
2538             UIMethodFinder.getSetter(getModifiableComponent().getClass(), map);
2539             UIMethodFinder.getSetter(this.getClass(), map);
2540         } else {
2541             UIMethodFinder.getSetter(this.getClass(), map);
2542             UIMethodFinder.getSetter(getModifiableComponent().getClass(), map);
2543         }
2544
2545         System.out.println(this.getClass() + ": (" + map.size() + " entries)");
2546         for (Map.Entry<String, Method> entry : map.entrySet()) {
2547             System.out.println(entry.getKey() + " --> " + entry.getValue());
2548         }
2549
2550         return null;
2551     }
2552
2553     /**
2554      * Get a property value
2555      * @param name the property name
2556      */
2557     public Object getProperty(final String name) throws UIWidgetException {
2558         try {
2559             if (thisOrComponent) {
2560                 return getPropertyViaReflectionInThis(name);
2561             } else {
2562                 return getPropertyViaReflectionInComponent(name);
2563             }
2564         } catch (Exception e) {
2565             if (thisOrComponent) {
2566                 return getPropertyViaReflectionInComponent(name);
2567             } else {
2568                 return getPropertyViaReflectionInThis(name);
2569             }
2570         }
2571     }
2572
2573     /**
2574      * Get a property value (via reflection)
2575      * @param name the property name
2576      */
2577     protected Object getPropertyViaReflectionInThis(final String name) throws UIWidgetException {
2578         return UIAccessTools.getPropertyViaReflection(this, name);
2579     }
2580
2581     /**
2582      * Get a property value (via reflection) in the modifiable component
2583      * @param name the property name
2584      */
2585     protected Object getPropertyViaReflectionInComponent(final String name) throws UIWidgetException {
2586         return UIAccessTools.getPropertyViaReflection(getModifiableComponent(), name);
2587     }
2588
2589     /**
2590      * Create a new instance
2591      * @param attributes the attributes
2592      */
2593     private void createNewInstance(final ConvertableMap attributes) throws UIWidgetException {
2594         Set<String> uselessAttrs = UIAccessTools.createNewInstance(this, attributes);
2595         if (uselessAttrs.contains("scrollable")) {
2596             boolean scrollable = (Boolean) attributes.get(boolean.class, "scrollable", false);
2597             if (scrollable && component instanceof JComponent) {
2598                 modifiableComponent = component;
2599                 if (SwingUtilities.isEventDispatchThread()) {
2600                     component = new MyScrollPane((JComponent) modifiableComponent);
2601                 } else {
2602                     try {
2603                         SwingUtilities.invokeAndWait(new Runnable() {
2604                             public void run() {
2605                                 try {
2606                                     component = new MyScrollPane((JComponent) modifiableComponent);
2607                                 } catch (Exception e) {
2608                                     System.err.println(e);
2609                                     e.printStackTrace();
2610                                 }
2611                             }
2612                         });
2613                     } catch (Exception e) {
2614                         System.err.println(e);
2615                         e.printStackTrace();
2616                     }
2617                 }
2618                 uselessAttrs.remove("scrollable");
2619             }
2620         }
2621
2622         if (uselessAttrs.contains("position")) {
2623             if (attributes instanceof StringMap) {
2624                 setNoLayoutConstraint(StringConverters.getObjectFromValue(Rectangle2D.Double.class, (String) attributes.get("position")));
2625             } else {
2626                 setNoLayoutConstraint(ScilabTypeConverters.getObjectFromValue(Rectangle2D.Double.class, (ScilabType) attributes.get("position")));
2627             }
2628             uselessAttrs.remove("position");
2629             if (uselessAttrs.contains("units")) {
2630                 if (attributes instanceof StringMap) {
2631                     setUnits(StringConverters.getObjectFromValue(String[].class, (String) attributes.get("units")));
2632                 } else {
2633                     setUnits(ScilabTypeConverters.getObjectFromValue(String[].class, (ScilabType) attributes.get("units")));
2634                 }
2635                 uselessAttrs.remove("units");
2636             }
2637         }
2638
2639         setAttributesAndStyle(attributes, uselessAttrs);
2640     }
2641
2642     /**
2643      * Set the attributes and style
2644      * @param attributes the attributes
2645      * @param uselessAttrs the useless attributes
2646      */
2647     private void setAttributesAndStyle(final ConvertableMap attributes, final Set<String> uselessAttrs) {
2648         if (!uselessAttrs.isEmpty()) {
2649             UIAccessTools.execOnEDT(new Runnable() {
2650                 public void run() {
2651                     if (attributes instanceof StringMap) {
2652                         for (String attr : uselessAttrs) {
2653                             try {
2654                                 setProperty(attr, (String) attributes.get(attr));
2655                             } catch (UIWidgetException e) { }
2656                         }
2657                     } else {
2658                         for (String attr : uselessAttrs) {
2659                             try {
2660                                 setProperty(attr, (ScilabType) attributes.get(attr));
2661                             } catch (UIWidgetException e) { }
2662                         }
2663                     }
2664
2665                     if (component instanceof JComponent && nolayoutconstraint == null) {
2666                         JComponent jc = (JComponent) component;
2667                         Dimension d = jc.getPreferredSize();
2668                         setNoLayoutConstraint(0, 0, (double) d.width, (double) d.height);
2669                         nolayoutconstraint.setUnit(0, 0, 0, 0);
2670                     }
2671                 }
2672             });
2673         } else {
2674             if (component instanceof JComponent && nolayoutconstraint == null) {
2675                 UIAccessTools.execOnEDT(new Runnable() {
2676                     public void run() {
2677                         JComponent jc = (JComponent) component;
2678                         Dimension d = jc.getPreferredSize();
2679                         setNoLayoutConstraint(0, 0, (double) d.width, (double) d.height);
2680                         nolayoutconstraint.setUnit(0, 0, 0, 0);
2681                     }
2682                 });
2683             }
2684         }
2685
2686         if (style != null) {
2687             Map<String, String> elementStyle = null;
2688             if (id != null) {
2689                 elementStyle = style.get("#" + id);
2690             }
2691
2692             if (elementStyle == null) {
2693                 String styleClass = (String) attributes.get(String.class, "class", null);
2694                 if (styleClass != null) {
2695                     elementStyle = style.get(styleClass);
2696                 }
2697             }
2698             if (elementStyle == null) {
2699                 elementStyle = style.get("." + this.getClass().getSimpleName());
2700             }
2701
2702             final Map<String, String> es = elementStyle;
2703             if (elementStyle != null) {
2704                 UIAccessTools.execOnEDT(new Runnable() {
2705                     public void run() {
2706                         try {
2707                             setUiStyle(new HashMap<String, String>(es));
2708                         } catch (UIWidgetException e) {
2709                             System.err.println(e);
2710                             e.printStackTrace();
2711                         }
2712                     }
2713                 });
2714             }
2715         }
2716
2717     }
2718
2719     /**
2720      * {@inheritdoc}
2721      */
2722     protected void finalize() throws Throwable {
2723         UserData.removeUIWidgetUserData(uid);
2724         super.finalize();
2725     }
2726
2727     /**
2728      * Convenient class to handle the case where the view dimensions are modified
2729      * and a setValue on a bar is made just after.
2730      * The ScrollBar model is warned of the view dimensions changes in a ComponentEvent
2731      */
2732     protected static class MyScrollPane extends JScrollPane {
2733
2734         protected int hvalue = -1;
2735         protected int vvalue = -1;
2736
2737         /**
2738          * {@inheritdoc}
2739          */
2740         public MyScrollPane() {
2741             super();
2742         }
2743
2744         /**
2745          * {@inheritdoc}
2746          */
2747         public MyScrollPane(Component c) {
2748             super(c);
2749         }
2750
2751         /**
2752          * {@inheritdoc}
2753          */
2754         public JScrollBar createVerticalScrollBar() {
2755             return new ScrollBar(JScrollBar.VERTICAL) {
2756                 public void setValues(int newValue, int newExtent, int newMin, int newMax) {
2757                     if (vvalue != -1) {
2758                         super.setValues(vvalue, newExtent, newMin, newMax);
2759                         vvalue = -1;
2760                     } else {
2761                         super.setValues(newValue, newExtent, newMin, newMax);
2762                     }
2763                 }
2764             };
2765         }
2766
2767         /**
2768          * {@inheritdoc}
2769          */
2770         public JScrollBar createHorizontalScrollBar() {
2771             return new ScrollBar(JScrollBar.HORIZONTAL) {
2772                 public void setValues(int newValue, int newExtent, int newMin, int newMax) {
2773                     if (hvalue != -1) {
2774                         super.setValues(hvalue, newExtent, newMin, newMax);
2775                         hvalue = -1;
2776                     } else {
2777                         super.setValues(newValue, newExtent, newMin, newMax);
2778                     }
2779                 }
2780             };
2781         }
2782     }
2783 }