Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.swing / org.gvsig.scripting.swing.impl / src / main / java / org / gvsig / scripting / swing / impl / DefaultJScriptingBrowser.java @ 457

History | View | Annotate | Download (11.8 KB)

1
package org.gvsig.scripting.swing.impl;
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.io.File;
12
import java.util.List;
13

    
14
import javax.swing.Icon;
15
import javax.swing.JComponent;
16
import javax.swing.JLabel;
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
import org.gvsig.scripting.swing.api.JScriptingBrowser;
33
import org.gvsig.scripting.swing.api.ScriptingUIManager;
34
import org.slf4j.LoggerFactory;
35
import org.slf4j.Logger;
36

    
37
public class DefaultJScriptingBrowser extends JScriptingBrowser {
38

    
39
        private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingBrowser.class);
40
        
41
        public static final int DEFAULT_ACTION = 1;
42
        public static final int SELECTION_ACTION = 2;
43
        public static final int DROPDOWN_ACTION = 3;
44
        /**
45
         * 
46
         */
47
        private static final long serialVersionUID = 1L;
48

    
49
        protected ScriptingUIManager uimanager;
50
        protected ScriptingManager manager;
51
        protected DefaultMutableTreeNode rootNode;
52
        protected DefaultTreeModel treeModel;
53
        protected JTree tree;
54
        protected ScriptingFolder root;
55
        protected ActionListener defaultActionlistener = null;
56
        protected ActionListener selectionActionlistener = null;
57
        protected ActionListener dropDownActionlistener = null;
58
        private final boolean foldersOnly;
59

    
60
        public static class BrowserActionEvent extends ActionEvent {
61
                /**
62
                 * 
63
                 */
64
                private static final long serialVersionUID = -1474410768278633364L;
65
                private ScriptingBaseScript script = null;
66

    
67
                public BrowserActionEvent(Object source, int id, String command,
68
                                ScriptingBaseScript script) {
69
                        super(source, id, command);
70
                        this.script = script;
71
                }
72

    
73
                public ScriptingBaseScript getScript() {
74
                        return this.script;
75
                }
76
        }
77

    
78
        public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
79
                        ScriptingFolder root) {
80
                this(uimanager, root, false);
81
        }
82

    
83
        public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
84
                        ScriptingFolder root, boolean foldersOnly) {
85
                super(new GridLayout(1, 2));
86
                this.foldersOnly = foldersOnly;
87
                this.uimanager = uimanager;
88
                this.manager = uimanager.getManager();
89
                this.root = root;
90
                this.makeUI();
91
        }
92

    
93
        @Override
94
        public ScriptingManager getManager() {
95
                return this.manager;
96
        }
97

    
98
        @Override
99
        public ScriptingFolder getRoot() {
100
                return this.root;
101
        }
102

    
103
        public void addDefaultActionListener(ActionListener actionlistener) {
104
                this.defaultActionlistener = actionlistener;
105
        }
106

    
107
        public void addSelectionActionListener(ActionListener actionlistener) {
108
                this.selectionActionlistener = actionlistener;
109
        }
110

    
111
        public void addDropDownActionListener(ActionListener actionlistener) {
112
                this.dropDownActionlistener = actionlistener;
113
        }
114

    
115
        private void makeUI() {
116
                // Creamos el nodo raíz
117
                String[] iconNames = root.getIconNames();
118
                rootNode = new DefaultMutableTreeNode(new IconData(
119
                                this.uimanager.getIcon(iconNames[0]),
120
                                this.uimanager.getIcon(iconNames[1]), root));
121

    
122
                // Lo asignamos al modelo del árbol e iniciamos el árbol con ese
123
                // modelo
124
                treeModel = new DefaultTreeModel(rootNode);
125
                tree = new JTree(treeModel);
126

    
127
                // Cargamos la información inicial del árbol
128
                this.initializeTree();
129

    
130
                // Para asignar iconos especiales según el tipo de objeto
131
                TreeCellRenderer renderer = new IconCellRenderer();
132
                tree.setCellRenderer(renderer);
133

    
134
                // Para marcar que no son editables sus propiedades o nodos
135
                tree.setEditable(false);
136

    
137
                // Determina que sólo se puede seleccionar una linea
138
                tree.getSelectionModel().setSelectionMode(
139
                                TreeSelectionModel.SINGLE_TREE_SELECTION);
140

    
141
                // Añadimos un listener que se ejecutará cuando seleccionemos un
142
                // elemento del árbol
143
                tree.addTreeSelectionListener(new TreeSelectionListener() {
144
                        public void valueChanged(TreeSelectionEvent e) {
145
                                loadChildrenLazily(e.getPath());
146
                                if (selectionActionlistener != null) {
147
                                        JComponent tree = (JComponent) e.getSource();
148
                                        ActionEvent event = new BrowserActionEvent(
149
                                                        tree.getParent(), SELECTION_ACTION, "select", null);
150
                                        selectionActionlistener.actionPerformed(event);
151
                                }
152
                        }
153
                });
154
                tree.addMouseListener(new MouseListener() {
155
                        public void mouseClicked(MouseEvent arg0) {
156
                                if (arg0.getClickCount() == 2) {
157
                                        JTree tree = (JTree) arg0.getSource();
158

    
159
                                        if (!tree.isSelectionEmpty()) {
160
                                                startingScript(tree.getSelectionPath());
161
                                        }
162

    
163
                                }
164
                        }
165

    
166
                        public void mouseEntered(MouseEvent arg0) {
167
                        }
168

    
169
                        public void mouseExited(MouseEvent arg0) {
170
                        }
171

    
172
                        public void mousePressed(MouseEvent arg0) {
173
                        }
174

    
175
                        public void mouseReleased(MouseEvent arg0) {
176
                        }
177
                });
178

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

    
183
                // Añadimos el Scroll
184
                JScrollPane scrollPane = new JScrollPane(tree);
185
                add(scrollPane);
186

    
187
        }
188

    
189
        @Override
190
        public ScriptingUnit getSelectedNode() {
191
                DefaultMutableTreeNode node;
192
                if (tree.getSelectionPath() != null) {
193
                        node = (DefaultMutableTreeNode) tree.getSelectionPath()
194
                                        .getLastPathComponent();
195
                } else {
196
                        node = this.rootNode;
197
                }
198
                return ((ScriptingUnit) ((IconData) (node.getUserObject())).m_data);
199
        }
200

    
201
        private void startingScript(TreePath path) {
202
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
203
                                .getLastPathComponent();
204
                ScriptingUnit unit = ((ScriptingUnit) ((IconData) (node.getUserObject())).m_data);
205

    
206
                if (unit instanceof ScriptingBaseScript) {
207
                        if (this.defaultActionlistener != null) {
208
                                ActionEvent event = new BrowserActionEvent(this,
209
                                                DEFAULT_ACTION, "default", (ScriptingBaseScript) unit);
210
                                this.defaultActionlistener.actionPerformed(event);
211
                        }
212
                }
213
        }
214

    
215
        /**
216
         * Función para el despliegue de los hijos de un nodo bajo demanda.
217
         **/
218
        private void loadChildrenLazily(TreePath path) {
219
                // Mediante el path recuperamos el último nodo, del que
220
                // queremos obtener sus hijos dinámicamente
221
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
222
                                .getLastPathComponent();
223
                ScriptingUnit unit = ((ScriptingUnit) ((IconData) (node.getUserObject())).m_data);
224

    
225
                List<ScriptingUnit> files = null;
226

    
227
                // Si es un ScriptingFolder y no hemos obtenido previamente sus hijos
228
                if (unit instanceof ScriptingFolder && node.getChildCount() == 0) {
229
                        // Obtenemos los hijos
230
                        files = ((ScriptingFolder) unit).getUnits();
231

    
232
                        ScriptingUnit subunit = null;
233

    
234
                        for (int i = 0; i < files.size(); i++) {
235
                                subunit = files.get(i);
236
                                if ((this.foldersOnly && subunit instanceof ScriptingFolder)
237
                                                || !this.foldersOnly) {
238
                                        // Obtenemos los iconos específicos para ese tipo de objeto
239
                                        String[] iconNames = subunit.getIconNames();
240

    
241
                                        // Creamos el objeto IconData, con la información
242
                                        // del objeto y de hasta 2 iconos asociados
243
                                        IconData data = new IconData(
244
                                                        this.uimanager.getIcon(iconNames[0]),
245
                                                        this.uimanager.getIcon(iconNames[1]), subunit);
246

    
247
                                        // Insertamos en el árbol el nuevo objeto creado
248
                                        addObject(node, data);
249
                                }
250
                        }
251
                }
252

    
253
        }
254

    
255
        /**
256
         * Función para la inicialización de los datos del árbol.
257
         **/
258
        private void initializeTree() {
259

    
260
                ScriptingUnit unit = null;
261

    
262
                List<ScriptingUnit> files = this.root.getUnits();
263

    
264
                for (int i = 0; i < files.size(); i++) {
265
                        unit = files.get(i);
266
                        String fname_unit = "(unknow)";
267
                        try {
268
                                fname_unit = unit.getFile().getAbsolutePath();
269
                                if ((this.foldersOnly && unit instanceof ScriptingFolder)
270
                                                || !this.foldersOnly) {
271
                                        String[] iconNames = unit.getIconNames();
272

    
273
                                        IconData data = new IconData(
274
                                                        uimanager.getIcon(iconNames[0]),
275
                                                        uimanager.getIcon(iconNames[1]), unit);
276
                                        // Insertamos en el nodo raiz del arbol
277
                                        this.addObject(this.rootNode, data);
278
                                }
279
                        } catch (Exception ex) {
280
                                logger.warn("Can't add script unit '"+fname_unit+"' to the tree.", ex);
281
                        }
282
                }
283

    
284
        }
285

    
286
        /**
287
         * Función para añadir un hijo al nodo actual.
288
         **/
289
        // private DefaultMutableTreeNode addObject(Object child) {
290
        // DefaultMutableTreeNode parentNode = rootNode;
291
        // return addObject(parentNode, child, true);
292
        // }
293

    
294
        private DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
295
                        Object child) {
296
                return addObject(parent, child, false);
297
        }
298

    
299
        private DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
300
                        Object child, boolean shouldBeVisible) {
301
                DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
302

    
303
                // Si no especificamos padre, lo colgará del raíz
304
                if (parent == null) {
305
                        parent = rootNode;
306
                }
307

    
308
                // Insertamos el nuevo nodo en el modelo del árbol
309
                treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
310

    
311
                // Para que el usuario pueda ver el nuevo nodo
312
                if (shouldBeVisible) {
313
                        tree.scrollPathToVisible(new TreePath(childNode.getPath()));
314
                }
315

    
316
                return childNode;
317
        }
318

    
319
        /**
320
         * Clase IconData permite asociar hasta dos iconos (para cuando está
321
         * expandido y cuando no) a un objeto del árbol
322
         **/
323
        static private class IconData {
324
                protected Icon m_icon;
325
                protected Icon m_expandedIcon;
326
                protected Object m_data;
327

    
328
                public IconData(Icon icon, Icon expandedIcon, Object data) {
329
                        m_icon = icon;
330
                        m_expandedIcon = expandedIcon;
331
                        m_data = data;
332
                }
333

    
334
                public Icon getIcon() {
335
                        return m_icon;
336
                }
337

    
338
                public Icon getExpandedIcon() {
339
                        return m_expandedIcon != null ? m_expandedIcon : m_icon;
340
                }
341

    
342
                @Override
343
                public String toString() {
344
                        return m_data.toString();
345
                }
346
        }
347

    
348
        private class IconCellRenderer extends JLabel implements TreeCellRenderer {
349

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

    
360
                protected boolean m_selected;
361

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

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

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

    
383
                        if (obj instanceof Boolean)
384
                                setText(uimanager.getTranslation("Retrieving_data"));
385

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

    
395
                        setFont(tree.getFont());
396
                        setForeground(sel ? m_textSelectionColor : m_textNonSelectionColor);
397
                        setBackground(sel ? m_bkSelectionColor : m_bkNonSelectionColor);
398
                        m_selected = sel;
399
                        return this;
400
                }
401

    
402
                @Override
403
                public void paintComponent(Graphics g) {
404
                        Color bColor = getBackground();
405
                        Icon icon = getIcon();
406

    
407
                        g.setColor(bColor);
408
                        int offset = 0;
409
                        if (icon != null && getText() != null)
410
                                offset = (icon.getIconWidth() + getIconTextGap());
411
                        g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
412

    
413
                        if (m_selected) {
414
                                g.setColor(m_borderSelectionColor);
415
                                g.drawRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
416
                        }
417
                        super.paintComponent(g);
418
                }
419
        }
420

    
421
}