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

History | View | Annotate | Download (15.2 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 static org.gvsig.scripting.swing.api.JScriptingBrowser.DEFAULT_ACTION;
43
import static org.gvsig.scripting.swing.api.JScriptingBrowser.SELECTION_ACTION;
44
import org.gvsig.scripting.swing.api.ScriptingUIManager;
45
import org.gvsig.tools.swing.api.ActionListenerSupport;
46
import org.gvsig.tools.swing.api.ToolsSwingLocator;
47
import org.slf4j.LoggerFactory;
48
import org.slf4j.Logger;
49

    
50
public class DefaultJScriptingBrowser extends JPanel implements JScriptingBrowser {
51

    
52
    private static final Logger logger = LoggerFactory.getLogger(DefaultJScriptingBrowser.class);
53
    private static final long serialVersionUID = 3140698910497806258L;
54

    
55
    protected ScriptingUIManager uimanager;
56
    protected ScriptingManager manager;
57
    protected TreeModel treeModel;
58
    protected JTree tree;
59
    protected ScriptingFolder root;
60
    protected ActionListenerSupport actionlisteners = null;
61
    private final boolean foldersOnly;
62

    
63
    public static class DefaultBrowserActionEvent extends ActionEvent implements BrowserActionEvent {
64

    
65
        /**
66
         *
67
         */
68
        private static final long serialVersionUID = -1474410768278633364L;
69
        private ScriptingUnit unit = null;
70

    
71
        public DefaultBrowserActionEvent(Object source, int id, String command,
72
                ScriptingUnit unit) {
73
            super(source, id, command);
74
            this.unit = unit;
75
        }
76

    
77
        @Override
78
        public ScriptingUnit getUnit() {
79
            return this.unit;
80
        }
81
    }
82

    
83
    class ScriptingFolderTreeModel implements TreeModel {
84

    
85
        protected final ScriptingFolder root;
86

    
87
        protected final List<TreeModelListener> listeners = new ArrayList();
88

    
89
        public ScriptingFolderTreeModel(ScriptingFolder root) {
90
            this.root = root;
91
        }
92

    
93
        @Override
94
        public Object getRoot() {
95
            return root;
96
        }
97

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

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

    
114
        @Override
115
        public boolean isLeaf(Object node) {
116
            return !(node instanceof ScriptingFolder);
117
        }
118

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

    
133
        @Override
134
        public void valueForPathChanged(TreePath path, Object value) {
135
        }
136

    
137
        @Override
138
        public void addTreeModelListener(TreeModelListener listener) {
139
            listeners.add(listener);
140
        }
141

    
142
        @Override
143
        public void removeTreeModelListener(TreeModelListener listener) {
144
            listeners.remove(listener);
145
        }
146

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

    
158
    class ScriptingFolderTreeModelFoldersOnly extends ScriptingFolderTreeModel {
159

    
160
        public ScriptingFolderTreeModelFoldersOnly(ScriptingFolder root) {
161
            super(root);
162
        }
163

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

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

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

    
194
    }
195

    
196
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
197
            ScriptingFolder root) {
198
        this(uimanager, root, false);
199
    }
200

    
201
    public DefaultJScriptingBrowser(ScriptingUIManager uimanager,
202
            ScriptingFolder root, boolean foldersOnly) {
203
        super(new GridLayout(1, 2));
204
        this.actionlisteners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
205
        this.foldersOnly = foldersOnly;
206
        this.uimanager = uimanager;
207
        this.manager = uimanager.getManager();
208
        this.root = root;
209
        this.makeUI();
210
    }
211

    
212
    @Override
213
    public JComponent asJComponent() {
214
        return this;
215
    }
216

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

    
232
    
233
    @Override
234
    public ScriptingManager getManager() {
235
        return this.manager;
236
    }
237

    
238
    @Override
239
    public ScriptingFolder getRoot() {
240
        return this.root;
241
    }
242

    
243
    @Override
244
    public void addActionListener(ActionListener actionlistener) {
245
        this.actionlisteners.addActionListener(actionlistener);
246
    }
247

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

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

    
262
        tree.addTreeSelectionListener(new TreeSelectionListener() {
263
            @Override
264
            public void valueChanged(TreeSelectionEvent e) {
265
                JTree tree = (JTree) e.getSource();
266
                if (!tree.isSelectionEmpty()) {
267
                    fireSelectAction(tree.getSelectionPath());
268
                }
269
            }
270
        });
271
        tree.addMouseListener(new MouseListener() {
272
            @Override
273
            public void mouseClicked(MouseEvent arg0) {
274
                if (arg0.getClickCount() == 2) {
275
                    JTree tree = (JTree) arg0.getSource();
276
                    if (!tree.isSelectionEmpty()) {
277
                        fireDefaultAction(tree.getSelectionPath());
278
                    }
279
                }
280
            }
281

    
282
            @Override
283
            public void mouseEntered(MouseEvent arg0) {
284
            }
285

    
286
            @Override
287
            public void mouseExited(MouseEvent arg0) {
288
            }
289

    
290
            @Override
291
            public void mousePressed(MouseEvent arg0) {
292
            }
293

    
294
            @Override
295
            public void mouseReleased(MouseEvent arg0) {
296
            }
297
        });
298
        tree.getActionMap().put(
299
                KeyStroke.getKeyStroke("+"),
300
                new ExpandSelectedNodeAction()
301
        );
302
        tree.getActionMap().put(
303
                KeyStroke.getKeyStroke("SPACE"),
304
                new ExpandSelectedNodeAction()
305
        );
306
        tree.getActionMap().put(
307
                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
308
                new EnterAction()
309
        );
310
        
311
        JScrollPane scrollPane = new JScrollPane(tree);
312
        add(scrollPane);
313
    }
314

    
315
    @Override
316
    public TreePath getSelectionPath() {
317
        return this.tree.getSelectionPath();
318
    }
319
    
320
    @Override
321
    public void setSelectionPath(TreePath path) {
322
        if( path == null ) {
323
            this.tree.clearSelection();
324
        } else {
325
            this.tree.setSelectionPath(path);
326
        }
327
    }
328
    
329
    @Override
330
    public ScriptingUnit getSelectedNode() {
331
        ScriptingUnit unit;
332
        if (tree.getSelectionPath() != null) {
333
            unit = (ScriptingUnit) tree.getSelectionPath().getLastPathComponent();
334
        } else {
335
            unit = (ScriptingUnit) this.treeModel.getRoot();
336
        }
337
        return unit;
338
    }
339

    
340
    private void fireDefaultAction(TreePath path) {
341
        ScriptingUnit unit = (ScriptingUnit) path.getLastPathComponent();
342
        unit.reload();
343
        ActionEvent ae = new DefaultBrowserActionEvent(
344
                this,
345
                DEFAULT_ACTION,
346
                "default",
347
                unit
348
        );
349
        this.actionlisteners.fireActionEvent(ae);
350
    }
351

    
352
    private void fireSelectAction(TreePath path) {
353
        ScriptingUnit unit = (ScriptingUnit) path.getLastPathComponent();
354
        ActionEvent ae = new DefaultJScriptingBrowser.DefaultBrowserActionEvent(
355
                this,
356
                SELECTION_ACTION,
357
                "select",
358
                unit
359
        );
360
        this.actionlisteners.fireActionEvent(ae);
361
    }
362

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

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

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

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

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

    
405
        protected boolean m_selected;
406

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

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

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

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

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

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

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

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

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

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

    
477
}