PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/jedit/browser/BrowserView.java

#
Java | 784 lines | 587 code | 100 blank | 97 comment | 112 complexity | 9aabe6b1a74792d1183b6a3e7595e11e MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * BrowserView.java
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.browser;
  23. //{{{ Imports
  24. import javax.swing.border.EmptyBorder;
  25. import javax.swing.event.*;
  26. import javax.swing.tree.*;
  27. import javax.swing.*;
  28. import java.awt.event.*;
  29. import java.awt.*;
  30. import java.io.File;
  31. import java.util.Enumeration;
  32. import java.util.Hashtable;
  33. import java.util.Vector;
  34. import org.gjt.sp.jedit.io.*;
  35. import org.gjt.sp.jedit.*;
  36. //}}}
  37. /**
  38. * VFS browser tree view.
  39. * @author Slava Pestov
  40. * @version $Id: BrowserView.java 3936 2001-12-21 07:02:14Z spestov $
  41. */
  42. public class BrowserView extends JPanel
  43. {
  44. //{{{ BrowserView constructor
  45. public BrowserView(VFSBrowser browser)
  46. {
  47. this.browser = browser;
  48. parentModel = new DefaultListModel();
  49. parentDirectories = new JList(parentModel);
  50. parentDirectories.getSelectionModel().setSelectionMode(
  51. TreeSelectionModel.SINGLE_TREE_SELECTION);
  52. parentDirectories.setCellRenderer(new ParentDirectoryRenderer());
  53. parentDirectories.setVisibleRowCount(5);
  54. parentDirectories.addMouseListener(new MouseHandler());
  55. rootNode = new DefaultMutableTreeNode(null,true);
  56. model = new DefaultTreeModel(rootNode,true);
  57. tree = new BrowserJTree(model);
  58. tree.setCellRenderer(renderer);
  59. tree.setEditable(false);
  60. tree.addTreeExpansionListener(new TreeHandler());
  61. tree.putClientProperty("JTree.lineStyle", "Angled");
  62. tree.setRootVisible(false);
  63. tree.setShowsRootHandles(true);
  64. tree.setVisibleRowCount(12);
  65. JScrollPane parentScroller = new JScrollPane(parentDirectories);
  66. parentScroller.setMinimumSize(new Dimension(0,0));
  67. JScrollPane treeScroller = new JScrollPane(tree);
  68. treeScroller.setMinimumSize(new Dimension(0,0));
  69. splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  70. parentScroller,treeScroller);
  71. // not null, because then it would be reset to the
  72. // default by updateUI()
  73. splitPane.setBorder(new EmptyBorder(0,0,0,0));
  74. tmpExpanded = new Hashtable();
  75. if(browser.isMultipleSelectionEnabled())
  76. tree.getSelectionModel().setSelectionMode(
  77. TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
  78. else
  79. tree.getSelectionModel().setSelectionMode(
  80. TreeSelectionModel.SINGLE_TREE_SELECTION);
  81. setLayout(new BorderLayout());
  82. add(BorderLayout.CENTER,splitPane);
  83. propertiesChanged();
  84. } //}}}
  85. //{{{ requestDefaultFocus() method
  86. public boolean requestDefaultFocus()
  87. {
  88. tree.requestFocus();
  89. return true;
  90. } //}}}
  91. //{{{ addNotify() method
  92. public void addNotify()
  93. {
  94. super.addNotify();
  95. SwingUtilities.invokeLater(new Runnable()
  96. {
  97. public void run()
  98. {
  99. int loc = jEdit.getIntegerProperty(
  100. "vfs.browser.splitter",0);
  101. if(loc != 0)
  102. {
  103. splitPane.setDividerLocation(loc);
  104. parentDirectories.ensureIndexIsVisible(
  105. parentDirectories.getModel()
  106. .getSize());
  107. }
  108. }
  109. });
  110. } //}}}
  111. //{{{ removeNotify() method
  112. public void removeNotify()
  113. {
  114. jEdit.setIntegerProperty("vfs.browser.splitter",
  115. splitPane.getDividerLocation());
  116. super.removeNotify();
  117. } //}}}
  118. //{{{ getSelectedFiles() method
  119. public VFS.DirectoryEntry[] getSelectedFiles()
  120. {
  121. Vector selected = new Vector(tree.getSelectionCount());
  122. TreePath[] paths = tree.getSelectionPaths();
  123. if(paths == null)
  124. return new VFS.DirectoryEntry[0];
  125. for(int i = 0; i < paths.length; i++)
  126. {
  127. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  128. paths[i].getLastPathComponent();
  129. Object obj = treeNode.getUserObject();
  130. if(obj instanceof VFS.DirectoryEntry)
  131. selected.addElement(obj);
  132. }
  133. VFS.DirectoryEntry[] retVal = new VFS.DirectoryEntry[selected.size()];
  134. selected.copyInto(retVal);
  135. return retVal;
  136. } //}}}
  137. //{{{ selectNone() method
  138. public void selectNone()
  139. {
  140. tree.setSelectionPaths(new TreePath[0]);
  141. } //}}}
  142. //{{{ directoryLoaded() method
  143. public void directoryLoaded(String path, Vector directory)
  144. {
  145. if(currentlyLoadingTreeNode == rootNode)
  146. {
  147. parentModel.removeAllElements();
  148. String parent = path;
  149. for(;;)
  150. {
  151. parentModel.insertElementAt(parent,0);
  152. String newParent = MiscUtilities.getParentOfPath(parent);
  153. if(newParent.length() != 1 && (newParent.endsWith("/")
  154. || newParent.endsWith(File.separator)))
  155. newParent = newParent.substring(0,newParent.length() - 1);
  156. if(newParent == null || parent.equals(newParent))
  157. break;
  158. else
  159. parent = newParent;
  160. }
  161. int index = parentModel.getSize() - 1;
  162. parentDirectories.setSelectedIndex(index);
  163. parentDirectories.ensureIndexIsVisible(parentModel.getSize() - 1);
  164. }
  165. currentlyLoadingTreeNode.removeAllChildren();
  166. Vector toExpand = new Vector();
  167. if(directory != null)
  168. {
  169. for(int i = 0; i < directory.size(); i++)
  170. {
  171. VFS.DirectoryEntry file = (VFS.DirectoryEntry)
  172. directory.elementAt(i);
  173. boolean allowsChildren = (file.type != VFS.DirectoryEntry.FILE);
  174. DefaultMutableTreeNode node = new DefaultMutableTreeNode(file,allowsChildren);
  175. currentlyLoadingTreeNode.add(node);
  176. if(tmpExpanded.get(file.path) != null)
  177. toExpand.addElement(new TreePath(node.getPath()));
  178. }
  179. }
  180. tmpExpanded.clear();
  181. // fire events
  182. model.reload(currentlyLoadingTreeNode);
  183. tree.expandPath(new TreePath(currentlyLoadingTreeNode.getPath()));
  184. // expand branches that were expanded before
  185. for(int i = 0; i < toExpand.size(); i++)
  186. {
  187. TreePath treePath = (TreePath)toExpand.elementAt(i);
  188. tree.expandPath(treePath);
  189. }
  190. timer.stop();
  191. typeSelectBuffer.setLength(0);
  192. } //}}}
  193. //{{{ updateFileView() method
  194. public void updateFileView()
  195. {
  196. tree.repaint();
  197. } //}}}
  198. //{{{ loadDirectory() method
  199. public void loadDirectory(String path)
  200. {
  201. loadDirectory(rootNode,path,false);
  202. } //}}}
  203. //{{{ maybeReloadDirectory() method
  204. public void maybeReloadDirectory(String path)
  205. {
  206. // because this method is called for *every* VFS update,
  207. // we don't want to scan the tree all the time. So we
  208. // use the following algorithm to determine if the path
  209. // might be part of the tree:
  210. // - if the path starts with the browser's current directory,
  211. // we do the tree scan
  212. // - if the browser's directory is 'favorites:' -- we have to
  213. // do the tree scan, as every path can appear under the
  214. // favorites list
  215. // - if the browser's directory is 'roots:' and path is on
  216. // the local filesystem, do a tree scan
  217. String browserDir = browser.getDirectory();
  218. if(browserDir.startsWith(FavoritesVFS.PROTOCOL))
  219. maybeReloadDirectory(rootNode,path);
  220. else if(browserDir.startsWith(FileRootsVFS.PROTOCOL))
  221. {
  222. if(!MiscUtilities.isURL(path) || MiscUtilities.getProtocolOfURL(path)
  223. .equals("file"))
  224. maybeReloadDirectory(rootNode,path);
  225. }
  226. else if(path.startsWith(browserDir))
  227. maybeReloadDirectory(rootNode,path);
  228. } //}}}
  229. //{{{ getDefaultFocusComponent() method
  230. public Component getDefaultFocusComponent()
  231. {
  232. return tree;
  233. } //}}}
  234. //{{{ propertiesChanged() method
  235. public void propertiesChanged()
  236. {
  237. showIcons = jEdit.getBooleanProperty("vfs.browser.showIcons");
  238. renderer.propertiesChanged();
  239. tree.setRowHeight(renderer.getTreeCellRendererComponent(
  240. tree,new DefaultMutableTreeNode("foo"),
  241. false,false,false,0,false).getSize().height);
  242. splitPane.setBorder(null);
  243. } //}}}
  244. //{{{ Private members
  245. //{{{ Instance variables
  246. private VFSBrowser browser;
  247. private JSplitPane splitPane;
  248. private JList parentDirectories;
  249. private DefaultListModel parentModel;
  250. private JTree tree;
  251. private Hashtable tmpExpanded;
  252. private DefaultTreeModel model;
  253. private DefaultMutableTreeNode rootNode;
  254. private DefaultMutableTreeNode currentlyLoadingTreeNode;
  255. private BrowserCommandsMenu popup;
  256. private boolean showIcons;
  257. private FileCellRenderer renderer = new FileCellRenderer();
  258. private StringBuffer typeSelectBuffer = new StringBuffer();
  259. private Timer timer = new Timer(0,new ClearTypeSelect());
  260. //}}}
  261. //{{{ maybeReloadDirectory() method
  262. private boolean maybeReloadDirectory(DefaultMutableTreeNode node, String path)
  263. {
  264. // nodes which are not expanded need not be checked
  265. if(!tree.isExpanded(new TreePath(node.getPath())))
  266. return false;
  267. if(node == rootNode && path.equals(browser.getDirectory()))
  268. {
  269. loadDirectory(rootNode,path,false);
  270. return true;
  271. }
  272. Object userObject = node.getUserObject();
  273. if(userObject instanceof VFS.DirectoryEntry)
  274. {
  275. VFS.DirectoryEntry file = (VFS.DirectoryEntry)userObject;
  276. // we don't need to do anything with files!
  277. if(file.type == VFS.DirectoryEntry.FILE)
  278. return false;
  279. if(path.equals(file.path))
  280. {
  281. loadDirectory(node,path,false);
  282. return true;
  283. }
  284. }
  285. if(node.getChildCount() != 0)
  286. {
  287. Enumeration children = node.children();
  288. while(children.hasMoreElements())
  289. {
  290. DefaultMutableTreeNode child = (DefaultMutableTreeNode)
  291. children.nextElement();
  292. if(maybeReloadDirectory(child,path))
  293. return true;
  294. }
  295. }
  296. return false;
  297. } //}}}
  298. //{{{ loadDirectory() method
  299. private void loadDirectory(DefaultMutableTreeNode node, String path,
  300. boolean showLoading)
  301. {
  302. currentlyLoadingTreeNode = node;
  303. if(node == rootNode)
  304. {
  305. parentModel.removeAllElements();
  306. parentModel.addElement(new LoadingPlaceholder());
  307. }
  308. if(showLoading)
  309. {
  310. node.removeAllChildren();
  311. node.add(new DefaultMutableTreeNode(new LoadingPlaceholder(),false));
  312. model.reload(currentlyLoadingTreeNode);
  313. }
  314. tmpExpanded.clear();
  315. int rowCount = tree.getRowCount();
  316. for(int i = 0; i < rowCount; i++)
  317. {
  318. TreePath treePath = tree.getPathForRow(i);
  319. if(tree.isExpanded(treePath))
  320. {
  321. DefaultMutableTreeNode _node = (DefaultMutableTreeNode)
  322. treePath.getLastPathComponent();
  323. VFS.DirectoryEntry file = ((VFS.DirectoryEntry)
  324. _node.getUserObject());
  325. tmpExpanded.put(file.path,file.path);
  326. }
  327. }
  328. browser.loadDirectory(path,node == rootNode);
  329. } //}}}
  330. //{{{ showFilePopup() method
  331. private void showFilePopup(VFS.DirectoryEntry file, Point point)
  332. {
  333. popup = new BrowserCommandsMenu(browser,file);
  334. GUIUtilities.showPopupMenu(popup,tree,point.x+1,point.y+1);
  335. } //}}}
  336. //}}}
  337. //{{{ Inner classes
  338. //{{{ ClearTypeSelect
  339. class ClearTypeSelect implements ActionListener
  340. {
  341. public void actionPerformed(ActionEvent evt)
  342. {
  343. typeSelectBuffer.setLength(0);
  344. browser.filesSelected();
  345. }
  346. } //}}}
  347. //{{{ ParentDirectoryRenderer class
  348. class ParentDirectoryRenderer extends DefaultListCellRenderer
  349. {
  350. Font plainFont, boldFont;
  351. ParentDirectoryRenderer()
  352. {
  353. plainFont = UIManager.getFont("Tree.font");
  354. boldFont = new Font(plainFont.getName(),Font.BOLD,plainFont.getSize());
  355. }
  356. public Component getListCellRendererComponent(
  357. JList list,
  358. Object value,
  359. int index,
  360. boolean isSelected,
  361. boolean cellHasFocus)
  362. {
  363. super.getListCellRendererComponent(list,value,index,
  364. isSelected,cellHasFocus);
  365. ParentDirectoryRenderer.this.setBorder(new EmptyBorder(
  366. 1,index * 17 + 1,1,1));
  367. if(value instanceof LoadingPlaceholder)
  368. {
  369. ParentDirectoryRenderer.this.setFont(plainFont);
  370. setIcon(showIcons ? FileCellRenderer.loadingIcon : null);
  371. setText(jEdit.getProperty("vfs.browser.tree.loading"));
  372. }
  373. else
  374. {
  375. ParentDirectoryRenderer.this.setFont(boldFont);
  376. setIcon(showIcons ? FileCellRenderer.openDirIcon : null);
  377. setText(MiscUtilities.getFileName(value.toString()));
  378. }
  379. return this;
  380. }
  381. } //}}}
  382. //{{{ MouseHandler class
  383. class MouseHandler extends MouseAdapter
  384. {
  385. public void mouseClicked(MouseEvent evt)
  386. {
  387. // ignore double clicks
  388. if(evt.getClickCount() == 2)
  389. return;
  390. int row = parentDirectories.locationToIndex(evt.getPoint());
  391. if(row != -1)
  392. {
  393. Object obj = parentModel.getElementAt(row);
  394. if(obj instanceof String)
  395. {
  396. browser.setDirectory((String)obj);
  397. requestDefaultFocus();
  398. }
  399. }
  400. }
  401. } //}}}
  402. //{{{ BrowserJTree class
  403. class BrowserJTree extends JTree
  404. {
  405. //{{{ BrowserJTree constructor
  406. BrowserJTree(TreeModel model)
  407. {
  408. super(model);
  409. ToolTipManager.sharedInstance().registerComponent(this);
  410. } //}}}
  411. //{{{ getToolTipText() method
  412. public final String getToolTipText(MouseEvent evt)
  413. {
  414. TreePath path = getPathForLocation(evt.getX(), evt.getY());
  415. if(path != null)
  416. {
  417. Rectangle cellRect = getPathBounds(path);
  418. if(cellRect != null && !cellRectIsVisible(cellRect))
  419. return path.getLastPathComponent().toString();
  420. }
  421. return null;
  422. } //}}}
  423. //{{{ getToolTipLocation() method
  424. public final Point getToolTipLocation(MouseEvent evt)
  425. {
  426. TreePath path = getPathForLocation(evt.getX(), evt.getY());
  427. if(path != null)
  428. {
  429. Rectangle cellRect = getPathBounds(path);
  430. if(cellRect != null && !cellRectIsVisible(cellRect))
  431. {
  432. return new Point(cellRect.x + (showIcons ? 19 : 1),
  433. cellRect.y -1);
  434. }
  435. }
  436. return null;
  437. } //}}}
  438. //{{{ processKeyEvent() method
  439. protected void processKeyEvent(KeyEvent evt)
  440. {
  441. if(evt.getID() == KeyEvent.KEY_PRESSED)
  442. {
  443. switch(evt.getKeyCode())
  444. {
  445. case KeyEvent.VK_ENTER:
  446. browser.filesActivated();
  447. evt.consume();
  448. break;
  449. case KeyEvent.VK_LEFT:
  450. String directory = browser.getDirectory();
  451. browser.setDirectory(MiscUtilities
  452. .getParentOfPath(directory));
  453. evt.consume();
  454. break;
  455. }
  456. }
  457. else if(evt.getID() == KeyEvent.KEY_TYPED)
  458. {
  459. switch(evt.getKeyChar())
  460. {
  461. case '~':
  462. browser.setDirectory(System.getProperty("user.home"));
  463. break;
  464. case '/':
  465. browser.setDirectory("roots:");
  466. break;
  467. case '-':
  468. View view = browser.getView();
  469. Buffer buffer = view.getBuffer();
  470. browser.setDirectory(MiscUtilities.getParentOfPath(
  471. buffer.getPath()));
  472. break;
  473. default:
  474. typeSelectBuffer.append(evt.getKeyChar());
  475. doTypeSelect(typeSelectBuffer.toString());
  476. timer.stop();
  477. timer.setInitialDelay(750);
  478. timer.setRepeats(false);
  479. timer.start();
  480. break;
  481. }
  482. }
  483. if(!evt.isConsumed())
  484. super.processKeyEvent(evt);
  485. } //}}}
  486. //{{{ processMouseEvent() method
  487. protected void processMouseEvent(MouseEvent evt)
  488. {
  489. ToolTipManager ttm = ToolTipManager.sharedInstance();
  490. switch(evt.getID())
  491. {
  492. //{{{ MOUSE_ENTERED...
  493. case MouseEvent.MOUSE_ENTERED:
  494. toolTipInitialDelay = ttm.getInitialDelay();
  495. toolTipReshowDelay = ttm.getReshowDelay();
  496. ttm.setInitialDelay(200);
  497. ttm.setReshowDelay(0);
  498. super.processMouseEvent(evt);
  499. break; //}}}
  500. //{{{ MOUSE_EXITED...
  501. case MouseEvent.MOUSE_EXITED:
  502. ttm.setInitialDelay(toolTipInitialDelay);
  503. ttm.setReshowDelay(toolTipReshowDelay);
  504. super.processMouseEvent(evt);
  505. break; //}}}
  506. //{{{ MOUSE_CLICKED...
  507. case MouseEvent.MOUSE_CLICKED:
  508. if((evt.getModifiers() & MouseEvent.BUTTON2_MASK) != 0)
  509. {
  510. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  511. if(path == null)
  512. {
  513. super.processMouseEvent(evt);
  514. break;
  515. }
  516. if(!isPathSelected(path))
  517. setSelectionPath(path);
  518. browser.filesActivated();
  519. break;
  520. }
  521. else if((evt.getModifiers() & MouseEvent.BUTTON1_MASK) != 0)
  522. {
  523. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  524. if(path == null)
  525. {
  526. super.processMouseEvent(evt);
  527. break;
  528. }
  529. if(!isPathSelected(path))
  530. setSelectionPath(path);
  531. if(evt.getClickCount() == 1)
  532. {
  533. browser.filesSelected();
  534. super.processMouseEvent(evt);
  535. }
  536. if(evt.getClickCount() == 2)
  537. {
  538. // don't pass double-clicks to tree, otherwise
  539. // directory nodes will be expanded and we don't
  540. // want that
  541. browser.filesActivated();
  542. break;
  543. }
  544. }
  545. else if(GUIUtilities.isPopupTrigger(evt))
  546. ; // do nothing
  547. super.processMouseEvent(evt);
  548. break; //}}}
  549. //{{{ MOUSE_PRESSED...
  550. case MouseEvent.MOUSE_PRESSED:
  551. if((evt.getModifiers() & MouseEvent.BUTTON1_MASK) != 0)
  552. {
  553. if(popup != null && popup.isVisible())
  554. popup.setVisible(false);
  555. if(evt.getClickCount() == 2)
  556. break;
  557. }
  558. else if(GUIUtilities.isPopupTrigger(evt))
  559. {
  560. if(popup != null && popup.isVisible())
  561. {
  562. popup.setVisible(false);
  563. break;
  564. }
  565. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  566. if(path == null)
  567. showFilePopup(null,evt.getPoint());
  568. else
  569. {
  570. setSelectionPath(path);
  571. browser.filesSelected();
  572. Object userObject = ((DefaultMutableTreeNode)path
  573. .getLastPathComponent()).getUserObject();
  574. if(userObject instanceof VFS.DirectoryEntry)
  575. {
  576. VFS.DirectoryEntry file = (VFS.DirectoryEntry)
  577. userObject;
  578. showFilePopup(file,evt.getPoint());
  579. }
  580. else
  581. showFilePopup(null,evt.getPoint());
  582. }
  583. break;
  584. }
  585. super.processMouseEvent(evt);
  586. break; //}}}
  587. //{{{ MOUSE_RELEASED:
  588. case MouseEvent.MOUSE_RELEASED:
  589. if(evt.getClickCount() != 2)
  590. super.processMouseEvent(evt);
  591. break; //}}}
  592. default:
  593. super.processMouseEvent(evt);
  594. break;
  595. }
  596. } //}}}
  597. //{{{ Private members
  598. private int toolTipInitialDelay = -1;
  599. private int toolTipReshowDelay = -1;
  600. //{{{ cellRectIsVisible() method
  601. private boolean cellRectIsVisible(Rectangle cellRect)
  602. {
  603. Rectangle vr = BrowserJTree.this.getVisibleRect();
  604. return vr.contains(cellRect.x,cellRect.y) &&
  605. vr.contains(cellRect.x + cellRect.width,
  606. cellRect.y + cellRect.height);
  607. } //}}}
  608. //{{{ doTypeSelect() method
  609. private void doTypeSelect(String str)
  610. {
  611. if(getSelectionCount() == 0)
  612. doTypeSelect(str,0,getRowCount());
  613. else
  614. {
  615. int start = getMaxSelectionRow();
  616. boolean retVal = doTypeSelect(str,start,getRowCount());
  617. if(!retVal)
  618. {
  619. // scan from selection to end failed, so
  620. // scan from start to selection
  621. doTypeSelect(str,0,start);
  622. }
  623. }
  624. } //}}}
  625. //{{{ doTypeSelect() method
  626. private boolean doTypeSelect(String str, int start, int end)
  627. {
  628. for(int i = start; i < end; i++)
  629. {
  630. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  631. getPathForRow(i).getLastPathComponent();
  632. Object obj = treeNode.getUserObject();
  633. if(obj instanceof VFS.DirectoryEntry)
  634. {
  635. VFS.DirectoryEntry file = (VFS.DirectoryEntry)obj;
  636. if(file.name.regionMatches(true,0,str,0,str.length()))
  637. {
  638. clearSelection();
  639. setSelectionRow(i);
  640. scrollRowToVisible(i);
  641. return true;
  642. }
  643. }
  644. }
  645. return false;
  646. } //}}}
  647. //}}}
  648. } //}}}
  649. //{{{ TreeHandler class
  650. class TreeHandler implements TreeExpansionListener
  651. {
  652. //{{{ treeExpanded() method
  653. public void treeExpanded(TreeExpansionEvent evt)
  654. {
  655. TreePath path = evt.getPath();
  656. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  657. path.getLastPathComponent();
  658. Object userObject = treeNode.getUserObject();
  659. if(userObject instanceof VFS.DirectoryEntry)
  660. {
  661. loadDirectory(treeNode,((VFS.DirectoryEntry)
  662. userObject).path,true);
  663. }
  664. } //}}}
  665. //{{{ treeCollapsed() method
  666. public void treeCollapsed(TreeExpansionEvent evt)
  667. {
  668. TreePath path = evt.getPath();
  669. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  670. path.getLastPathComponent();
  671. if(treeNode.getUserObject() instanceof VFS.DirectoryEntry)
  672. {
  673. // we add the placeholder so that the node has
  674. // 1 child (otherwise the user won't be able to
  675. // expand it again)
  676. treeNode.removeAllChildren();
  677. treeNode.add(new DefaultMutableTreeNode(new LoadingPlaceholder(),false));
  678. model.reload(treeNode);
  679. }
  680. } //}}}
  681. } //}}}
  682. static class LoadingPlaceholder {}
  683. //}}}
  684. }