1 21 22 package org.armedbear.j; 23 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import java.awt.Graphics ; 27 import java.awt.Point ; 28 import java.awt.event.InputEvent ; 29 import java.awt.event.KeyEvent ; 30 import java.awt.event.KeyListener ; 31 import java.awt.event.MouseEvent ; 32 import java.awt.event.MouseListener ; 33 import java.awt.event.MouseMotionListener ; 34 import javax.swing.JTree ; 35 import javax.swing.SwingUtilities ; 36 import javax.swing.event.TreeExpansionEvent ; 37 import javax.swing.event.TreeExpansionListener ; 38 import javax.swing.event.TreeSelectionEvent ; 39 import javax.swing.event.TreeSelectionListener ; 40 import javax.swing.tree.DefaultMutableTreeNode ; 41 import javax.swing.tree.DefaultTreeCellRenderer ; 42 import javax.swing.tree.TreeModel ; 43 import javax.swing.tree.TreePath ; 44 import javax.swing.tree.TreeSelectionModel ; 45 46 public final class DirectoryTree extends SidebarTree implements NavigationComponent, 47 TreeSelectionListener , TreeExpansionListener , MouseListener , 48 MouseMotionListener , KeyListener 49 { 50 private Editor editor; 51 private DirectoryTreeModel treeModel; 52 53 private DirectoryTree(Editor editor, TreeModel model) 54 { 55 super(model); 56 this.editor = editor; 57 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 58 setScrollsOnExpand(false); 59 addTreeSelectionListener(this); 60 addTreeExpansionListener(this); 61 addMouseListener(this); 62 addMouseMotionListener(this); 63 addKeyListener(this); 64 setCellRenderer(new DirectoryTreeCellRenderer(this)); 65 } 66 67 public static DirectoryTree getDirectoryTree(Editor editor) 68 { 69 if (editor.getCurrentDirectory().isLocal()) { 70 if (editor.localDirectoryTree == null) 71 editor.localDirectoryTree = new DirectoryTree(editor, null); 72 return editor.localDirectoryTree; 73 } 74 return new DirectoryTree(editor, null); 75 } 76 77 public final String getLabelText() 78 { 79 return editor.getBuffer().getFile().getName(); 80 } 81 82 public DirectoryTreeModel getTreeModel() 83 { 84 return treeModel; 85 } 86 87 public Editor getEditor() 88 { 89 return editor; 90 } 91 92 public void refresh() 93 { 94 if (!SwingUtilities.isEventDispatchThread()) 95 Debug.bug("DirectoryTree.refresh() called from background thread!"); 96 Runnable refreshRunnable = new Runnable () { 97 public void run() 98 { 99 File file = editor.getBuffer().getFile(); 100 if (file == null) 101 return; 102 if (treeModel == null) { 103 treeModel = DirectoryTreeModel.getTreeModel(file); 104 if (treeModel != null) { 105 final DefaultMutableTreeNode node = getNode(file); 106 Runnable completionRunnable = new Runnable () { 107 public void run() 108 { 109 setModel(treeModel); 110 if (node != null) 111 scrollNodeToCenter(node); 112 } 113 }; 114 SwingUtilities.invokeLater(completionRunnable); 115 } 116 } else { 117 DefaultMutableTreeNode selectedNode = null; 118 TreePath path = getSelectionPath(); 119 if (path != null) { 120 selectedNode = 121 (DefaultMutableTreeNode ) path.getLastPathComponent(); 122 } 123 final DefaultMutableTreeNode node = getNode(file); 124 if (node != null && node != selectedNode) { 125 Runnable completionRunnable = new Runnable () { 126 public void run() 127 { 128 scrollNodeToCenter(node); 129 } 130 }; 131 SwingUtilities.invokeLater(completionRunnable); 132 } 133 } 134 } 135 }; 136 new Thread (refreshRunnable).start(); 137 } 138 139 private void expandNode(DefaultMutableTreeNode node) 140 { 141 DirectoryTreeElement treeElement = 142 (DirectoryTreeElement) node.getUserObject(); 143 File file = treeElement.getFile(); 144 expandNode(node, file); 145 } 146 147 private void expandNode(DefaultMutableTreeNode node, File file) 148 { 149 treeModel.expandNode(node, file); 150 } 151 152 private DefaultMutableTreeNode getNode(File file) 153 { 154 if (treeModel == null || file == null) 155 return null; 156 return treeModel.getNode(file); 157 } 158 159 public void updatePosition() 160 { 161 int limit = getRowCount(); 162 int rowToBeSelected = -1; 163 String path = editor.getBuffer().getFile().canonicalPath(); 164 for (int row = 0; row < limit; row++) { 165 TreePath treepath = getPathForRow(row); 166 if (treepath != null) { 167 DefaultMutableTreeNode node = 168 (DefaultMutableTreeNode ) treepath.getLastPathComponent(); 169 if (node != null) { 170 if (node.getUserObject() instanceof DirectoryTreeElement) { 172 DirectoryTreeElement treeElement = 173 (DirectoryTreeElement) node.getUserObject(); 174 if (path.equals(treeElement.getPath())) { 175 rowToBeSelected = row; 176 break; 177 } 178 } 179 } 180 } 181 } 182 if (rowToBeSelected >= 0) { 183 int[] selectedRows = getSelectionRows(); 184 if (selectedRows != null && selectedRows.length == 1 && 185 selectedRows[0] == rowToBeSelected) 186 ; else { 188 setSelectionRow(rowToBeSelected); 189 scrollRowToCenter(rowToBeSelected); 190 } 191 } else 192 clearSelection(); 193 } 194 195 public void valueChanged(TreeSelectionEvent e) {} 196 197 public void treeCollapsed(TreeExpansionEvent e) {} 198 199 public void treeExpanded(TreeExpansionEvent e) {} 200 201 public void keyPressed(KeyEvent e) 202 { 203 int keyCode = e.getKeyCode(); 204 int modifiers = e.getModifiers(); 205 206 switch (keyCode) { 207 case KeyEvent.VK_SHIFT: 209 case KeyEvent.VK_CONTROL: 210 case KeyEvent.VK_ALT: 211 case KeyEvent.VK_META: 212 return; 213 214 case KeyEvent.VK_ENTER: { 215 e.consume(); 216 TreePath path = getSelectionPath(); 217 if (path != null) { 218 DefaultMutableTreeNode node = 219 (DefaultMutableTreeNode ) path.getLastPathComponent(); 220 if (node.getUserObject() instanceof DirectoryTreeElement) { 221 DirectoryTreeElement treeElement = 222 (DirectoryTreeElement) node.getUserObject(); 223 File file = treeElement.getFile(); 224 editor.setWaitCursor(); 225 expandNode(node, file); 226 editor.setDefaultCursor(); 227 if (e.getModifiers() == InputEvent.BUTTON2_MASK) 228 editor.setFocusToDisplay(); 229 repaint(); 230 ((Directory)editor.getBuffer()).changeDirectory(file); 231 editor.updateDisplay(); 232 } 233 } 234 editor.setFocusToDisplay(); 235 if (modifiers == KeyEvent.ALT_MASK) 236 editor.toggleSidebar(); 237 return; 238 } 239 240 case KeyEvent.VK_TAB: 241 e.consume(); 242 if (modifiers == 0) { 243 if (editor.getSidebar().getBufferList() != null) 244 editor.setFocus(editor.getSidebar().getBufferList()); 245 } 246 return; 247 248 case KeyEvent.VK_ESCAPE: 249 e.consume(); 250 editor.getSidebar().setBuffer(); 251 editor.getSidebar().updatePosition(); 252 editor.setFocusToDisplay(); 253 return; 254 } 255 256 editor.getDispatcher().setEnabled(false); 257 } 258 259 public void keyReleased(KeyEvent e) 260 { 261 e.consume(); 262 editor.getDispatcher().setEnabled(true); 263 } 264 265 public void keyTyped(KeyEvent e) 266 { 267 e.consume(); 268 } 269 270 private boolean ignoreMouseClicked; 271 272 public void mousePressed(MouseEvent e) 273 { 274 ignoreMouseClicked = false; 275 LocationBar.cancelInput(); 276 editor.ensureActive(); 277 int modifiers = e.getModifiers(); 278 if (modifiers == InputEvent.BUTTON1_MASK || 279 modifiers == InputEvent.BUTTON2_MASK) { 280 Point point = e.getPoint(); 281 if (e.getModifiers() == InputEvent.BUTTON2_MASK) { 282 int row = getRowForLocation(point.x, point.y); 283 setSelectionRow(row); 284 } 285 editor.setFocus(this); 286 TreePath treepath = getPathForLocation(point.x, point.y); 287 if (treepath == null) { 288 ignoreMouseClicked = true; 289 e.consume(); 290 } 291 } else 292 editor.setFocusToDisplay(); 293 } 294 295 public void mouseReleased(MouseEvent e) {} 296 297 public void mouseClicked(MouseEvent e) 298 { 299 if (ignoreMouseClicked) { 300 e.consume(); 301 editor.setFocusToDisplay(); 302 return; 303 } 304 final int modifiers = e.getModifiers(); 305 if (modifiers != InputEvent.BUTTON1_MASK && 306 modifiers != InputEvent.BUTTON2_MASK) { 307 e.consume(); 308 editor.setFocusToDisplay(); 309 return; 310 } 311 Point point = e.getPoint(); 312 TreePath treepath = getPathForLocation(point.x, point.y); 313 if (treepath != null) { 314 DefaultMutableTreeNode node = 315 (DefaultMutableTreeNode ) treepath.getLastPathComponent(); 316 DirectoryTreeElement treeElement = 317 (DirectoryTreeElement) node.getUserObject(); 318 File file = treeElement.getFile(); 319 editor.setWaitCursor(); 320 expandNode(node, file); 321 expandPath(treepath); 322 editor.setDefaultCursor(); 323 if (modifiers == InputEvent.BUTTON1_MASK || 324 modifiers == InputEvent.BUTTON2_MASK) 325 editor.setFocusToDisplay(); 326 repaint(); 327 ((Directory)editor.getBuffer()).changeDirectory(file); 328 editor.updateDisplay(); 329 } 330 } 331 332 public void mouseMoved(MouseEvent e) {} 333 334 public void mouseEntered(MouseEvent e) {} 335 336 public void mouseExited(MouseEvent e) 337 { 338 editor.setFocusToDisplay(); 339 } 340 341 public void mouseDragged(MouseEvent e) {} 342 343 private static class DirectoryTreeCellRenderer extends DefaultTreeCellRenderer 344 { 345 private DirectoryTree tree; 346 private Editor editor; 347 348 private static Color noFocusSelectionBackground = 349 new Color (208, 208, 208); 350 351 private Color oldBackgroundSelectionColor; 352 353 public DirectoryTreeCellRenderer(DirectoryTree tree) 354 { 355 super(); 356 this.tree = tree; 357 editor = tree.getEditor(); 358 oldBackgroundSelectionColor = getBackgroundSelectionColor(); 359 360 setOpenIcon(Utilities.getIconFromFile("dir_open.png")); 361 setClosedIcon(Utilities.getIconFromFile("dir_close.png")); 362 setLeafIcon(Utilities.getIconFromFile("dir_close.png")); 363 } 364 365 public Component getTreeCellRendererComponent( 366 JTree tree, 367 Object value, 368 boolean selected, 369 boolean expanded, 370 boolean leaf, 371 int row, 372 boolean hasFocus) 373 { 374 super.getTreeCellRendererComponent(tree, value, selected, expanded, 375 leaf, row, hasFocus); 376 if (selected) 377 super.setForeground(getTextSelectionColor()); 378 else 379 super.setForeground(getTextNonSelectionColor()); 380 if (editor.getFocusedComponent() == tree) 381 setBackgroundSelectionColor(oldBackgroundSelectionColor); 382 else 383 setBackgroundSelectionColor(noFocusSelectionBackground); 384 return this; 385 } 386 387 public void paintComponent(Graphics g) 388 { 389 Display.setRenderingHints(g); 390 super.paintComponent(g); 391 } 392 } 393 } 394 | Popular Tags |