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 ; 8 import javax.swing.event.TreeSelectionListener ; 9 import javax.swing.tree.DefaultMutableTreeNode ; 10 import javax.swing.tree.DefaultTreeCellRenderer ; 11 import javax.swing.tree.DefaultTreeModel ; 12 import javax.swing.tree.TreePath ; 13 import java.awt.*; 14 import java.awt.event.ActionEvent ; 15 import java.awt.event.ActionListener ; 16 import java.awt.event.MouseAdapter ; 17 import java.awt.event.MouseEvent ; 18 import java.util.*; 19 import java.util.List ; 20 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 filesTreeRootNode; 60 protected DefaultTreeModel 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 filesTree.setToolTipText(""); 76 filesTree.setDragEnabled(true); 77 filesTree.setRootVisible(false); 78 filesTree.setShowsRootHandles(true); 79 filesTree.setCellRenderer(new CustomTableRenderer()); 81 82 filesTreeRootNode = new DefaultMutableTreeNode (); 83 filesTreeModel = new DefaultTreeModel (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 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 <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 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 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 expanded = getExpandedItems(); 143 int rows[] = filesTree.getSelectionRows(); 144 145 filesTreeRootNode.removeAllChildren(); 146 147 for (Iterator groupIterator = loader.getGroups().iterator(); groupIterator.hasNext();) { 148 String groupName = (String ) groupIterator.next(); 149 150 DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode (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 (item)); 155 } 156 filesTree.expandPath(new TreePath (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 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 items) { 194 if(items == null || items.isEmpty()) 195 return; 196 197 for (Iterator iterator = items.iterator(); iterator.hasNext();) { 198 String name = (String ) iterator.next(); 199 for (int i = 0; i < filesTreeRootNode.getChildCount(); i++) { 200 DefaultMutableTreeNode child = (DefaultMutableTreeNode )filesTreeRootNode.getChildAt(i); 201 if(child.getUserObject().equals(name)) { 202 filesTree.expandPath(new TreePath (child.getPath())); 203 } 204 } 205 } 206 } 207 208 public List getExpandedItems() { 209 List expanded = new ArrayList(); 210 for (int i = 0; i < filesTreeRootNode.getChildCount(); i++) { 211 DefaultMutableTreeNode child = (DefaultMutableTreeNode )filesTreeRootNode.getChildAt(i); 212 if(filesTree.isExpanded(new TreePath (child.getPath()))) { 213 expanded.add(child.getUserObject()); 214 } 215 } 216 return expanded; 217 } 218 219 public static final String KEY_FILE_ITEMS = "KEY_FILE_ITEMS"; 220 public static final String KEY_EXPANDED_ITEMS = "KEY_EXPANDED_ITEMS"; 221 222 public void setPersistentData(Map data) { 223 reload(); 224 225 if(data != null) { 226 expandItems((List ) 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 fileName = (String )iterator.next(); 232 ProjectFileItem item = loader.getFileItemForFileName(fileName); 233 if(item != null) { 234 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 { 271 public void valueChanged(TreeSelectionEvent e) { 272 } 273 } 274 275 protected class FilesTreeMouseListener extends MouseAdapter { 276 277 public void mouseClicked(MouseEvent e) { 278 if(e.getClickCount() == 2) { 279 project.openFileItem(getFileItemAtLocation(e.getX(), e.getY())); 280 } 281 } 282 283 public void displayPopUp(MouseEvent 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 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 event) { 309 displayPopUp(event); 310 } 311 312 public void mouseReleased(MouseEvent 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 p = filesTree.getPathForLocation(x, y); 321 DefaultMutableTreeNode node = (DefaultMutableTreeNode )p.getLastPathComponent(); 322 Object 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 { 333 334 public boolean ignore; 335 336 public FileContextualMenu(boolean ignore) { 337 this.ignore = ignore; 338 } 339 340 public void actionPerformed(ActionEvent event) { 341 for (int i = 0; i < filesTree.getSelectionPaths().length; i++) { 342 TreePath treePath = filesTree.getSelectionPaths()[i]; 343 DefaultMutableTreeNode node = (DefaultMutableTreeNode ) 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 { 352 353 public Component getTreeCellRendererComponent( 354 JTree tree, 355 Object 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 node = (DefaultMutableTreeNode )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 ) { 378 setText(ProjectFileItem.getFileTypeName(node.getUserObject().toString())); 381 setIcon(null); 382 } 383 384 return r; 385 } 386 } 387 388 } 389 | Popular Tags |