/** * When called it will traverse all visible leaves in the browseTree and collapse them if they * have been open for too long and are not selected. */ private void collapseOldNodes() { Stack<ListableEntry> toConsider = new Stack< ListableEntry>(); // this is a stack of expanded nodes that need their children (and // themselves) to be considered. toConsider.push(fs.getBrowseRoot()); // we know these are always expanded, and uncollapsable. toConsider.push(fs.getSearchRoot()); // " " " // a) mark all uncollapsable nodes TreePath[] selecteds = browseTree.getSelectionPaths(); if (selecteds != null) { for (TreePath selected : selecteds) { for (Object toMark : selected.getPath()) { // a selected nodes and their ancestors are not collapsable. expandedTimes.put(toMark, System.currentTimeMillis()); } } } // b) collapse old expanded nodes. while (!toConsider.empty()) { for (FileSystemEntry child : toConsider.pop().getAllChildren()) { if (browseTree.isExpanded(child.getPath())) { toConsider.push(child); if (System.currentTimeMillis() - expandedTimes.get(child) > FS2Constants.CLIENT_BROWSETREE_COLLAPSE_INTERVAL) { browseTree.collapsePath(child.getPath()); expandedTimes.remove(child); } } } } }
@Override public void mouseClicked(MouseEvent e) { if (e.getSource() == filesTable) { if (e.getClickCount() == 2 && e.getModifiersEx() == 0) { // the modifiers test is to prevent absurd clicks like "b1, b3" registering as // double-clicks. if (filesTable.getSelectedRow() >= 0) { FileSystemEntry clicked = fs.getEntryForRow(filesTable.convertRowIndexToModel(filesTable.getSelectedRow())); if (clicked.isDirectory()) { // Go into the directory: TreePath pathToClicked = clicked.getPath(); browseTree.setSelectionPath(pathToClicked); browseTree.scrollPathToVisible(pathToClicked); browseTree.setSelectionPath( pathToClicked); // the first one may have expanded the node and changed the // selection, so ensure the node we want is actually selected. } else { downloadToDirectory(Arrays.asList(new FileSystemEntry[] {clicked}), null, null); frame.setStatusHint( new StatusHint( frame.gui.util.getImage("tick"), clicked.getName() + " queued for download!")); } } } } if (e.getSource() == browseTree) { // remove a search if they clicked on the searches icon. if (lastOnIcon && lastInspectedFSE instanceof FileSystemEntry && ((FileSystemEntry) lastInspectedFSE).isSearch()) { fs.removeSearch((FileSystemEntry) lastInspectedFSE); lastInspectedFSE = null; // doesn't exist anymore. lastOnIcon = false; mouseMoved( new MouseEvent( browseTree, 0, System.currentTimeMillis(), 0, e.getX(), e.getY(), 0, false)); // simulate the mouse moving to update status bar and icons. } // remove all searches if the clicked the searchroot: if (lastInspectedFSE == fs.getSearchRoot()) { fs.removeAllSearches(); } } }
JSplitPane createBrowseSection() { spinner = new LoadingAnimationHelper(); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.setContinuousLayout(true); fs = frame.gui.ssvr.getIndexNodeCommunicator().getFileSystem(); browseTree = new JTree(fs); // Allows the filesystem to keep refreshing directories we have visible: fs.setPathRequired( new PathRequired() { @Override public boolean required(TreePath path) { return browseTree.isExpanded(path); } }); fs.addTreeModelListener(spinner); browseTree.setCellRenderer(browseTreeRenderer = new BrowseTreeCellRenderer()); browseTree.addTreeSelectionListener(this); browseTree.addMouseMotionListener(this); browseTree.addMouseListener(this); browseTree.addTreeExpansionListener(this); browseTree.setRootVisible(false); browseTree.expandPath(fs.getBrowseRoot().getPath()); JScrollPane treeView = new JScrollPane(browseTree); treeView.setMinimumSize(new Dimension(100, 100)); splitPane.setLeftComponent(treeView); filesTable = new FancierTable(fs, frame.gui.conf, CK.FILES_TABLE_COLWIDTHS); filesTable.addMouseListener(this); filesTable.getSelectionModel().addListSelectionListener(this); filesTable.getColumn(fs.getColumnName(0)).setCellRenderer(new FilesTableNameRenderer()); JScrollPane filesView = new JScrollPane(filesTable); splitPane.setRightComponent(filesView); splitPane.setDividerLocation(frame.gui.conf.getInt(CK.FILES_DIVIDER_LOCATION)); splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, this); return splitPane; }
@Override public void actionPerformed(ActionEvent e) { if (e.getSource() == collapseTimer) { collapseOldNodes(); } else if (e.getActionCommand().equals("search")) { if (searchQuery.getText().equals("")) return; TreePath path = fs.newSearch(searchQuery.getText()).getPath(); browseTree.expandPath(path); browseTree.setSelectionPath(path); } }
void setTableStatusHint() { if (browseTree.getSelectionPath() == null) { return; } if (!(browseTree.getSelectionPath().getLastPathComponent() instanceof FileSystemEntry)) return; FileSystemEntry fse = ((FileSystemEntry) browseTree.getSelectionPath().getLastPathComponent()); int[] selected = filesTable.getSelectedRows(); if (selected == null || selected.length == 0) { if (fse.getFiles() != null) frame.setStatusHint( "Directories: " + fse.getChildCount() + ", Files: " + fse.getFiles().size() + ", Total size: " + Util.niceSize(fse.getSize())); } else { long size = 0; int dirs = 0; int files = 0; for (int i : selected) { FileSystemEntry current = fs.getEntryForRow(filesTable.convertRowIndexToModel(i)); size += current.getSize(); if (current.isDirectory()) dirs++; else files++; } frame.setStatusHint( "(selection) Directories: " + dirs + ", Files: " + files + ", Total size: " + Util.niceSize(size)); } }
@Override public void valueChanged(TreeSelectionEvent e) { if (e.getPath().getLastPathComponent() instanceof ListableEntry) fs.setSelectedEntry((ListableEntry) e.getPath().getLastPathComponent()); }