Statistics
| Revision:

gvsig-scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.api / src / main / java / org / gvsig / scripting / swing / JScriptingBrowser.java @ 36

History | View | Annotate | Download (11.3 KB)

1
package org.gvsig.scripting.swing;
2

    
3
import java.awt.Color;
4
import java.awt.Component;
5
import java.awt.Graphics;
6
import java.awt.GridLayout;
7
import java.awt.event.ActionEvent;
8
import java.awt.event.ActionListener;
9
import java.awt.event.MouseEvent;
10
import java.awt.event.MouseListener;
11
import java.util.List;
12

    
13
import javax.swing.Icon;
14
import javax.swing.JComponent;
15
import javax.swing.JLabel;
16
import javax.swing.JPanel;
17
import javax.swing.JScrollPane;
18
import javax.swing.JTree;
19
import javax.swing.UIManager;
20
import javax.swing.event.TreeSelectionEvent;
21
import javax.swing.event.TreeSelectionListener;
22
import javax.swing.tree.DefaultMutableTreeNode;
23
import javax.swing.tree.DefaultTreeModel;
24
import javax.swing.tree.TreeCellRenderer;
25
import javax.swing.tree.TreePath;
26
import javax.swing.tree.TreeSelectionModel;
27

    
28
import org.gvsig.scripting.ScriptingBaseScript;
29
import org.gvsig.scripting.ScriptingFolder;
30
import org.gvsig.scripting.ScriptingManager;
31
import org.gvsig.scripting.ScriptingUnit;
32

    
33

    
34
public class JScriptingBrowser extends JPanel{
35

    
36
        
37
        public static final int DEFAULT_ACTION = 1;
38
        public static final int SELECTION_ACTION = 2;
39
        public static final int DROPDOWN_ACTION = 3;
40
        /**
41
         * 
42
         */
43
        private static final long serialVersionUID = 1L;
44

    
45
        protected ScriptingManager manager;
46
        protected DefaultMutableTreeNode rootNode;
47
        protected DefaultTreeModel treeModel;
48
        protected JTree tree;
49
        protected ScriptingFolder root;
50
        protected ActionListener defaultActionlistener = null;
51
        protected ActionListener selectionActionlistener = null;
52
        protected ActionListener dropDownActionlistener = null;
53
        private boolean foldersOnly;
54

    
55

    
56
        public static class BrowserActionEvent extends ActionEvent{
57
                /**
58
                 * 
59
                 */
60
                private static final long serialVersionUID = -1474410768278633364L;
61
                private ScriptingBaseScript script= null;
62
                
63
                public BrowserActionEvent(Object source, int id, String command, ScriptingBaseScript script) {
64
                        super(source,id,command);
65
                        this.script = script;
66
                }
67
                
68
                public ScriptingBaseScript getScript(){
69
                        return this.script;
70
                }
71
        }
72

    
73
        
74
        public JScriptingBrowser(ScriptingManager manager,ScriptingFolder root) {
75
                this(manager,root,false);
76
        }
77
        public JScriptingBrowser(ScriptingManager manager,ScriptingFolder root, boolean foldersOnly) {
78
                super(new GridLayout(1,2));
79
                this.foldersOnly = foldersOnly;
80
                this.manager = manager;
81
                this.root = root;
82
                this.makeUI();        
83
        }
84
        
85
        public ScriptingManager getManager(){
86
                return this.manager;
87
        }
88
        
89
        public ScriptingFolder getRoot(){
90
                return this.root;
91
        }
92
        
93
        public void addDefaultActionListener(ActionListener actionlistener) {
94
                this.defaultActionlistener = actionlistener;  
95
        }
96
        
97
        public void addSelectionActionListener(ActionListener actionlistener) {
98
                this.selectionActionlistener = actionlistener;  
99
        }
100
        
101
        public void addDropDownActionListener(ActionListener actionlistener) {
102
                this.dropDownActionlistener = actionlistener;  
103
        }
104
                
105
        private void makeUI(){
106
                //Creamos el nodo raíz
107
                String[] iconNames = root.getIconNames();
108
                rootNode = new DefaultMutableTreeNode(new IconData(
109
                                this.manager.getIcon(iconNames[0]),this.manager.getIcon(iconNames[1]), root)
110
                );
111

    
112
                // Lo asignamos al modelo del árbol e iniciamos el árbol con ese modelo
113
                treeModel = new DefaultTreeModel(rootNode);
114
                tree = new JTree(treeModel);
115

    
116
                // Cargamos la información inicial del árbol
117
                this.initializeTree();
118

    
119
                // Para asignar iconos especiales según el tipo de objeto
120
                TreeCellRenderer renderer = new IconCellRenderer();
121
                tree.setCellRenderer(renderer);
122

    
123
                //Para marcar que no son editables sus propiedades o nodos
124
                tree.setEditable(false);
125

    
126
                //Determina que sólo se puede seleccionar una linea
127
                tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
128

    
129
                // Añadimos un listener que se ejecutará cuando seleccionemos un elemento del árbol
130
                tree.addTreeSelectionListener(new TreeSelectionListener() {
131
                        public void valueChanged(TreeSelectionEvent e) {        
132
                                loadChildrenLazily(e.getPath());
133
                                if(selectionActionlistener!=null){
134
                                        JComponent tree = (JComponent) e.getSource();
135
                                        ActionEvent event = new BrowserActionEvent(tree.getParent(),SELECTION_ACTION,"select",null);
136
                                        selectionActionlistener.actionPerformed(event);
137
                                }
138
                        }
139
                });
140
                tree.addMouseListener(new MouseListener() {
141
                        public void mouseClicked(MouseEvent arg0) {
142
                                if (arg0.getClickCount() == 2) {
143
                                        JTree tree = (JTree) arg0.getSource();
144
                                        
145
                                                if(!tree.isSelectionEmpty()){
146
                                                        startingScript(tree.getSelectionPath());
147
                                                }
148
                                        
149
                                }
150
                        }
151

    
152
                        public void mouseEntered(MouseEvent arg0) {
153
                        }
154

    
155
                        public void mouseExited(MouseEvent arg0) {
156
                        }
157

    
158
                        public void mousePressed(MouseEvent arg0) {
159
                        }
160

    
161
                        public void mouseReleased(MouseEvent arg0) {
162
                        }
163
                });
164

    
165
                //Indica si el nodo raíz actúa como un nodo más o queda desplegado de manera fija
166
                tree.setShowsRootHandles(true);
167

    
168
                //Añadimos el Scroll
169
                JScrollPane scrollPane = new JScrollPane(tree);
170
                add(scrollPane);
171
                        
172
        }
173
        
174
        public ScriptingUnit getSelectedNode(){
175
                DefaultMutableTreeNode node;
176
                if(tree.getSelectionPath()!=null){
177
                        node = (DefaultMutableTreeNode)tree.getSelectionPath().getLastPathComponent();
178
                }else{
179
                        node = this.rootNode;
180
                }
181
                return ((ScriptingUnit)((IconData)(node.getUserObject())).m_data);
182
        }
183
        
184
        private void startingScript(TreePath path){
185
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
186
                ScriptingUnit unit = ((ScriptingUnit)((IconData)(node.getUserObject())).m_data);
187
                
188
                if (unit instanceof ScriptingBaseScript){
189
                        if(this.defaultActionlistener!=null){
190
                                ActionEvent event = new BrowserActionEvent(this,DEFAULT_ACTION,"default", (ScriptingBaseScript) unit);
191
                                this.defaultActionlistener.actionPerformed(event);
192
                        }
193
                }
194
        }
195
        
196

    
197
        /** 
198
         * Función para el despliegue de los hijos de un nodo bajo demanda. 
199
         **/ 
200
        private void loadChildrenLazily(TreePath path){
201
                // Mediante el path recuperamos el último nodo, del que
202
                // queremos obtener sus hijos dinámicamente
203
                DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
204
                ScriptingUnit unit = ((ScriptingUnit)((IconData)(node.getUserObject())).m_data);
205
                
206
                List files = null;
207
                
208
                // Si es un ScriptingFolder y no hemos obtenido previamente sus hijos
209
                if (unit instanceof ScriptingFolder && node.getChildCount() == 0){
210
                        // Obtenemos los hijos
211
                        files = ((ScriptingFolder)unit).getUnits();
212

    
213
                        ScriptingUnit subunit = null;
214

    
215
                        for (int i = 0; i < files.size(); i++){
216
                                subunit = (ScriptingUnit) files.get(i);
217
                                if((this.foldersOnly && subunit instanceof ScriptingFolder) || !this.foldersOnly){
218
                                        // Obtenemos los iconos específicos para ese tipo de objeto
219
                                        String[] iconNames = subunit.getIconNames();
220
                                        
221
                                        // Creamos el objeto IconData, con la información
222
                                        // del objeto y de hasta 2 iconos asociados
223
                                        IconData data = new IconData(
224
                                                        this.manager.getIcon(iconNames[0]),
225
                                                        this.manager.getIcon(iconNames[1]),
226
                                                        subunit
227
                                        );
228
        
229
                                        // Insertamos en el árbol el nuevo objeto creado
230
                                        addObject(node,data);
231
                                }
232
                        }
233
                }
234
                
235
        }
236

    
237
        /** 
238
         * Función para la inicialización de los datos del árbol.
239
         **/
240
        private void initializeTree(){
241

    
242
                ScriptingUnit unit = null;
243

    
244
                List files = this.root.getUnits();
245

    
246
                for (int i = 0; i < files.size(); i++){
247
                        unit = (ScriptingUnit) files.get(i);
248
                        if((this.foldersOnly && unit instanceof ScriptingFolder) || !this.foldersOnly){
249
                        String[] iconNames = unit.getIconNames();
250

    
251
                        IconData data = new IconData(
252
                                        manager.getIcon(iconNames[0]),
253
                                        manager.getIcon(iconNames[1]),
254
                                        unit
255
                        );
256

    
257
                        // Insertamos en el nodo raíz del árbol
258
                        this.addObject(this.rootNode,data);
259
                        }
260
                }
261

    
262
        }
263

    
264

    
265
        /** 
266
         * Función para añadir un hijo al nodo actual. 
267
         **/
268
//        private DefaultMutableTreeNode addObject(Object child) {
269
//                DefaultMutableTreeNode parentNode = rootNode;
270
//                return addObject(parentNode, child, true);
271
//        }
272

    
273
        private DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
274
                        Object child) {
275
                return addObject(parent, child, false);
276
        }
277

    
278
        private DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
279
                        Object child, 
280
                        boolean shouldBeVisible) {
281
                DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
282
                
283
                // Si no especificamos padre, lo colgará del raíz
284
                if (parent == null) {
285
                        parent = rootNode;
286
                }
287
                
288
                // Insertamos el nuevo nodo en el modelo del árbol
289
                treeModel.insertNodeInto(childNode, parent, 
290
                                parent.getChildCount());
291

    
292
                // Para que el usuario pueda ver el nuevo nodo
293
                if (shouldBeVisible) {
294
                        tree.scrollPathToVisible(new TreePath(childNode.getPath()));
295
                }
296

    
297
                return childNode;
298
        }
299

    
300
        /**
301
         * Clase IconData permite asociar hasta dos iconos (para 
302
         * cuando está expandido y cuando no) a un objeto del árbol
303
         **/
304
        static private class IconData
305
        {
306
                protected Icon   m_icon;
307
                protected Icon   m_expandedIcon;
308
                protected Object m_data;
309

    
310
                public IconData(Icon icon, Object data)
311
                {
312
                        m_icon = icon;
313
                        m_expandedIcon = null;
314
                        m_data = data;
315
                }
316

    
317
                public IconData(Icon icon, Icon expandedIcon, Object data)
318
                {
319
                        m_icon = icon;
320
                        m_expandedIcon = expandedIcon;
321
                        m_data = data;
322
                }
323

    
324
                public Icon getIcon() 
325
                { 
326
                        return m_icon;
327
                }
328

    
329
                public Icon getExpandedIcon() 
330
                { 
331
                        return m_expandedIcon!=null ? m_expandedIcon : m_icon;
332
                }
333

    
334
                public Object getObject() 
335
                { 
336
                        return m_data;
337
                }
338

    
339
                public String toString() 
340
                { 
341
                        return m_data.toString();
342
                }
343
        }
344

    
345
        private class IconCellRenderer extends JLabel implements TreeCellRenderer {
346

    
347
                /**
348
                 * 
349
                 */
350
                private static final long serialVersionUID = 1L;
351
                protected Color m_textSelectionColor;
352
                protected Color m_textNonSelectionColor;
353
                protected Color m_bkSelectionColor;
354
                protected Color m_bkNonSelectionColor;
355
                protected Color m_borderSelectionColor;
356

    
357
                protected boolean m_selected;
358

    
359
                public IconCellRenderer()
360
                {
361
                        super();
362
                        m_textSelectionColor = UIManager.getColor(
363
                        "Tree.selectionForeground");
364
                        m_textNonSelectionColor = UIManager.getColor(
365
                        "Tree.textForeground");
366
                        m_bkSelectionColor = UIManager.getColor(
367
                        "Tree.selectionBackground");
368
                        m_bkNonSelectionColor = UIManager.getColor(
369
                        "Tree.textBackground");
370
                        m_borderSelectionColor = UIManager.getColor(
371
                        "Tree.selectionBorderColor");
372
                        setOpaque(false);
373
                }
374

    
375
                public Component getTreeCellRendererComponent(JTree tree, 
376
                                Object value, boolean sel, boolean expanded, boolean leaf, 
377
                                int row, boolean hasFocus) 
378

    
379
                {
380
                        DefaultMutableTreeNode node = 
381
                                (DefaultMutableTreeNode)value;
382
                        Object obj = node.getUserObject();
383
                        setText(obj.toString());
384

    
385
                        if (obj instanceof Boolean)
386
                                setText("Retrieving data...");
387

    
388
                        if (obj instanceof IconData)
389
                        {
390
                                IconData idata = (IconData)obj;
391
                                if (expanded)
392
                                        setIcon(idata.getExpandedIcon());
393
                                else
394
                                        setIcon(idata.getIcon());
395
                        }
396
                        else
397
                                setIcon(null);
398

    
399
                        setFont(tree.getFont());
400
                        setForeground(sel ? m_textSelectionColor : 
401
                                m_textNonSelectionColor);
402
                        setBackground(sel ? m_bkSelectionColor : 
403
                                m_bkNonSelectionColor);
404
                        m_selected = sel;
405
                        return this;
406
                }
407

    
408
                public void paintComponent(Graphics g) 
409
                {
410
                        Color bColor = getBackground();
411
                        Icon icon = getIcon();
412

    
413
                        g.setColor(bColor);
414
                        int offset = 0;
415
                        if(icon != null && getText() != null) 
416
                                offset = (icon.getIconWidth() + getIconTextGap());
417
                        g.fillRect(offset, 0, getWidth() - 1 - offset,
418
                                        getHeight() - 1);
419

    
420
                        if (m_selected) 
421
                        {
422
                                g.setColor(m_borderSelectionColor);
423
                                g.drawRect(offset, 0, getWidth()-1-offset, getHeight()-1);
424
                        }
425
                        super.paintComponent(g);
426
                }
427
        }
428

    
429
}