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

History | View | Annotate | Download (15.1 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.KeyEvent;
10
import java.awt.event.MouseEvent;
11
import java.awt.event.MouseListener;
12
import java.util.ArrayList;
13
import java.util.Enumeration;
14
import java.util.HashMap;
15
import java.util.Iterator;
16
import java.util.List;
17
import java.util.Map;
18
import javax.swing.AbstractAction;
19

    
20
import javax.swing.Icon;
21
import javax.swing.ImageIcon;
22
import javax.swing.JComponent;
23
import javax.swing.JLabel;
24
import javax.swing.JPanel;
25
import javax.swing.JScrollPane;
26
import javax.swing.JTree;
27
import javax.swing.KeyStroke;
28
import javax.swing.UIManager;
29
import javax.swing.event.TreeModelEvent;
30
import javax.swing.event.TreeModelListener;
31
import javax.swing.event.TreeSelectionEvent;
32
import javax.swing.event.TreeSelectionListener;
33
import javax.swing.tree.TreeCellRenderer;
34
import javax.swing.tree.TreeModel;
35
import javax.swing.tree.TreePath;
36
import javax.swing.tree.TreeSelectionModel;
37

    
38
import org.gvsig.scripting.ScriptingFolder;
39
import org.gvsig.scripting.ScriptingManager;
40
import org.gvsig.scripting.ScriptingUnit;
41
import org.gvsig.scripting.swing.api.JScriptingBrowser;
42
import org.gvsig.scripting.swing.api.ScriptingUIManager;
43
import org.slf4j.LoggerFactory;
44
import org.slf4j.Logger;
45

    
46
public class DefaultJScriptingBrowser extends JPanel implements JScriptingBrowser {
47

    
48
    private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingBrowser.class);
49
    private static final long serialVersionUID = 3140698910497806258L;
50

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

    
60
    public static class DefaultBrowserActionEvent extends ActionEvent implements BrowserActionEvent {
61

    
62
        /**
63
         *
64
         */
65
        private static final long serialVersionUID = -1474410768278633364L;
66
        private ScriptingUnit unit = null;
67

    
68
        public DefaultBrowserActionEvent(Object source, int id, String command,
69
                ScriptingUnit unit) {
70
            super(source, id, command);
71
            this.unit = unit;
72
        }
73

    
74
        @Override
75
        public ScriptingUnit getUnit() {
76
            return this.unit;
77
        }
78
    }
79

    
80
    class ScriptingFolderTreeModel implements TreeModel {
81

    
82
        protected final ScriptingFolder root;
83

    
84
        protected final List<TreeModelListener> listeners = new ArrayList();
85

    
86
        public ScriptingFolderTreeModel(ScriptingFolder root) {
87
            this.root = root;
88
        }
89

    
90
        @Override
91
        public Object getRoot() {
92
            return root;
93
        }
94

    
95
        @Override
96
        public Object getChild(Object parent, int index) {
97
            ScriptingFolder folder = (ScriptingFolder) parent;
98
            List<ScriptingUnit> children = folder.getUnits();
99
            return children.get(index);
100
        }
101

    
102
        @Override
103
        public int getChildCount(Object parent) {
104
            if (!(parent instanceof ScriptingFolder)) {
105
                return 0;
106
            }
107
            ScriptingFolder folder = (ScriptingFolder) parent;
108
            return folder.getUnits().size();
109
        }
110

    
111
        @Override
112
        public boolean isLeaf(Object node) {
113
            return !(node instanceof ScriptingFolder);
114
        }
115

    
116
        @Override
117
        public int getIndexOfChild(Object parent, Object child) {
118
            String childPath = ((ScriptingUnit) child).getFile().getAbsolutePath();
119
            ScriptingFolder folder = (ScriptingFolder) parent;
120
            List<ScriptingUnit> children = folder.getUnits();
121
            for (int i = 0; i < children.size(); i++) {
122
                ScriptingUnit aChild = children.get(i);
123
                if (aChild.getFile().getAbsolutePath().equals(childPath)) {
124
                    return i;
125
                }
126
            }
127
            return -1;
128
        }
129

    
130
        @Override
131
        public void valueForPathChanged(TreePath path, Object value) {
132
        }
133

    
134
        @Override
135
        public void addTreeModelListener(TreeModelListener listener) {
136
            listeners.add(listener);
137
        }
138

    
139
        @Override
140
        public void removeTreeModelListener(TreeModelListener listener) {
141
            listeners.remove(listener);
142
        }
143

    
144
        public void reload() {
145
            TreeModelEvent event = new TreeModelEvent(this, new TreePath(this.root));
146
            Iterator<TreeModelListener> iterator = listeners.iterator();
147
            TreeModelListener listener;
148
            while (iterator.hasNext()) {
149
                listener = iterator.next();
150
                listener.treeStructureChanged(event);
151
            }
152
        }
153
    }
154

    
155
    class ScriptingFolderTreeModelFoldersOnly extends ScriptingFolderTreeModel {
156

    
157
        public ScriptingFolderTreeModelFoldersOnly(ScriptingFolder root) {
158
            super(root);
159
        }
160

    
161
        @Override
162
        public Object getChild(Object parent, int index) {
163
            ScriptingFolder folder = (ScriptingFolder) parent;
164
            List<ScriptingFolder> children = folder.getUnitFolders();
165
            return children.get(index);
166
        }
167

    
168
        @Override
169
        public int getChildCount(Object parent) {
170
            if (!(parent instanceof ScriptingFolder)) {
171
                return 0;
172
            }
173
            ScriptingFolder folder = (ScriptingFolder) parent;
174
            return folder.getUnitFolders().size();
175
        }
176

    
177
        @Override
178
        public int getIndexOfChild(Object parent, Object child) {
179
            String childPath = ((ScriptingFolder) child).getFile().getAbsolutePath();
180
            ScriptingFolder folder = (ScriptingFolder) parent;
181
            List<ScriptingFolder> children = folder.getUnitFolders();
182
            for (int i = 0; i < children.size(); i++) {
183
                ScriptingUnit aChild = children.get(i);
184
                if (aChild.getFile().getAbsolutePath().equals(childPath)) {
185
                    return i;
186
                }
187
            }
188
            return -1;
189
        }
190

    
191
    }
192

    
193
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
194
            ScriptingFolder root) {
195
        this(uimanager, root, false);
196
    }
197

    
198
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
199
            ScriptingFolder root, boolean foldersOnly) {
200
        super(new GridLayout(1, 2));
201
        this.foldersOnly = foldersOnly;
202
        this.uimanager = uimanager;
203
        this.manager = uimanager.getManager();
204
        this.root = root;
205
        this.makeUI();
206
    }
207

    
208
    @Override
209
    public JComponent asJComponent() {
210
        return this;
211
    }
212

    
213
    public void refresh() {
214
        Enumeration<TreePath> x = tree.getExpandedDescendants(new TreePath(treeModel.getRoot()));
215
        ((ScriptingFolderTreeModel) this.treeModel).reload();
216
        if (x != null) {
217
            while (x.hasMoreElements()) {
218
                try {
219
                    TreePath treePath = (TreePath) x.nextElement();
220
                    tree.expandPath(treePath);
221
                } catch(Throwable th) {
222
                    
223
                }
224
            }
225
        }        
226
    }
227

    
228
    
229
    @Override
230
    public ScriptingManager getManager() {
231
        return this.manager;
232
    }
233

    
234
    @Override
235
    public ScriptingFolder getRoot() {
236
        return this.root;
237
    }
238

    
239
    @Override
240
    public void addDefaultActionListener(ActionListener actionlistener) {
241
        this.defaultActionlistener = actionlistener;
242
    }
243

    
244
    @Override
245
    public void addSelectionActionListener(ActionListener actionlistener) {
246
        this.selectionActionlistener = actionlistener;
247
    }
248

    
249
    private void makeUI() {
250
        if (this.foldersOnly) {
251
            treeModel = new ScriptingFolderTreeModelFoldersOnly(root);
252
        } else {
253
            treeModel = new ScriptingFolderTreeModel(root);
254
        }
255

    
256
        tree = new JTree(treeModel);
257
        tree.setCellRenderer(new IconCellRenderer());
258
        tree.setEditable(false);
259
        tree.setShowsRootHandles(true);
260
        tree.getSelectionModel().setSelectionMode(
261
                TreeSelectionModel.SINGLE_TREE_SELECTION);
262

    
263
        tree.addTreeSelectionListener(new TreeSelectionListener() {
264
            @Override
265
            public void valueChanged(TreeSelectionEvent e) {
266
                if (selectionActionlistener != null) {
267
                    JComponent tree = (JComponent) e.getSource();
268
                    ActionEvent event = new DefaultBrowserActionEvent(
269
                            tree.getParent(),
270
                            SELECTION_ACTION,
271
                            "select",
272
                            null
273
                    );
274
                    selectionActionlistener.actionPerformed(event);
275
                }
276
            }
277
        });
278
        tree.addMouseListener(new MouseListener() {
279
            @Override
280
            public void mouseClicked(MouseEvent arg0) {
281
                if (arg0.getClickCount() == 2) {
282
                    JTree tree = (JTree) arg0.getSource();
283
                    if (!tree.isSelectionEmpty()) {
284
                        fireDefaultAction(tree.getSelectionPath());
285
                    }
286
                }
287
            }
288

    
289
            @Override
290
            public void mouseEntered(MouseEvent arg0) {
291
            }
292

    
293
            @Override
294
            public void mouseExited(MouseEvent arg0) {
295
            }
296

    
297
            @Override
298
            public void mousePressed(MouseEvent arg0) {
299
            }
300

    
301
            @Override
302
            public void mouseReleased(MouseEvent arg0) {
303
            }
304
        });
305
        tree.getActionMap().put(
306
                KeyStroke.getKeyStroke("+"),
307
                new ExpandSelectedNodeAction()
308
        );
309
        tree.getActionMap().put(
310
                KeyStroke.getKeyStroke("SPACE"),
311
                new ExpandSelectedNodeAction()
312
        );
313
        tree.getActionMap().put(
314
                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
315
                new EnterAction()
316
        );
317
        
318
        JScrollPane scrollPane = new JScrollPane(tree);
319
        add(scrollPane);
320
    }
321

    
322
    @Override
323
    public TreePath getSelectionPath() {
324
        return this.tree.getSelectionPath();
325
    }
326
    
327
    @Override
328
    public void setSelectionPath(TreePath path) {
329
        if( path == null ) {
330
            this.tree.clearSelection();
331
        } else {
332
            this.tree.setSelectionPath(path);
333
        }
334
    }
335
    
336
    @Override
337
    public ScriptingUnit getSelectedNode() {
338
        ScriptingUnit unit;
339
        if (tree.getSelectionPath() != null) {
340
            unit = (ScriptingUnit) tree.getSelectionPath().getLastPathComponent();
341
        } else {
342
            unit = (ScriptingUnit) this.treeModel.getRoot();
343
        }
344
        return unit;
345
    }
346

    
347
    private void fireDefaultAction(TreePath path) {
348
        ScriptingUnit unit = (ScriptingUnit) path.getLastPathComponent();
349
        //if (unit instanceof ScriptingBaseScript) {
350
            if (this.defaultActionlistener != null) {
351
                ActionEvent event = new DefaultBrowserActionEvent(
352
                        this,
353
                        DEFAULT_ACTION,
354
                        "default",
355
                        unit
356
                );
357
                this.defaultActionlistener.actionPerformed(event);
358
            }
359
        //}
360
    }
361

    
362
    private class EnterAction extends AbstractAction {
363
        private static final long serialVersionUID = -3673546098243190397L;
364

    
365
        @Override
366
        public void actionPerformed(ActionEvent ae) {
367
            TreePath selected = tree.getSelectionPath();
368
            fireDefaultAction(selected);
369
        }
370
        
371
    }
372

    
373
    private class ExpandSelectedNodeAction extends AbstractAction {
374
        private static final long serialVersionUID = -4121272513454221967L;
375

    
376
        @Override
377
        public void actionPerformed(ActionEvent ae) {
378
            try {
379
                TreePath selected = tree.getSelectionPath();
380
                if( tree.isCollapsed(selected) ) {
381
                    tree.expandPath(selected);
382
                } else {
383
                    tree.collapsePath(selected);
384
                }
385
            } catch(Throwable th) {
386
                // Do nothing, ignore errors
387
            }
388
        }
389
        
390
    }
391
    
392
    private class IconCellRenderer extends JLabel implements TreeCellRenderer {
393

    
394
        /**
395
         *
396
         */
397
        private static final long serialVersionUID = 1L;
398
        protected Color m_textSelectionColor;
399
        protected Color m_textNonSelectionColor;
400
        protected Color m_bkSelectionColor;
401
        protected Color m_bkNonSelectionColor;
402
        protected Color m_borderSelectionColor;
403

    
404
        protected boolean m_selected;
405

    
406
        public IconCellRenderer() {
407
            super();
408
            m_textSelectionColor = UIManager
409
                    .getColor("Tree.selectionForeground");
410
            m_textNonSelectionColor = UIManager.getColor("Tree.textForeground");
411
            m_bkSelectionColor = UIManager.getColor("Tree.selectionBackground");
412
            m_bkNonSelectionColor = UIManager.getColor("Tree.textBackground");
413
            m_borderSelectionColor = UIManager
414
                    .getColor("Tree.selectionBorderColor");
415
            setOpaque(false);
416
        }
417

    
418
        private final Map<String, ImageIcon> icons = new HashMap<>();
419

    
420
        private ImageIcon getIcon(String iconName) {
421
            ImageIcon img = this.icons.get(iconName);
422
            if (img == null) {
423
                img = uimanager.getIcon(iconName);
424
                this.icons.put(iconName, img);
425
            }
426
            return img;
427
        }
428

    
429
        private ImageIcon getExpandedIcon(ScriptingUnit unit) {
430
            return getIcon(unit.getIconNames()[1]);
431
        }
432

    
433
        private ImageIcon getCollapsedIcon(ScriptingUnit unit) {
434
            return getIcon(unit.getIconNames()[0]);
435
        }
436

    
437
        @Override
438
        public Component getTreeCellRendererComponent(JTree tree, Object value,
439
                boolean sel, boolean expanded, boolean leaf, int row,
440
                boolean hasFocus) {
441
            ScriptingUnit unit = (ScriptingUnit) value;
442
            setText(unit.getName());
443
            if (expanded) {
444
                setIcon(this.getExpandedIcon(unit));
445
            } else {
446
                setIcon(this.getCollapsedIcon(unit));
447
            }
448

    
449
            setFont(tree.getFont());
450
            setForeground(sel ? m_textSelectionColor : m_textNonSelectionColor);
451
            setBackground(sel ? m_bkSelectionColor : m_bkNonSelectionColor);
452
            m_selected = sel;
453
            return this;
454
        }
455

    
456
        @Override
457
        public void paintComponent(Graphics g) {
458
            Color bColor = getBackground();
459
            Icon icon = getIcon();
460

    
461
            g.setColor(bColor);
462
            int offset = 0;
463
            if (icon != null && getText() != null) {
464
                offset = (icon.getIconWidth() + getIconTextGap());
465
            }
466
            g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
467

    
468
            if (m_selected) {
469
                g.setColor(m_borderSelectionColor);
470
                g.drawRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1);
471
            }
472
            super.paintComponent(g);
473
        }
474
    }
475

    
476
}