[Jreepad-CVS] jreepad/src/jreepad TreeView.java, NONE, 1.1 JreepadView.java, 1.32, 1.33
Brought to you by:
danstowell
From: PeWu <pe...@us...> - 2007-01-14 17:10:39
|
Update of /cvsroot/jreepad/jreepad/src/jreepad In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv18551/src/jreepad Modified Files: JreepadView.java Added Files: TreeView.java Log Message: refactoring: extracted TreeView from JreepadView to manage the tree component Index: JreepadView.java =================================================================== RCS file: /cvsroot/jreepad/jreepad/src/jreepad/JreepadView.java,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** JreepadView.java 14 Jan 2007 00:21:59 -0000 1.32 --- JreepadView.java 14 Jan 2007 17:10:21 -0000 1.33 *************** *** 20,29 **** package jreepad; ! import javax.swing.*; ! import javax.swing.tree.*; ! import javax.swing.table.*; ! import javax.swing.event.*; ! import javax.swing.undo.*; ! import javax.swing.text.*; import org.philwilson.JTextile; --- 20,73 ---- package jreepad; ! import java.awt.Color; ! import java.awt.Dimension; ! import java.awt.event.ComponentEvent; ! import java.awt.event.ComponentListener; ! import java.awt.event.KeyAdapter; ! import java.awt.event.KeyEvent; ! import java.io.BufferedReader; ! import java.io.File; ! import java.io.FileInputStream; ! import java.io.IOException; ! import java.io.InputStreamReader; ! import java.util.Vector; ! ! import javax.swing.Box; ! import javax.swing.BoxLayout; ! import javax.swing.JComponent; ! import javax.swing.JEditorPane; ! import javax.swing.JOptionPane; ! import javax.swing.JScrollPane; ! import javax.swing.JSplitPane; ! import javax.swing.JTable; ! import javax.swing.JTree; ! import javax.swing.event.CaretEvent; ! import javax.swing.event.CaretListener; ! import javax.swing.event.ChangeEvent; ! import javax.swing.event.ChangeListener; ! import javax.swing.event.DocumentEvent; ! import javax.swing.event.DocumentListener; ! import javax.swing.event.TableModelEvent; ! import javax.swing.event.TableModelListener; ! import javax.swing.event.TreeModelEvent; ! import javax.swing.event.TreeModelListener; ! import javax.swing.event.TreeSelectionEvent; ! import javax.swing.event.TreeSelectionListener; ! import javax.swing.event.UndoableEditEvent; ! import javax.swing.event.UndoableEditListener; ! import javax.swing.table.DefaultTableModel; ! import javax.swing.text.AbstractDocument; ! import javax.swing.text.BadLocationException; ! import javax.swing.text.BoxView; ! import javax.swing.text.ComponentView; ! import javax.swing.text.Document; ! import javax.swing.text.Element; ! import javax.swing.text.IconView; ! import javax.swing.text.LabelView; ! import javax.swing.text.StyleConstants; ! import javax.swing.text.StyledEditorKit; ! import javax.swing.text.View; ! import javax.swing.text.ViewFactory; ! import javax.swing.tree.TreePath; import org.philwilson.JTextile; *************** *** 34,44 **** import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException; - import java.awt.*; - import java.awt.event.*; - import java.util.Enumeration; - import java.util.Vector; - import java.io.*; - import java.awt.print.*; - public class JreepadView extends Box implements TableModelListener { --- 78,81 ---- *************** *** 91,98 **** private JreepadNode root; private JreepadNode currentNode; - private JreepadNode currentDragDropNode; - private TreeNode topNode; private JreepadTreeModel treeModel; ! private JTree tree; private JScrollPane treeView; private JScrollPane articleView; --- 128,133 ---- private JreepadNode root; private JreepadNode currentNode; private JreepadTreeModel treeModel; ! private TreeView tree; private JScrollPane treeView; private JScrollPane articleView; *************** *** 155,179 **** treeModel.addTreeModelListener(new JreepadTreeModelListener()); ! tree = new JTree(treeModel){ ! public void cancelEditing() ! { ! super.cancelEditing(); // if we can override this perhaps we can prevent blank nodes...? ! JreepadNode lastEditedNode = (JreepadNode)(tree.getSelectionPath().getLastPathComponent()); ! if(lastEditedNode.getTitle().equals("")) ! lastEditedNode.setTitle("<Untitled node>"); ! } ! }; ! tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); ! tree.setExpandsSelectedPaths(true); ! tree.setInvokesStopCellEditing(true); ! tree.setEditable(true); ! ! tree.setModel(treeModel); ! ! DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); ! renderer.setOpenIcon(null); ! renderer.setClosedIcon(null); ! renderer.setLeafIcon(null); ! tree.setCellRenderer(renderer); searcher = new JreepadSearcher(root); --- 190,194 ---- treeModel.addTreeModelListener(new JreepadTreeModelListener()); ! tree = new TreeView(treeModel); searcher = new JreepadSearcher(root); *************** *** 199,262 **** }); - // Fiddle with the cell editor - to ensure that when editing a new node, you shouldn't be able to leave a blank title - tree.getCellEditor().addCellEditorListener(new CellEditorListener() - { - public void editingCanceled(ChangeEvent e) - { - ensureNodeTitleIsNotEmpty(e); - } - public void editingStopped(ChangeEvent e) - { - ensureNodeTitleIsNotEmpty(e); - } - }); - - // Add mouse listener - this will be used to implement drag-and-drop, context menu (?), etc - MouseListener ml = new MouseAdapter() - { - public void mousePressed(MouseEvent e) - { - TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - if(selPath != null) - { - currentDragDropNode = (JreepadNode)selPath.getLastPathComponent(); - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - } - public void mouseReleased(MouseEvent e) - { - TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - // System.out.println("Mouse released: path = " + selPath); - if(selPath != null) - { - if(currentDragDropNode != null && - currentDragDropNode.getParentNode() != null && - currentDragDropNode.getParentNode() != (JreepadNode)selPath.getLastPathComponent() && - currentDragDropNode != (JreepadNode)selPath.getLastPathComponent()) - { - // Then we need to perform a drag-and-drop operation! - moveNode(currentDragDropNode, (JreepadNode)selPath.getLastPathComponent()); - - // Ensure that the destination node is open - tree.setSelectionPath(selPath.pathByAddingChild(currentDragDropNode)); - } - } - setCursor(Cursor.getDefaultCursor()); - currentDragDropNode = null; - } - public void mouseClicked(MouseEvent e) - { - TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - if(selPath != null) - { - if(e.isPopupTrigger()) - { - // Now we can implement the pop-up content menu - System.out.println("Context menu would be launched here!"); - } - } - } - }; - tree.addMouseListener(ml); tree.addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent kee) { --- 214,217 ---- *************** *** 471,516 **** } - public void moveNode(JreepadNode node, JreepadNode newParent) - { - // First we need to make sure that the node is not a parent of the new parent - // - otherwise things would go really wonky! - if(node.isNodeInSubtree(newParent)) - { - return; - } - - //DEL storeForUndo(); - - JreepadNode oldParent = node.getParentNode(); - - // Now make a note of the expanded/collapsed state of the subtree of the moving node - boolean thisOnesExpanded = tree.isExpanded(tree.getSelectionPath()); - Enumeration enumer; - Vector expanded; - if(thisOnesExpanded) - { - enumer = tree.getExpandedDescendants(tree.getSelectionPath()); - expanded = new Vector(); - while(enumer.hasMoreElements()) - { - expanded.add((TreePath)enumer.nextElement()); - // System.out.println(expanded.lastElement()); - } - } - - node.removeFromParent(); - newParent.addChild(node); - treeModel.reload(oldParent); - treeModel.reload(newParent); - // treeModel.reload((TreeNode)tree.getPathForRow(0).getLastPathComponent()); - - // If the destination node didn't previously have any children, then we'll expand it - // if(newParent.getChildCount()==1) - - - // Reapply the expanded/collapsed states - - } public void indentCurrentNode() --- 426,430 ---- *************** *** 522,526 **** } - int nodeRow = tree.getLeadSelectionRow(); TreePath parentPath = tree.getSelectionPath().getParentPath(); int pos = currentNode.getIndex(); --- 436,439 ---- *************** *** 746,799 **** public void expandAllCurrentNode() { ! expandAll(currentNode, tree.getLeadSelectionPath()); ! } ! public void expandAll(JreepadNode thisNode, TreePath tp) ! { ! // It's at this point that we expand the current element ! tree.expandPath(tp); ! ! Enumeration getKids = thisNode.children(); ! JreepadNode thisKid; ! while(getKids.hasMoreElements()) ! { ! thisKid = (JreepadNode)getKids.nextElement(); ! expandAll(thisKid, tp.pathByAddingChild(thisKid)); ! } } public void collapseAllCurrentNode() { ! collapseAll(currentNode, tree.getLeadSelectionPath()); ! } ! public void collapseAll(JreepadNode thisNode, TreePath tp) ! { ! Enumeration getKids = thisNode.children(); ! JreepadNode thisKid; ! while(getKids.hasMoreElements()) ! { ! thisKid = (JreepadNode)getKids.nextElement(); ! collapseAll(thisKid, tp.pathByAddingChild(thisKid)); ! } ! // It's at this point that we collapse the current element ! tree.collapsePath(tp); } - public TreePath[] getAllExpandedPaths() { ! if(root.getChildCount()==0) ! return new TreePath[] {new TreePath(root)}; ! ! Enumeration getPaths = tree.getExpandedDescendants(new TreePath(root)); ! TreePath thisKid; ! Vector allPaths = new Vector(); ! while(getPaths.hasMoreElements()) ! { ! thisKid = (TreePath)getPaths.nextElement(); ! allPaths.add(thisKid); ! } ! TreePath[] ret = new TreePath[allPaths.size()]; ! for(int i=0; i<ret.length; i++) ! ret[i] = (TreePath)allPaths.get(i); ! return ret; } --- 659,672 ---- public void expandAllCurrentNode() { ! tree.expandAll(currentNode, tree.getLeadSelectionPath()); } public void collapseAllCurrentNode() { ! tree.collapseAll(currentNode, tree.getLeadSelectionPath()); } public TreePath[] getAllExpandedPaths() { ! return tree.getAllExpandedPaths(); } *************** *** 801,808 **** public void expandPaths(TreePath[] paths) { ! for(int i=0; i<paths.length; i++) ! { ! tree.expandPath(paths[i]); ! } } --- 674,678 ---- public void expandPaths(TreePath[] paths) { ! tree.expandPaths(paths); } *************** *** 1478,1497 **** // End of: functions which should allow us to switch between JEditorPane and JTable - private void ensureNodeTitleIsNotEmpty(ChangeEvent e) - { - TreeCellEditor theEditor = (TreeCellEditor)tree.getCellEditor(); - String newTitle = (String)(theEditor.getCellEditorValue()); - - // JreepadNode thatNode = (JreepadNode)(tree.getEditingPath().getLastPathComponent()); - //System.out.println("ensureNodeTitleIsNotEmpty(): Event source = " + e.getSource()); - //System.out.println("ensureNodeTitleIsNotEmpty(): thatNode = " + thatNode); - // System.out.println("getCellEditorValue() = " + newTitle); - if(newTitle.equals("")) - { - theEditor.getTreeCellEditorComponent(tree, "<Untitled node>", true, true, false, 1); - // thatNode.setTitle("<Untitled node>"); - } - } public void editNodeTitleAction() --- 1348,1352 ---- *************** *** 1528,1534 **** { warnAboutUnsaved = true; ! Object[] parentPath = e.getPath(); // Parent of the changed node(s) ! int[] children = e.getChildIndices(); // Indices of the changed node(s) ! JreepadNode parent = (JreepadNode)(parentPath[parentPath.length-1]); tree.repaint(); } --- 1383,1389 ---- { warnAboutUnsaved = true; ! // Object[] parentPath = e.getPath(); // Parent of the changed node(s) ! // int[] children = e.getChildIndices(); // Indices of the changed node(s) ! // JreepadNode parent = (JreepadNode)(parentPath[parentPath.length-1]); tree.repaint(); } --- NEW FILE: TreeView.java --- /* Jreepad - personal information manager. Copyright (C) 2004 Dan Stowell This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The full license can be read online here: http://www.gnu.org/copyleft/gpl.html */ package jreepad; import java.awt.Cursor; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.JTree; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellEditor; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /** * The GUI component that displays the tree. * * @version $Id$ */ public class TreeView extends JTree { private JreepadTreeModel treeModel; public TreeView(JreepadTreeModel treeModel) { super(treeModel); this.treeModel = treeModel; getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); setExpandsSelectedPaths(true); setInvokesStopCellEditing(true); setEditable(true); DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); renderer.setOpenIcon(null); renderer.setClosedIcon(null); renderer.setLeafIcon(null); setCellRenderer(renderer); // Fiddle with the cell editor - to ensure that when editing a new node, you shouldn't be // able to leave a blank title getCellEditor().addCellEditorListener(new CellEditorListener() { public void editingCanceled(ChangeEvent e) { ensureNodeTitleIsNotEmpty(e); } public void editingStopped(ChangeEvent e) { ensureNodeTitleIsNotEmpty(e); } }); // Add mouse listener - this will be used to implement drag-and-drop, context menu (?), etc addMouseListener(new TreeViewMouseListener()); } public void cancelEditing() { super.cancelEditing(); // if we can override this perhaps we can prevent blank nodes...? JreepadNode lastEditedNode = (JreepadNode)(getSelectionPath().getLastPathComponent()); if (lastEditedNode.getTitle().equals("")) lastEditedNode.setTitle("<Untitled node>"); } private void ensureNodeTitleIsNotEmpty(ChangeEvent e) { TreeCellEditor theEditor = (TreeCellEditor)getCellEditor(); String newTitle = (String)(theEditor.getCellEditorValue()); // JreepadNode thatNode = (JreepadNode)(tree.getEditingPath().getLastPathComponent()); // System.out.println("ensureNodeTitleIsNotEmpty(): Event source = " + e.getSource()); // System.out.println("ensureNodeTitleIsNotEmpty(): thatNode = " + thatNode); // System.out.println("getCellEditorValue() = " + newTitle); if(newTitle.equals("")) { theEditor.getTreeCellEditorComponent(this, "<Untitled node>", true, true, false, 1); // thatNode.setTitle("<Untitled node>"); } } public void moveNode(JreepadNode node, JreepadNode newParent) { // First we need to make sure that the node is not a parent of the new parent // - otherwise things would go really wonky! if (node.isNodeInSubtree(newParent)) { return; } // DEL storeForUndo(); JreepadNode oldParent = node.getParentNode(); // Now make a note of the expanded/collapsed state of the subtree of the moving node boolean thisOnesExpanded = isExpanded(getSelectionPath()); Enumeration enumer; Vector expanded; if (thisOnesExpanded) { enumer = getExpandedDescendants(getSelectionPath()); expanded = new Vector(); while (enumer.hasMoreElements()) { expanded.add((TreePath)enumer.nextElement()); // System.out.println(expanded.lastElement()); } } node.removeFromParent(); newParent.addChild(node); treeModel.reload(oldParent); treeModel.reload(newParent); // treeModel.reload((TreeNode)tree.getPathForRow(0).getLastPathComponent()); // If the destination node didn't previously have any children, then we'll expand it // if(newParent.getChildCount()==1) // Reapply the expanded/collapsed states } public void expandAll(JreepadNode thisNode, TreePath tp) { // It's at this point that we expand the current element expandPath(tp); Enumeration getKids = thisNode.children(); JreepadNode thisKid; while (getKids.hasMoreElements()) { thisKid = (JreepadNode)getKids.nextElement(); expandAll(thisKid, tp.pathByAddingChild(thisKid)); } } public void collapseAll(JreepadNode thisNode, TreePath tp) { Enumeration getKids = thisNode.children(); JreepadNode thisKid; while (getKids.hasMoreElements()) { thisKid = (JreepadNode)getKids.nextElement(); collapseAll(thisKid, tp.pathByAddingChild(thisKid)); } // It's at this point that we collapse the current element collapsePath(tp); } public TreePath[] getAllExpandedPaths() { JreepadNode root = (JreepadNode)treeModel.getRoot(); if (root.getChildCount() == 0) return new TreePath[] { new TreePath(root) }; Enumeration getPaths = getExpandedDescendants(new TreePath(root)); TreePath thisKid; Vector allPaths = new Vector(); while (getPaths.hasMoreElements()) { thisKid = (TreePath)getPaths.nextElement(); allPaths.add(thisKid); } TreePath[] ret = new TreePath[allPaths.size()]; for (int i = 0; i < ret.length; i++) ret[i] = (TreePath)allPaths.get(i); return ret; } // THIS FUNCTION SEEMS TO HAVE NO EFFECT, ON MY MACHINE AT LEAST! WHAT'S GOING ON? public void expandPaths(TreePath[] paths) { for (int i = 0; i < paths.length; i++) { expandPath(paths[i]); } } /** * Mouse control for the Tree View. */ private class TreeViewMouseListener extends MouseAdapter { private JreepadNode currentDragDropNode; public void mousePressed(MouseEvent e) { TreePath selPath = getPathForLocation(e.getX(), e.getY()); if (selPath != null) { currentDragDropNode = (JreepadNode)selPath.getLastPathComponent(); setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } public void mouseReleased(MouseEvent e) { TreePath selPath = getPathForLocation(e.getX(), e.getY()); // System.out.println("Mouse released: path = " + selPath); if (selPath != null) { if (currentDragDropNode != null && currentDragDropNode.getParentNode() != null && currentDragDropNode.getParentNode() != (JreepadNode)selPath .getLastPathComponent() && currentDragDropNode != (JreepadNode)selPath.getLastPathComponent()) { // Then we need to perform a drag-and-drop operation! moveNode(currentDragDropNode, (JreepadNode)selPath.getLastPathComponent()); // Ensure that the destination node is open setSelectionPath(selPath.pathByAddingChild(currentDragDropNode)); } } setCursor(Cursor.getDefaultCursor()); currentDragDropNode = null; } public void mouseClicked(MouseEvent e) { TreePath selPath = getPathForLocation(e.getX(), e.getY()); if (selPath != null) { if (e.isPopupTrigger()) { // Now we can implement the pop-up content menu System.out.println("Context menu would be launched here!"); } } } } } |