Prefs: add a function preferences()
[scilab.git] / scilab / modules / preferences / src / java / org / scilab / modules / preferences / ComponentFactory.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.preferences;
14
15 import java.awt.Color;
16 import java.awt.Component;
17 import java.awt.Dimension;
18 import java.awt.FlowLayout;
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import javax.swing.BorderFactory;
25 import javax.swing.Box;
26 import javax.swing.JLabel;
27 import javax.swing.JPanel;
28 import javax.swing.border.Border;
29 import javax.swing.border.TitledBorder;
30
31 import org.w3c.dom.Node;
32
33 import org.scilab.modules.commons.ScilabCommonsUtils;
34 import org.scilab.modules.preferences.Component.Scroll;
35
36 /**
37  * Component factory
38  *
39  * @author Calixte DENIZET
40  *
41  */
42 class ComponentFactory {
43
44     private static final String X_PACKAGE = "org.scilab.modules.preferences.Component.";
45     private static final int SPACE = 5;
46     private static final Map<String, Constructor<Component>> cache = new HashMap<String, Constructor<Component>>();
47     private static final Map<String, MyAction> actions = new HashMap<String, MyAction>();
48
49     static {
50         actions.put("Scroll", new MyAction() {
51             public Component getComponent(final Node node) {
52                 return new Scroll(node, new JPanel());
53             }
54         });
55         actions.put("#text", new MyAction() {
56             public Component getComponent(final Node node) {
57                 return new JLabel(node.getNodeValue());
58             }
59         });
60         actions.put("VSpace", new MyAction() {
61             public Component getComponent(final Node node) {
62                 return Box.createVerticalStrut(XConfigManager.getInt(node, "height", SPACE));
63             }
64         });
65         actions.put("HSpace", new MyAction() {
66             public Component getComponent(final Node node) {
67                 return Box.createHorizontalStrut(XConfigManager.getInt(node, "height", SPACE));
68             }
69         });
70         actions.put("Glue", new MyAction() {
71             public Component getComponent(final Node node) {
72                 return Box.createGlue();
73             }
74         });
75     }
76
77     public static final Component getComponent(final Node node) {
78         Component component;
79         String tag = node.getNodeName();
80         MyAction action = actions.get(tag);
81         if (action != null) {
82             component = action.getComponent(node);
83             return component;
84         }
85
86         Constructor constructor = cache.get(tag);
87         if (constructor == null) {
88             if ("PreviewCode".equals(tag)) {
89                 ScilabCommonsUtils.loadOnUse("SciNotes");
90             }
91
92             Class<Component> componentClass;
93             try {
94                 componentClass = (Class<Component>) Class.forName(X_PACKAGE + tag);
95             } catch (ClassNotFoundException e) {
96                 System.err.println(e);
97                 return new XStub(node, "ClassNotFoundException");
98             }
99
100             try {
101                 // First with a Node as argument
102                 Class[] parameter = new Class[] {Node.class};
103                 constructor = componentClass.getConstructor(parameter);
104             } catch (NoSuchMethodException e) {
105                 System.err.println("NoSuchMethodException:" + e);
106                 return new XStub(node, "NoSuchMethodException");
107             } catch (SecurityException e) {
108                 // Declare failure due to constructor rights (it must be public)
109                 System.err.println("SecurityException:" + e);
110                 return new XStub(node, "SecurityException");
111             }
112
113             cache.put(tag, constructor);
114         }
115
116         try {
117             component = (Component) constructor.newInstance(new Object[] {node});
118         } catch (InstantiationException e) {
119             System.err.println("InstantiationException:" + e);
120             return new XStub(node, "InstantiationException");
121         } catch (IllegalAccessException e) {
122             System.err.println("IllegalAccessException:" + e);
123             return new XStub(node, "IllegalAccessException");
124         } catch (IllegalArgumentException e) {
125             System.err.println("IllegalArgumentException:" + e);
126             return new XStub(node, "IllegalArgumentException");
127         } catch (InvocationTargetException e) {
128             System.err.println("InvocationTargetException:" + e.getTargetException());
129             e.getTargetException().printStackTrace();
130             return new XStub(node, "InvocationTargetException");
131         }
132
133         return component;
134     }
135
136     private static interface MyAction {
137         Component getComponent(final Node node);
138     }
139
140     /**
141      * Graphical indication of what goes wrong in buildPeerFor(node).
142      */
143     private static class XStub extends JPanel {
144
145         /**
146          * Serialization id.
147          */
148         private static final long serialVersionUID = -6540983459186007758L;
149
150         /**
151          * Default height.
152          */
153         private static final int D_HEIGHT = 50;
154
155         /**
156          * Default width.
157          */
158         private static final int D_WIDTH = 100;
159
160         /** Constructor.
161          * @param tag : class name source of the error
162          * @param cause : description of the error
163          *
164          */
165         public XStub(final Node node, final String cause) {
166             super();
167             Border red = BorderFactory.createLineBorder(Color.RED);
168             TitledBorder title = BorderFactory.createTitledBorder(red, node.getNodeName() + " " + cause);
169             Dimension dimension = new Dimension(D_WIDTH, D_HEIGHT);
170             setPreferredSize(dimension);
171             setOpaque(false);
172             XConfigManager.setDimension(this, node);
173
174             title.setTitleColor(Color.RED);
175             setBorder(title);
176             setLayout(new FlowLayout());
177         }
178
179         /**
180          * Output method.
181          * @return the string representation
182          */
183         public String toString() {
184             return "STUB";
185         }
186     }
187 }