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 @ 1200

History | View | Annotate | Download (16.3 KB)

1 165 jobacas
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 630 jjdelcerro
import java.awt.event.KeyEvent;
10 165 jobacas
import java.awt.event.MouseEvent;
11
import java.awt.event.MouseListener;
12 1200 jjdelcerro
import java.net.URL;
13 468 jjdelcerro
import java.util.ArrayList;
14 952 jjdelcerro
import java.util.Enumeration;
15 468 jjdelcerro
import java.util.HashMap;
16
import java.util.Iterator;
17 165 jobacas
import java.util.List;
18 468 jjdelcerro
import java.util.Map;
19 630 jjdelcerro
import javax.swing.AbstractAction;
20 165 jobacas
21
import javax.swing.Icon;
22 468 jjdelcerro
import javax.swing.ImageIcon;
23 165 jobacas
import javax.swing.JComponent;
24
import javax.swing.JLabel;
25 639 jjdelcerro
import javax.swing.JPanel;
26 165 jobacas
import javax.swing.JScrollPane;
27
import javax.swing.JTree;
28 630 jjdelcerro
import javax.swing.KeyStroke;
29 165 jobacas
import javax.swing.UIManager;
30 468 jjdelcerro
import javax.swing.event.TreeModelEvent;
31
import javax.swing.event.TreeModelListener;
32 165 jobacas
import javax.swing.event.TreeSelectionEvent;
33
import javax.swing.event.TreeSelectionListener;
34
import javax.swing.tree.TreeCellRenderer;
35 468 jjdelcerro
import javax.swing.tree.TreeModel;
36 165 jobacas
import javax.swing.tree.TreePath;
37
import javax.swing.tree.TreeSelectionModel;
38 1200 jjdelcerro
import org.apache.commons.io.FilenameUtils;
39
import org.gvsig.scripting.ScriptingExternalFile;
40 165 jobacas
41
import org.gvsig.scripting.ScriptingFolder;
42
import org.gvsig.scripting.ScriptingManager;
43
import org.gvsig.scripting.ScriptingUnit;
44
import org.gvsig.scripting.swing.api.JScriptingBrowser;
45 953 jjdelcerro
import static org.gvsig.scripting.swing.api.JScriptingBrowser.DEFAULT_ACTION;
46
import static org.gvsig.scripting.swing.api.JScriptingBrowser.SELECTION_ACTION;
47 165 jobacas
import org.gvsig.scripting.swing.api.ScriptingUIManager;
48 953 jjdelcerro
import org.gvsig.tools.swing.api.ActionListenerSupport;
49
import org.gvsig.tools.swing.api.ToolsSwingLocator;
50 442 jjdelcerro
import org.slf4j.LoggerFactory;
51
import org.slf4j.Logger;
52 165 jobacas
53 639 jjdelcerro
public class DefaultJScriptingBrowser extends JPanel implements JScriptingBrowser {
54 165 jobacas
55 468 jjdelcerro
    private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingBrowser.class);
56 639 jjdelcerro
    private static final long serialVersionUID = 3140698910497806258L;
57 165 jobacas
58 468 jjdelcerro
    protected ScriptingUIManager uimanager;
59
    protected ScriptingManager manager;
60
    protected TreeModel treeModel;
61
    protected JTree tree;
62
    protected ScriptingFolder root;
63 953 jjdelcerro
    protected ActionListenerSupport actionlisteners = null;
64 468 jjdelcerro
    private final boolean foldersOnly;
65 165 jobacas
66 639 jjdelcerro
    public static class DefaultBrowserActionEvent extends ActionEvent implements BrowserActionEvent {
67 442 jjdelcerro
68 468 jjdelcerro
        /**
69
         *
70
         */
71
        private static final long serialVersionUID = -1474410768278633364L;
72 702 jjdelcerro
        private ScriptingUnit unit = null;
73 442 jjdelcerro
74 639 jjdelcerro
        public DefaultBrowserActionEvent(Object source, int id, String command,
75 702 jjdelcerro
                ScriptingUnit unit) {
76 468 jjdelcerro
            super(source, id, command);
77 702 jjdelcerro
            this.unit = unit;
78 468 jjdelcerro
        }
79 165 jobacas
80 639 jjdelcerro
        @Override
81 702 jjdelcerro
        public ScriptingUnit getUnit() {
82
            return this.unit;
83 468 jjdelcerro
        }
84
    }
85 442 jjdelcerro
86 468 jjdelcerro
    class ScriptingFolderTreeModel implements TreeModel {
87 442 jjdelcerro
88 468 jjdelcerro
        protected final ScriptingFolder root;
89 442 jjdelcerro
90 468 jjdelcerro
        protected final List<TreeModelListener> listeners = new ArrayList();
91 442 jjdelcerro
92 468 jjdelcerro
        public ScriptingFolderTreeModel(ScriptingFolder root) {
93
            this.root = root;
94
        }
95 442 jjdelcerro
96 468 jjdelcerro
        @Override
97
        public Object getRoot() {
98
            return root;
99
        }
100 442 jjdelcerro
101 468 jjdelcerro
        @Override
102
        public Object getChild(Object parent, int index) {
103
            ScriptingFolder folder = (ScriptingFolder) parent;
104
            List<ScriptingUnit> children = folder.getUnits();
105
            return children.get(index);
106
        }
107 442 jjdelcerro
108 468 jjdelcerro
        @Override
109
        public int getChildCount(Object parent) {
110
            if (!(parent instanceof ScriptingFolder)) {
111
                return 0;
112
            }
113
            ScriptingFolder folder = (ScriptingFolder) parent;
114
            return folder.getUnits().size();
115
        }
116 165 jobacas
117 468 jjdelcerro
        @Override
118
        public boolean isLeaf(Object node) {
119
            return !(node instanceof ScriptingFolder);
120
        }
121 165 jobacas
122 468 jjdelcerro
        @Override
123
        public int getIndexOfChild(Object parent, Object child) {
124
            String childPath = ((ScriptingUnit) child).getFile().getAbsolutePath();
125
            ScriptingFolder folder = (ScriptingFolder) parent;
126
            List<ScriptingUnit> children = folder.getUnits();
127
            for (int i = 0; i < children.size(); i++) {
128
                ScriptingUnit aChild = children.get(i);
129
                if (aChild.getFile().getAbsolutePath().equals(childPath)) {
130
                    return i;
131
                }
132
            }
133
            return -1;
134
        }
135 165 jobacas
136 468 jjdelcerro
        @Override
137
        public void valueForPathChanged(TreePath path, Object value) {
138
        }
139 165 jobacas
140 468 jjdelcerro
        @Override
141
        public void addTreeModelListener(TreeModelListener listener) {
142
            listeners.add(listener);
143
        }
144 165 jobacas
145 468 jjdelcerro
        @Override
146
        public void removeTreeModelListener(TreeModelListener listener) {
147
            listeners.remove(listener);
148
        }
149 165 jobacas
150 468 jjdelcerro
        public void reload() {
151
            TreeModelEvent event = new TreeModelEvent(this, new TreePath(this.root));
152
            Iterator<TreeModelListener> iterator = listeners.iterator();
153
            TreeModelListener listener;
154
            while (iterator.hasNext()) {
155
                listener = iterator.next();
156
                listener.treeStructureChanged(event);
157
            }
158
        }
159
    }
160 442 jjdelcerro
161 468 jjdelcerro
    class ScriptingFolderTreeModelFoldersOnly extends ScriptingFolderTreeModel {
162 442 jjdelcerro
163 468 jjdelcerro
        public ScriptingFolderTreeModelFoldersOnly(ScriptingFolder root) {
164
            super(root);
165
        }
166 165 jobacas
167 468 jjdelcerro
        @Override
168
        public Object getChild(Object parent, int index) {
169
            ScriptingFolder folder = (ScriptingFolder) parent;
170
            List<ScriptingFolder> children = folder.getUnitFolders();
171
            return children.get(index);
172
        }
173 165 jobacas
174 468 jjdelcerro
        @Override
175
        public int getChildCount(Object parent) {
176
            if (!(parent instanceof ScriptingFolder)) {
177
                return 0;
178
            }
179
            ScriptingFolder folder = (ScriptingFolder) parent;
180
            return folder.getUnitFolders().size();
181
        }
182 165 jobacas
183 468 jjdelcerro
        @Override
184
        public int getIndexOfChild(Object parent, Object child) {
185
            String childPath = ((ScriptingFolder) child).getFile().getAbsolutePath();
186
            ScriptingFolder folder = (ScriptingFolder) parent;
187
            List<ScriptingFolder> children = folder.getUnitFolders();
188
            for (int i = 0; i < children.size(); i++) {
189
                ScriptingUnit aChild = children.get(i);
190
                if (aChild.getFile().getAbsolutePath().equals(childPath)) {
191
                    return i;
192
                }
193
            }
194
            return -1;
195
        }
196 165 jobacas
197 468 jjdelcerro
    }
198 165 jobacas
199 468 jjdelcerro
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
200
            ScriptingFolder root) {
201
        this(uimanager, root, false);
202
    }
203 165 jobacas
204 468 jjdelcerro
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
205
            ScriptingFolder root, boolean foldersOnly) {
206
        super(new GridLayout(1, 2));
207 953 jjdelcerro
        this.actionlisteners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
208 468 jjdelcerro
        this.foldersOnly = foldersOnly;
209
        this.uimanager = uimanager;
210
        this.manager = uimanager.getManager();
211
        this.root = root;
212
        this.makeUI();
213
    }
214 442 jjdelcerro
215 639 jjdelcerro
    @Override
216
    public JComponent asJComponent() {
217
        return this;
218
    }
219
220 468 jjdelcerro
    public void refresh() {
221 952 jjdelcerro
        Enumeration<TreePath> x = tree.getExpandedDescendants(new TreePath(treeModel.getRoot()));
222 468 jjdelcerro
        ((ScriptingFolderTreeModel) this.treeModel).reload();
223 952 jjdelcerro
        if (x != null) {
224
            while (x.hasMoreElements()) {
225
                try {
226
                    TreePath treePath = (TreePath) x.nextElement();
227
                    tree.expandPath(treePath);
228
                } catch(Throwable th) {
229
230
                }
231
            }
232
        }
233 468 jjdelcerro
    }
234 442 jjdelcerro
235 952 jjdelcerro
236 468 jjdelcerro
    @Override
237
    public ScriptingManager getManager() {
238
        return this.manager;
239
    }
240 442 jjdelcerro
241 468 jjdelcerro
    @Override
242
    public ScriptingFolder getRoot() {
243
        return this.root;
244
    }
245 442 jjdelcerro
246 639 jjdelcerro
    @Override
247 953 jjdelcerro
    public void addActionListener(ActionListener actionlistener) {
248
        this.actionlisteners.addActionListener(actionlistener);
249 468 jjdelcerro
    }
250 165 jobacas
251 468 jjdelcerro
    private void makeUI() {
252
        if (this.foldersOnly) {
253
            treeModel = new ScriptingFolderTreeModelFoldersOnly(root);
254
        } else {
255
            treeModel = new ScriptingFolderTreeModel(root);
256
        }
257 165 jobacas
258 468 jjdelcerro
        tree = new JTree(treeModel);
259
        tree.setCellRenderer(new IconCellRenderer());
260
        tree.setEditable(false);
261
        tree.setShowsRootHandles(true);
262
        tree.getSelectionModel().setSelectionMode(
263
                TreeSelectionModel.SINGLE_TREE_SELECTION);
264 165 jobacas
265 468 jjdelcerro
        tree.addTreeSelectionListener(new TreeSelectionListener() {
266
            @Override
267
            public void valueChanged(TreeSelectionEvent e) {
268 953 jjdelcerro
                JTree tree = (JTree) e.getSource();
269
                if (!tree.isSelectionEmpty()) {
270
                    fireSelectAction(tree.getSelectionPath());
271 468 jjdelcerro
                }
272
            }
273
        });
274
        tree.addMouseListener(new MouseListener() {
275
            @Override
276
            public void mouseClicked(MouseEvent arg0) {
277
                if (arg0.getClickCount() == 2) {
278
                    JTree tree = (JTree) arg0.getSource();
279
                    if (!tree.isSelectionEmpty()) {
280
                        fireDefaultAction(tree.getSelectionPath());
281
                    }
282
                }
283
            }
284 442 jjdelcerro
285 468 jjdelcerro
            @Override
286
            public void mouseEntered(MouseEvent arg0) {
287
            }
288 442 jjdelcerro
289 468 jjdelcerro
            @Override
290
            public void mouseExited(MouseEvent arg0) {
291
            }
292 442 jjdelcerro
293 468 jjdelcerro
            @Override
294
            public void mousePressed(MouseEvent arg0) {
295
            }
296 165 jobacas
297 468 jjdelcerro
            @Override
298
            public void mouseReleased(MouseEvent arg0) {
299
            }
300
        });
301 630 jjdelcerro
        tree.getActionMap().put(
302
                KeyStroke.getKeyStroke("+"),
303
                new ExpandSelectedNodeAction()
304
        );
305
        tree.getActionMap().put(
306
                KeyStroke.getKeyStroke("SPACE"),
307
                new ExpandSelectedNodeAction()
308
        );
309
        tree.getActionMap().put(
310
                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
311
                new EnterAction()
312
        );
313
314 468 jjdelcerro
        JScrollPane scrollPane = new JScrollPane(tree);
315
        add(scrollPane);
316
    }
317 165 jobacas
318 468 jjdelcerro
    @Override
319 702 jjdelcerro
    public TreePath getSelectionPath() {
320
        return this.tree.getSelectionPath();
321
    }
322
323
    @Override
324
    public void setSelectionPath(TreePath path) {
325
        if( path == null ) {
326
            this.tree.clearSelection();
327
        } else {
328
            this.tree.setSelectionPath(path);
329
        }
330
    }
331
332
    @Override
333 468 jjdelcerro
    public ScriptingUnit getSelectedNode() {
334
        ScriptingUnit unit;
335
        if (tree.getSelectionPath() != null) {
336
            unit = (ScriptingUnit) tree.getSelectionPath().getLastPathComponent();
337
        } else {
338
            unit = (ScriptingUnit) this.treeModel.getRoot();
339
        }
340
        return unit;
341
    }
342 165 jobacas
343 468 jjdelcerro
    private void fireDefaultAction(TreePath path) {
344
        ScriptingUnit unit = (ScriptingUnit) path.getLastPathComponent();
345 981 jjdelcerro
        unit.reload();
346 953 jjdelcerro
        ActionEvent ae = new DefaultBrowserActionEvent(
347
                this,
348
                DEFAULT_ACTION,
349
                "default",
350
                unit
351
        );
352
        this.actionlisteners.fireActionEvent(ae);
353 468 jjdelcerro
    }
354 165 jobacas
355 953 jjdelcerro
    private void fireSelectAction(TreePath path) {
356
        ScriptingUnit unit = (ScriptingUnit) path.getLastPathComponent();
357
        ActionEvent ae = new DefaultJScriptingBrowser.DefaultBrowserActionEvent(
358
                this,
359
                SELECTION_ACTION,
360
                "select",
361
                unit
362
        );
363
        this.actionlisteners.fireActionEvent(ae);
364
    }
365
366 630 jjdelcerro
    private class EnterAction extends AbstractAction {
367 639 jjdelcerro
        private static final long serialVersionUID = -3673546098243190397L;
368 630 jjdelcerro
369
        @Override
370
        public void actionPerformed(ActionEvent ae) {
371
            TreePath selected = tree.getSelectionPath();
372
            fireDefaultAction(selected);
373
        }
374
375
    }
376
377
    private class ExpandSelectedNodeAction extends AbstractAction {
378 639 jjdelcerro
        private static final long serialVersionUID = -4121272513454221967L;
379 630 jjdelcerro
380
        @Override
381
        public void actionPerformed(ActionEvent ae) {
382
            try {
383
                TreePath selected = tree.getSelectionPath();
384
                if( tree.isCollapsed(selected) ) {
385
                    tree.expandPath(selected);
386
                } else {
387
                    tree.collapsePath(selected);
388
                }
389
            } catch(Throwable th) {
390
                // Do nothing, ignore errors
391
            }
392
        }
393
394
    }
395
396 468 jjdelcerro
    private class IconCellRenderer extends JLabel implements TreeCellRenderer {
397 165 jobacas
398 468 jjdelcerro
        /**
399
         *
400
         */
401
        private static final long serialVersionUID = 1L;
402
        protected Color m_textSelectionColor;
403
        protected Color m_textNonSelectionColor;
404
        protected Color m_bkSelectionColor;
405
        protected Color m_bkNonSelectionColor;
406
        protected Color m_borderSelectionColor;
407 165 jobacas
408 468 jjdelcerro
        protected boolean m_selected;
409 165 jobacas
410 468 jjdelcerro
        public IconCellRenderer() {
411
            super();
412
            m_textSelectionColor = UIManager
413
                    .getColor("Tree.selectionForeground");
414
            m_textNonSelectionColor = UIManager.getColor("Tree.textForeground");
415
            m_bkSelectionColor = UIManager.getColor("Tree.selectionBackground");
416
            m_bkNonSelectionColor = UIManager.getColor("Tree.textBackground");
417
            m_borderSelectionColor = UIManager
418
                    .getColor("Tree.selectionBorderColor");
419
            setOpaque(false);
420
        }
421 165 jobacas
422 639 jjdelcerro
        private final Map<String, ImageIcon> icons = new HashMap<>();
423 165 jobacas
424 468 jjdelcerro
        private ImageIcon getIcon(String iconName) {
425
            ImageIcon img = this.icons.get(iconName);
426
            if (img == null) {
427
                img = uimanager.getIcon(iconName);
428
                this.icons.put(iconName, img);
429
            }
430
            return img;
431
        }
432 442 jjdelcerro
433 468 jjdelcerro
        private ImageIcon getExpandedIcon(ScriptingUnit unit) {
434 1200 jjdelcerro
            if( unit instanceof ScriptingExternalFile) {
435
              ScriptingExternalFile extfile = (ScriptingExternalFile) unit;
436
              String ext = FilenameUtils.getExtension(extfile.getExternalFile().getName());
437
              ClassLoader loader = this.getClass().getClassLoader();
438
              URL res = loader.getResource("org/gvsig/scripting/i18n/images/16x16/extensions/"+ext+"-icon-16x16.png");
439
              if( res!=null ) {
440
                return new ImageIcon(res);
441
              }
442
            }
443 468 jjdelcerro
            return getIcon(unit.getIconNames()[1]);
444
        }
445 442 jjdelcerro
446 468 jjdelcerro
        private ImageIcon getCollapsedIcon(ScriptingUnit unit) {
447 1200 jjdelcerro
            if( unit instanceof ScriptingExternalFile) {
448
              ScriptingExternalFile extfile = (ScriptingExternalFile) unit;
449
              String ext = FilenameUtils.getExtension(extfile.getExternalFile().getName());
450
              ClassLoader loader = this.getClass().getClassLoader();
451
              URL res = loader.getResource("org/gvsig/scripting/images/16x16/extensions/"+ext+"-icon-16x16.png");
452
              if( res!=null ) {
453
                return new ImageIcon(res);
454
              }
455
            }
456 468 jjdelcerro
            return getIcon(unit.getIconNames()[0]);
457
        }
458 165 jobacas
459 639 jjdelcerro
        @Override
460 468 jjdelcerro
        public Component getTreeCellRendererComponent(JTree tree, Object value,
461
                boolean sel, boolean expanded, boolean leaf, int row,
462
                boolean hasFocus) {
463
            ScriptingUnit unit = (ScriptingUnit) value;
464
            setText(unit.getName());
465
            if (expanded) {
466
                setIcon(this.getExpandedIcon(unit));
467
            } else {
468
                setIcon(this.getCollapsedIcon(unit));
469
            }
470 165 jobacas
471 468 jjdelcerro
            setFont(tree.getFont());
472
            setForeground(sel ? m_textSelectionColor : m_textNonSelectionColor);
473
            setBackground(sel ? m_bkSelectionColor : m_bkNonSelectionColor);
474
            m_selected = sel;
475
            return this;
476
        }
477 165 jobacas
478 468 jjdelcerro
        @Override
479
        public void paintComponent(Graphics g) {
480
            Color bColor = getBackground();
481
            Icon icon = getIcon();
482 165 jobacas
483 468 jjdelcerro
            g.setColor(bColor);
484
            int offset = 0;
485
            if (icon != null && getText() != null) {
486
                offset = (icon.getIconWidth() + getIconTextGap());
487
            }
488
            g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
489 165 jobacas
490 468 jjdelcerro
            if (m_selected) {
491
                g.setColor(m_borderSelectionColor);
492
                g.drawRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
493
            }
494
            super.paintComponent(g);
495
        }
496
    }
497 165 jobacas
498
}