KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > works > project > ProjectExplorer


1 package org.antlr.works.project;
2
3 import org.antlr.xjlib.appkit.swing.XJTree;
4 import org.antlr.works.components.project.CContainerProject;
5
6 import javax.swing.*;
7 import javax.swing.event.TreeSelectionEvent JavaDoc;
8 import javax.swing.event.TreeSelectionListener JavaDoc;
9 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
10 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
11 import javax.swing.tree.DefaultTreeModel JavaDoc;
12 import javax.swing.tree.TreePath JavaDoc;
13 import java.awt.*;
14 import java.awt.event.ActionEvent JavaDoc;
15 import java.awt.event.ActionListener JavaDoc;
16 import java.awt.event.MouseAdapter JavaDoc;
17 import java.awt.event.MouseEvent JavaDoc;
18 import java.util.*;
19 import java.util.List JavaDoc;
20 /*
21
22 [The "BSD licence"]
23 Copyright (c) 2005-2006 Jean Bovet
24 All rights reserved.
25
26 Redistribution and use in source and binary forms, with or without
27 modification, are permitted provided that the following conditions
28 are met:
29
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32 2. Redistributions in binary form must reproduce the above copyright
33 notice, this list of conditions and the following disclaimer in the
34 documentation and/or other materials provided with the distribution.
35 3. The name of the author may not be used to endorse or promote products
36 derived from this software without specific prior written permission.
37
38 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
41 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
42 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
47 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48
49 */

50
51 public class ProjectExplorer {
52
53     protected CContainerProject project;
54     protected JComponent container;
55
56     protected ProjectExplorerLoader loader;
57
58     protected XJTree filesTree;
59     protected DefaultMutableTreeNode JavaDoc filesTreeRootNode;
60     protected DefaultTreeModel JavaDoc filesTreeModel;
61
62     public ProjectExplorer(CContainerProject project) {
63         this.project = project;
64         loader = new ProjectExplorerLoader(this);
65
66         create();
67     }
68
69     public void create() {
70
71         filesTree = new XJTree();
72
73         filesTree.setBorder(null);
74         // Apparently, if I don't set the tooltip here, nothing is displayed (weird)
75
filesTree.setToolTipText("");
76         filesTree.setDragEnabled(true);
77         filesTree.setRootVisible(false);
78         filesTree.setShowsRootHandles(true);
79 // filesTree.setEnableDragAndDrop();
80
filesTree.setCellRenderer(new CustomTableRenderer());
81
82         filesTreeRootNode = new DefaultMutableTreeNode JavaDoc();
83         filesTreeModel = new DefaultTreeModel JavaDoc(filesTreeRootNode);
84
85         filesTree.setModel(filesTreeModel);
86         filesTree.addTreeSelectionListener(new FilesTreeSelectionListener());
87         filesTree.addMouseListener(new FilesTreeMouseListener());
88
89         JScrollPane scrollPane = new JScrollPane(filesTree);
90         scrollPane.setWheelScrollingEnabled(true);
91
92         container = scrollPane;
93     }
94
95     public Component getPanel() {
96         return container;
97     }
98
99     public List JavaDoc getFileEditorItems() {
100         return loader.getAllFiles();
101     }
102
103     public void close() {
104         runClosureOnFileEditorItems(new FileEditorItemClosure() {
105             public void process(ProjectFileItem item) {
106                 item.close();
107             }
108         });
109     }
110
111     public List JavaDoc<ProjectFileItem> openedFiles = new ArrayList<ProjectFileItem>();
112
113     public void reopen() {
114         openedFiles.clear();
115
116         runClosureOnFileEditorItems(new FileEditorItemClosure() {
117             public void process(ProjectFileItem item) {
118                 if(item.isOpened())
119                     ProjectExplorer.this.openedFiles.add(item);
120             }
121         });
122
123         if(openedFiles.isEmpty())
124             return;
125         
126         // Sort the project file item by tab index
127
ProjectFileItem items[] = new ProjectFileItem[openedFiles.size()];
128         for (Iterator<ProjectFileItem> iterator = openedFiles.iterator(); iterator.hasNext();) {
129             ProjectFileItem item = iterator.next();
130             items[item.getTabIndex()] = item;
131         }
132
133         // Open them
134
for (int i = 0; i < items.length; i++) {
135             project.openFileItem(items[i]);
136         }
137     }
138
139     public void reload() {
140         loader.reload();
141
142         List JavaDoc expanded = getExpandedItems();
143         int rows[] = filesTree.getSelectionRows();
144
145         filesTreeRootNode.removeAllChildren();
146
147         for (Iterator groupIterator = loader.getGroups().iterator(); groupIterator.hasNext();) {
148             String JavaDoc groupName = (String JavaDoc) groupIterator.next();
149
150             DefaultMutableTreeNode JavaDoc groupNode = new DefaultMutableTreeNode JavaDoc(groupName);
151             filesTreeRootNode.add(groupNode);
152             for (Iterator fileItemIterator = loader.getFiles(groupName).iterator(); fileItemIterator.hasNext();) {
153                 ProjectFileItem item = (ProjectFileItem) fileItemIterator.next();
154                 groupNode.add(new DefaultMutableTreeNode JavaDoc(item));
155             }
156             filesTree.expandPath(new TreePath JavaDoc(groupNode.getPath()));
157         }
158
159         filesTreeModel.reload();
160
161         expandItems(expanded);
162         filesTree.setSelectionRows(rows);
163     }
164
165     public void saveAll() {
166         runClosureOnFileEditorItems(new FileEditorItemClosure() {
167             public void process(ProjectFileItem item) {
168                 if(item.save()) {
169                     // Reset modification date in the build list
170
project.getBuildList().resetModificationDate(item);
171                 }
172             }
173         });
174     }
175
176     public void setIgnoreFromBuild(ProjectFileItem item, boolean ignore) {
177         project.getBuildList().setIgnoreBuild(item, !ignore);
178         filesTree.repaint();
179     }
180
181     public void windowActivated() {
182         reload();
183
184         runClosureOnFileEditorItems(new FileEditorItemClosure() {
185             public void process(ProjectFileItem item) {
186                 if(item.handleExternalModification())
187                     project.changeDone();
188                 item.windowActivated();
189             }
190         });
191     }
192
193     public void expandItems(List JavaDoc items) {
194         if(items == null || items.isEmpty())
195             return;
196
197         for (Iterator iterator = items.iterator(); iterator.hasNext();) {
198             String JavaDoc name = (String JavaDoc) iterator.next();
199             for (int i = 0; i < filesTreeRootNode.getChildCount(); i++) {
200                 DefaultMutableTreeNode JavaDoc child = (DefaultMutableTreeNode JavaDoc)filesTreeRootNode.getChildAt(i);
201                 if(child.getUserObject().equals(name)) {
202                     filesTree.expandPath(new TreePath JavaDoc(child.getPath()));
203                 }
204             }
205         }
206     }
207
208     public List JavaDoc getExpandedItems() {
209         List JavaDoc expanded = new ArrayList();
210         for (int i = 0; i < filesTreeRootNode.getChildCount(); i++) {
211             DefaultMutableTreeNode JavaDoc child = (DefaultMutableTreeNode JavaDoc)filesTreeRootNode.getChildAt(i);
212             if(filesTree.isExpanded(new TreePath JavaDoc(child.getPath()))) {
213                 expanded.add(child.getUserObject());
214             }
215         }
216         return expanded;
217     }
218
219     public static final String JavaDoc KEY_FILE_ITEMS = "KEY_FILE_ITEMS";
220     public static final String JavaDoc KEY_EXPANDED_ITEMS = "KEY_EXPANDED_ITEMS";
221
222     public void setPersistentData(Map data) {
223         reload();
224
225         if(data != null) {
226             expandItems((List JavaDoc) data.get(KEY_EXPANDED_ITEMS));
227
228             Map fileItems = (Map) data.get(KEY_FILE_ITEMS);
229             if(fileItems != null) {
230                 for (Iterator iterator = fileItems.keySet().iterator(); iterator.hasNext();) {
231                     String JavaDoc fileName = (String JavaDoc)iterator.next();
232                     ProjectFileItem item = loader.getFileItemForFileName(fileName);
233                     if(item != null) {
234                         // Only apply data to existing files
235
item.setPersistentData((Map) fileItems.get(fileName));
236                     }
237                 }
238             }
239         }
240
241         reopen();
242     }
243
244     public Map getPersistentData() {
245         Map data = new HashMap();
246
247         data.put(KEY_EXPANDED_ITEMS, getExpandedItems());
248
249         Map fileItems = new HashMap();
250         for (Iterator iterator = getFileEditorItems().iterator(); iterator.hasNext();) {
251             ProjectFileItem item = (ProjectFileItem) iterator.next();
252             fileItems.put(item.getFileName(), item.getPersistentData());
253         }
254         data.put(KEY_FILE_ITEMS, fileItems);
255
256         return data;
257     }
258
259     public interface FileEditorItemClosure {
260         public void process(ProjectFileItem item);
261     }
262
263     public void runClosureOnFileEditorItems(FileEditorItemClosure closure) {
264         for (Iterator iterator = loader.getAllFiles().iterator(); iterator.hasNext();) {
265             ProjectFileItem item = (ProjectFileItem) iterator.next();
266             closure.process(item);
267         }
268     }
269
270     protected class FilesTreeSelectionListener implements TreeSelectionListener JavaDoc {
271         public void valueChanged(TreeSelectionEvent JavaDoc e) {
272         }
273     }
274
275     protected class FilesTreeMouseListener extends MouseAdapter JavaDoc {
276
277         public void mouseClicked(MouseEvent JavaDoc e) {
278             if(e.getClickCount() == 2) {
279                 project.openFileItem(getFileItemAtLocation(e.getX(), e.getY()));
280             }
281         }
282
283         public void displayPopUp(MouseEvent JavaDoc me) {
284             if(!me.isPopupTrigger())
285                 return;
286
287             ProjectFileItem fileItem = getFileItemAtLocation(me.getX(), me.getY());
288             if(fileItem == null)
289                 return;
290
291             filesTree.modifySelectionIfNecessary(me);
292
293             String JavaDoc title;
294             boolean ignore = project.getBuildList().isIgnoreBuild(fileItem);
295             if(ignore)
296                 title = "Add to build list";
297             else
298                 title = "Remove from build list";
299
300             JMenuItem item = new JMenuItem(title);
301             item.addActionListener(new FileContextualMenu(ignore));
302
303             JPopupMenu popup = new JPopupMenu();
304             popup.add(item);
305             popup.show(me.getComponent(), me.getX(), me.getY());
306         }
307
308         public void mousePressed(MouseEvent JavaDoc event) {
309             displayPopUp(event);
310         }
311
312         public void mouseReleased(MouseEvent JavaDoc event) {
313             displayPopUp(event);
314         }
315
316         public ProjectFileItem getFileItemAtLocation(int x, int y) {
317             if(filesTree.getRowForLocation(x, y) == -1)
318                 return null;
319
320             TreePath JavaDoc p = filesTree.getPathForLocation(x, y);
321             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)p.getLastPathComponent();
322             Object JavaDoc userObject = node.getUserObject();
323             if(userObject instanceof ProjectFileItem)
324                 return (ProjectFileItem)userObject;
325             else
326                 return null;
327         }
328
329
330     }
331
332     protected class FileContextualMenu implements ActionListener JavaDoc {
333
334         public boolean ignore;
335
336         public FileContextualMenu(boolean ignore) {
337             this.ignore = ignore;
338         }
339
340         public void actionPerformed(ActionEvent JavaDoc event) {
341             for (int i = 0; i < filesTree.getSelectionPaths().length; i++) {
342                 TreePath JavaDoc treePath = filesTree.getSelectionPaths()[i];
343                 DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) treePath.getLastPathComponent();
344                 if(node.getUserObject() instanceof ProjectFileItem) {
345                     setIgnoreFromBuild((ProjectFileItem)node.getUserObject(), ignore);
346                 }
347             }
348         }
349     }
350
351     public class CustomTableRenderer extends DefaultTreeCellRenderer JavaDoc {
352
353         public Component getTreeCellRendererComponent(
354                 JTree tree,
355                 Object JavaDoc value,
356                 boolean sel,
357                 boolean expanded,
358                 boolean leaf,
359                 int row,
360                 boolean hasFocus)
361         {
362             Component r = super.getTreeCellRendererComponent(
363                     tree, value, sel,
364                     expanded, leaf, row,
365                     hasFocus);
366
367             setToolTipText("");
368
369             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc)value;
370             if(node.getUserObject() instanceof ProjectFileItem) {
371                 ProjectFileItem item = (ProjectFileItem)node.getUserObject();
372                 ProjectBuildList.BuildFile f = project.getBuildList().getBuildFile(item);
373                 if(f != null && f.isIgnore())
374                     setForeground(Color.gray);
375                 else
376                     setForeground(Color.black);
377             } else if(node.getUserObject() instanceof String JavaDoc) {
378                 // Do not display the default folder for group because
379
// they are not folders ;-)
380
setText(ProjectFileItem.getFileTypeName(node.getUserObject().toString()));
381                 setIcon(null);
382             }
383
384             return r;
385         }
386     }
387
388 }
389
Popular Tags