PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
Java | 784 lines | 588 code | 100 blank | 96 comment | 112 complexity | 1549ee105f7de2915820cd249666d26c 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, 2001, 2002 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 4000 2002-01-30 08:06:41Z spestov $
  41. */
  42. public class BrowserView extends JPanel
  43. {
  44. //{{{ BrowserView constructor
  45. public BrowserView(VFSBrowser browser, boolean splitHorizontally)
  46. {
  47. this.browser = browser;
  48. this.splitHorizontally = splitHorizontally;
  49. parentModel = new DefaultListModel();
  50. parentDirectories = new JList(parentModel);
  51. parentDirectories.getSelectionModel().setSelectionMode(
  52. TreeSelectionModel.SINGLE_TREE_SELECTION);
  53. parentDirectories.setCellRenderer(new ParentDirectoryRenderer());
  54. parentDirectories.setVisibleRowCount(5);
  55. parentDirectories.addMouseListener(new MouseHandler());
  56. rootNode = new DefaultMutableTreeNode(null,true);
  57. model = new DefaultTreeModel(rootNode,true);
  58. tree = new BrowserJTree(model);
  59. tree.setCellRenderer(renderer);
  60. tree.setEditable(false);
  61. tree.addTreeExpansionListener(new TreeHandler());
  62. tree.putClientProperty("JTree.lineStyle", "Angled");
  63. tree.setRootVisible(false);
  64. tree.setShowsRootHandles(true);
  65. tree.setVisibleRowCount(12);
  66. JScrollPane parentScroller = new JScrollPane(parentDirectories);
  67. parentScroller.setMinimumSize(new Dimension(0,0));
  68. JScrollPane treeScroller = new JScrollPane(tree);
  69. treeScroller.setMinimumSize(new Dimension(0,0));
  70. splitPane = new JSplitPane(
  71. splitHorizontally ? JSplitPane.HORIZONTAL_SPLIT : JSplitPane.VERTICAL_SPLIT,
  72. parentScroller,treeScroller);
  73. tmpExpanded = new Hashtable();
  74. if(browser.isMultipleSelectionEnabled())
  75. tree.getSelectionModel().setSelectionMode(
  76. TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
  77. else
  78. tree.getSelectionModel().setSelectionMode(
  79. TreeSelectionModel.SINGLE_TREE_SELECTION);
  80. setLayout(new BorderLayout());
  81. add(BorderLayout.CENTER,splitPane);
  82. propertiesChanged();
  83. } //}}}
  84. //{{{ requestDefaultFocus() method
  85. public boolean requestDefaultFocus()
  86. {
  87. tree.requestFocus();
  88. return true;
  89. } //}}}
  90. //{{{ addNotify() method
  91. public void addNotify()
  92. {
  93. super.addNotify();
  94. SwingUtilities.invokeLater(new Runnable()
  95. {
  96. public void run()
  97. {
  98. String prop = splitHorizontally ? "vfs.browser.horizontalSplitter" : "vfs.browser.splitter";
  99. int loc = jEdit.getIntegerProperty(prop,0);
  100. if(loc != 0)
  101. {
  102. splitPane.setDividerLocation(loc);
  103. parentDirectories.ensureIndexIsVisible(
  104. parentDirectories.getModel()
  105. .getSize());
  106. }
  107. }
  108. });
  109. } //}}}
  110. //{{{ removeNotify() method
  111. public void removeNotify()
  112. {
  113. String prop = splitHorizontally ? "vfs.browser.horizontalSplitter" : "vfs.browser.splitter";
  114. jEdit.setIntegerProperty(prop,splitPane.getDividerLocation());
  115. super.removeNotify();
  116. } //}}}
  117. //{{{ getSelectedFiles() method
  118. public VFS.DirectoryEntry[] getSelectedFiles()
  119. {
  120. Vector selected = new Vector(tree.getSelectionCount());
  121. TreePath[] paths = tree.getSelectionPaths();
  122. if(paths == null)
  123. return new VFS.DirectoryEntry[0];
  124. for(int i = 0; i < paths.length; i++)
  125. {
  126. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  127. paths[i].getLastPathComponent();
  128. Object obj = treeNode.getUserObject();
  129. if(obj instanceof VFS.DirectoryEntry)
  130. selected.addElement(obj);
  131. }
  132. VFS.DirectoryEntry[] retVal = new VFS.DirectoryEntry[selected.size()];
  133. selected.copyInto(retVal);
  134. return retVal;
  135. } //}}}
  136. //{{{ selectNone() method
  137. public void selectNone()
  138. {
  139. tree.setSelectionPaths(new TreePath[0]);
  140. } //}}}
  141. //{{{ directoryLoaded() method
  142. public void directoryLoaded(DefaultMutableTreeNode node,
  143. String path, Vector directory)
  144. {
  145. if(node == 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. node.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 newNode = new DefaultMutableTreeNode(file,allowsChildren);
  175. node.add(newNode);
  176. if(tmpExpanded.get(file.path) != null)
  177. toExpand.addElement(new TreePath(newNode.getPath()));
  178. }
  179. }
  180. // fire events
  181. model.reload(node);
  182. tree.expandPath(new TreePath(node.getPath()));
  183. // expand branches that were expanded before
  184. for(int i = 0; i < toExpand.size(); i++)
  185. {
  186. TreePath treePath = (TreePath)toExpand.elementAt(i);
  187. tree.expandPath(treePath);
  188. }
  189. timer.stop();
  190. typeSelectBuffer.setLength(0);
  191. } //}}}
  192. //{{{ updateFileView() method
  193. public void updateFileView()
  194. {
  195. tree.repaint();
  196. } //}}}
  197. //{{{ loadDirectory() method
  198. public void loadDirectory(String path)
  199. {
  200. // called by VFSBrowser.setDirectory()
  201. tmpExpanded.clear();
  202. loadDirectory(rootNode,path,false);
  203. } //}}}
  204. //{{{ maybeReloadDirectory() method
  205. public void maybeReloadDirectory(String path)
  206. {
  207. tmpExpanded.clear();
  208. // because this method is called for *every* VFS update,
  209. // we don't want to scan the tree all the time. So we
  210. // use the following algorithm to determine if the path
  211. // might be part of the tree:
  212. // - if the path starts with the browser's current directory,
  213. // we do the tree scan
  214. // - if the browser's directory is 'favorites:' -- we have to
  215. // do the tree scan, as every path can appear under the
  216. // favorites list
  217. // - if the browser's directory is 'roots:' and path is on
  218. // the local filesystem, do a tree scan
  219. String browserDir = browser.getDirectory();
  220. if(browserDir.startsWith(FavoritesVFS.PROTOCOL))
  221. maybeReloadDirectory(rootNode,path);
  222. else if(browserDir.startsWith(FileRootsVFS.PROTOCOL))
  223. {
  224. if(!MiscUtilities.isURL(path) || MiscUtilities.getProtocolOfURL(path)
  225. .equals("file"))
  226. maybeReloadDirectory(rootNode,path);
  227. }
  228. else if(path.startsWith(browserDir))
  229. maybeReloadDirectory(rootNode,path);
  230. } //}}}
  231. //{{{ getDefaultFocusComponent() method
  232. public Component getDefaultFocusComponent()
  233. {
  234. return tree;
  235. } //}}}
  236. //{{{ propertiesChanged() method
  237. public void propertiesChanged()
  238. {
  239. showIcons = jEdit.getBooleanProperty("vfs.browser.showIcons");
  240. renderer.propertiesChanged();
  241. tree.setRowHeight(renderer.getTreeCellRendererComponent(
  242. tree,new DefaultMutableTreeNode("foo"),
  243. false,false,false,0,false).getSize().height);
  244. splitPane.setBorder(null);
  245. } //}}}
  246. //{{{ Private members
  247. //{{{ Instance variables
  248. private VFSBrowser browser;
  249. private JSplitPane splitPane;
  250. private JList parentDirectories;
  251. private DefaultListModel parentModel;
  252. private JTree tree;
  253. private Hashtable tmpExpanded;
  254. private DefaultTreeModel model;
  255. private DefaultMutableTreeNode rootNode;
  256. private BrowserCommandsMenu popup;
  257. private boolean showIcons;
  258. private boolean splitHorizontally;
  259. private FileCellRenderer renderer = new FileCellRenderer();
  260. private StringBuffer typeSelectBuffer = new StringBuffer();
  261. private Timer timer = new Timer(0,new ClearTypeSelect());
  262. //}}}
  263. //{{{ maybeReloadDirectory() method
  264. private boolean maybeReloadDirectory(DefaultMutableTreeNode node, String path)
  265. {
  266. // nodes which are not expanded need not be checked
  267. if(!tree.isExpanded(new TreePath(node.getPath())))
  268. return false;
  269. if(node == rootNode && path.equals(browser.getDirectory()))
  270. {
  271. loadDirectory(rootNode,path,false);
  272. return true;
  273. }
  274. Object userObject = node.getUserObject();
  275. if(userObject instanceof VFS.DirectoryEntry)
  276. {
  277. VFS.DirectoryEntry file = (VFS.DirectoryEntry)userObject;
  278. // we don't need to do anything with files!
  279. if(file.type == VFS.DirectoryEntry.FILE)
  280. return false;
  281. if(path.equals(file.path))
  282. {
  283. loadDirectory(node,path,false);
  284. return true;
  285. }
  286. }
  287. if(node.getChildCount() != 0)
  288. {
  289. Enumeration children = node.children();
  290. while(children.hasMoreElements())
  291. {
  292. DefaultMutableTreeNode child = (DefaultMutableTreeNode)
  293. children.nextElement();
  294. if(maybeReloadDirectory(child,path))
  295. return true;
  296. }
  297. }
  298. return false;
  299. } //}}}
  300. //{{{ loadDirectory() method
  301. private void loadDirectory(DefaultMutableTreeNode node, String path,
  302. boolean showLoading)
  303. {
  304. int rowCount = tree.getRowCount();
  305. for(int i = 0; i < rowCount; i++)
  306. {
  307. TreePath treePath = tree.getPathForRow(i);
  308. if(tree.isExpanded(treePath))
  309. {
  310. DefaultMutableTreeNode _node = (DefaultMutableTreeNode)
  311. treePath.getLastPathComponent();
  312. VFS.DirectoryEntry file = ((VFS.DirectoryEntry)
  313. _node.getUserObject());
  314. tmpExpanded.put(file.path,file.path);
  315. }
  316. }
  317. if(node == rootNode)
  318. {
  319. parentModel.removeAllElements();
  320. parentModel.addElement(new LoadingPlaceholder());
  321. }
  322. if(showLoading)
  323. {
  324. node.removeAllChildren();
  325. node.add(new DefaultMutableTreeNode(new LoadingPlaceholder(),false));
  326. model.reload(node);
  327. }
  328. browser.loadDirectory(node,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 * 10 + 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 ? 14 : - 4),
  433. cellRect.y);
  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(evt.isShiftDown(),false);
  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.rootDirectory();
  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. return;
  483. }
  484. if(!evt.isConsumed())
  485. super.processKeyEvent(evt);
  486. } //}}}
  487. //{{{ processMouseEvent() method
  488. protected void processMouseEvent(MouseEvent evt)
  489. {
  490. ToolTipManager ttm = ToolTipManager.sharedInstance();
  491. switch(evt.getID())
  492. {
  493. //{{{ MOUSE_ENTERED...
  494. case MouseEvent.MOUSE_ENTERED:
  495. toolTipInitialDelay = ttm.getInitialDelay();
  496. toolTipReshowDelay = ttm.getReshowDelay();
  497. ttm.setInitialDelay(200);
  498. ttm.setReshowDelay(0);
  499. super.processMouseEvent(evt);
  500. break; //}}}
  501. //{{{ MOUSE_EXITED...
  502. case MouseEvent.MOUSE_EXITED:
  503. ttm.setInitialDelay(toolTipInitialDelay);
  504. ttm.setReshowDelay(toolTipReshowDelay);
  505. super.processMouseEvent(evt);
  506. break; //}}}
  507. //{{{ MOUSE_CLICKED...
  508. case MouseEvent.MOUSE_CLICKED:
  509. if((evt.getModifiers() & MouseEvent.BUTTON2_MASK) != 0)
  510. {
  511. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  512. if(path == null)
  513. {
  514. super.processMouseEvent(evt);
  515. break;
  516. }
  517. if(!isPathSelected(path))
  518. setSelectionPath(path);
  519. browser.filesActivated(evt.isShiftDown(),true);
  520. break;
  521. }
  522. else if((evt.getModifiers() & MouseEvent.BUTTON1_MASK) != 0)
  523. {
  524. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  525. if(path == null)
  526. {
  527. super.processMouseEvent(evt);
  528. break;
  529. }
  530. if(!isPathSelected(path))
  531. setSelectionPath(path);
  532. if(evt.getClickCount() == 1)
  533. {
  534. browser.filesSelected();
  535. super.processMouseEvent(evt);
  536. }
  537. if(evt.getClickCount() == 2)
  538. {
  539. // don't pass double-clicks to tree, otherwise
  540. // directory nodes will be expanded and we don't
  541. // want that
  542. browser.filesActivated(evt.isShiftDown(),true);
  543. break;
  544. }
  545. }
  546. else if(GUIUtilities.isPopupTrigger(evt))
  547. ; // do nothing
  548. super.processMouseEvent(evt);
  549. break; //}}}
  550. //{{{ MOUSE_PRESSED...
  551. case MouseEvent.MOUSE_PRESSED:
  552. if((evt.getModifiers() & MouseEvent.BUTTON1_MASK) != 0)
  553. {
  554. if(popup != null && popup.isVisible())
  555. popup.setVisible(false);
  556. if(evt.getClickCount() == 2)
  557. break;
  558. }
  559. else if(GUIUtilities.isPopupTrigger(evt))
  560. {
  561. if(popup != null && popup.isVisible())
  562. {
  563. popup.setVisible(false);
  564. break;
  565. }
  566. TreePath path = getPathForLocation(evt.getX(),evt.getY());
  567. if(path == null)
  568. showFilePopup(null,evt.getPoint());
  569. else
  570. {
  571. setSelectionPath(path);
  572. browser.filesSelected();
  573. Object userObject = ((DefaultMutableTreeNode)path
  574. .getLastPathComponent()).getUserObject();
  575. if(userObject instanceof VFS.DirectoryEntry)
  576. {
  577. VFS.DirectoryEntry file = (VFS.DirectoryEntry)
  578. userObject;
  579. showFilePopup(file,evt.getPoint());
  580. }
  581. else
  582. showFilePopup(null,evt.getPoint());
  583. }
  584. break;
  585. }
  586. super.processMouseEvent(evt);
  587. break; //}}}
  588. //{{{ MOUSE_RELEASED...
  589. case MouseEvent.MOUSE_RELEASED:
  590. if(evt.getClickCount() != 2)
  591. super.processMouseEvent(evt);
  592. break; //}}}
  593. default:
  594. super.processMouseEvent(evt);
  595. break;
  596. }
  597. } //}}}
  598. //{{{ Private members
  599. private int toolTipInitialDelay = -1;
  600. private int toolTipReshowDelay = -1;
  601. //{{{ cellRectIsVisible() method
  602. private boolean cellRectIsVisible(Rectangle cellRect)
  603. {
  604. Rectangle vr = BrowserJTree.this.getVisibleRect();
  605. return vr.contains(cellRect.x,cellRect.y) &&
  606. vr.contains(cellRect.x + cellRect.width,
  607. cellRect.y + cellRect.height);
  608. } //}}}
  609. //{{{ doTypeSelect() method
  610. private void doTypeSelect(String str)
  611. {
  612. if(getSelectionCount() == 0)
  613. doTypeSelect(str,0,getRowCount());
  614. else
  615. {
  616. int start = getMaxSelectionRow();
  617. boolean retVal = doTypeSelect(str,start,getRowCount());
  618. if(!retVal)
  619. {
  620. // scan from selection to end failed, so
  621. // scan from start to selection
  622. doTypeSelect(str,0,start);
  623. }
  624. }
  625. } //}}}
  626. //{{{ doTypeSelect() method
  627. private boolean doTypeSelect(String str, int start, int end)
  628. {
  629. for(int i = start; i < end; i++)
  630. {
  631. DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)
  632. getPathForRow(i).getLastPathComponent();
  633. Object obj = treeNode.getUserObject();
  634. if(obj instanceof VFS.DirectoryEntry)
  635. {
  636. VFS.DirectoryEntry file = (VFS.DirectoryEntry)obj;
  637. if(file.name.regionMatches(true,0,str,0,str.length()))
  638. {
  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. }