JTree 中的事件

public void jTree1_propertyChange(PropertyChangeEvent propertyChangeEvent) {} //接口 java.beans.PropertyChangeListener 中的方法 
在绑定属性发生更改时调用此方法。 


public void jTree1_treeCollapsed(TreeExpansionEvent event) {} 
// javax.swing.plaf.basic.BasicTreeUI.TreeExpansionHandler 中的方法 
每当树中的项被折叠时调用

public void jTree1_treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {} // 接口 javax.swing.event.TreeWillExpandListener 中的方法 
每当树中的一个节点将被折叠时调用。 

public void jTree1_treeExpanded(TreeExpansionEvent event) {} 
// 接口 javax.swing.event.TreeExpansionListener 中的方法 
每当树中的一个项被扩展时调用。 

public void jTree1_treeWillExpand(TreeExpansionEvent event) throws 
ExpandVetoException {}// 接口 javax.swing.event.TreeWillExpandListener 中的方法 
每当树中的一个节点将被扩展时调用。 

public void jTree1_valueChanged(TreeSelectionEvent e) {} 
// 类 java.awt.TextComponent.AccessibleAWTTextComponent 中的方法 
文本值更改的 TextListener 通知。
public void jTree1_vetoableChange(PropertyChangeEvent propertyChangeEvent) throws 
PropertyVetoException {} 
// 类 java.beans.VetoableChangeListenerProxy 中的方法 
将属性更改事件转发给侦听器代理。 
以上各类均可在javaAPI中找到详细解释
================================================================
jTree1.addTreeSelectionListener(this);  
==================================================================
JTree 也是一个分层显示数据的组件 ,它在Swing里复杂度算是中等,涉及的类不是很多,也没有复杂的UI ,所以单独对一个树来说,构造和渲染都不难,对于树的操作比较麻烦的是拖拽和与其他组件数据交互.

对于JTree有几个比较重要的类和接口 : TreeMode是一个接口,用来构建树的模型 , 实现这个接口之后我们可以把一些比较另类的组件抽象成一棵树,TreeTable就是这个原理实现的;TreeNode是一个接口,代表树的节 点,DefaultMutableTreeNode是该接口的一个实现,我们一般构建树使用它就可以了,当然也可以继承它添加新的功能,或者实现 TreeNode把节点变成其它组件; TreePath是一个类,负责节点到根的路径,一般不需要我们来修改; TreeSelectionModel是一个接口,表示树选择组件的当前状态,只是使用皆可以了,一般除非做很大的改动,否则不需要修改这个类;还有就是 TreeCellRenderer和TreeCellEditor了,它们是树的渲染器,实现特殊效果都需要实现它们;还有就是TreeUI了,树的UI 比较死板,很少需要修改.

由上面类和接口可以,树还是一个不是很复杂的组件的,除了基本使用外,我们一般会用到的也就是对Cell进行渲染,替换树的节点图片,或者给节点加个CheckBox这些了.

先看树的简单使用,Sun官方给我们提供了例子:

附件: 1q.jpg

这个例子只是简单的构建一棵树:
  1.       // Create the root nodes.
  2.         DefaultMutableTreeNode top = new DefaultMutableTreeNode(
  3.                 "The Java Series");
  4.         //add node
  5.         createNodes(top);
  6.         // Create a tree that allows one selection at a time.
  7.         tree = new JTree(top);
  8.         tree.getSelectionModel().setSelectionMode(
  9.                 TreeSelectionModel.SINGLE_TREE_SELECTION);
复制代码

当然我们也可以先创建树,再设置数据,这都是JTree的构造函数,本质上是没区别的,最终JTree也是通过setModel设置数据的:

  1. tree = new JTree();
  2. tree.setModel(treeModel);
复制代码

构造完树之后还要把树放在JScollPanel上,否则树显示会有问题:

  1.         // Create the scroll pane and add the tree to it.
  2.         JScrollPane treeView = new JScrollPane(tree);
复制代码

到此为止,树就完成了,当然Sun也提供了许多方法便捷于我们操作树:

取得根节点:

  1.     // get the tree root node
  2.     TreeNode rootNode = (TreeNode)tree.getModel().getRoot();
复制代码

取得树的数据模型:

  1.     // get the tree model.
  2.     DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
复制代码

取得树的某一个节点的位置:

  1.     // get tree node path.
  2.     TreePath nodePath = new TreePath(treeModel.getPathToRoot(node));
复制代码

设置节点的展开可见和选择:

  1.     //select the node.
  2.     tree.setSelectionPath(nodePath);
  3.     // Ensures that the node identified by path is currently viewable.
  4. tree.makeVisible(nodePath);
复制代码

展开后滚动至节点可见:

  1.     // Makes sure all the path components display
  2. tree.scrollPathToVisible(nodePath);
复制代码

还有一个是设置鼠标点击展开树节点的(默认是双击,改成了0就是不可点击):

  1.   // Sets the number of mouse clicks before a node will expand or close.
  2.   tree.setToggleClickCount(1);
复制代码

另外就是一个设置Cell的高度的,但这个方法我们一般不用,大多时候是在Renderer里设置的,因为这样设置可能有UI问题:

  1.   // Sets the height of each cell, in pixels.
  2.   tree.setRowHeight(15);
复制代码

其它还有很多,因为JTree继承JComponent,所以它有父类的所有方法,我们通过setXXX和getXXX就可以设置了.

说完基本的设置之后,说一下JTree的事件:

JTree继承JComponent,所以它有JComponent的事件,但我们一般只关注鼠标的键盘的:

  1.     // add mouse listener
  2.     tree.addMouseListener(this);
  3.     // add key listener
  4. tree.addKeyListener(this);
复制代码

然后是JTree独有的事件:

  1.     tree.addTreeExpansionListener(this);
  2.     tree.addTreeWillExpandListener(this);
  3.     tree.addTreeSelectionListener(this);
复制代码

分别是树节点展开(折叠)、树节点将要展开(折叠)和树节点选择事件,我们一般用的多的是addTreeExpansionListener和addTreeSelectionListener事件。

 

事件处理都不是很复杂,增加监听后实现方法就可以了,需要注意的是TreeSelectionListener和MouseListener,它们有事件 重叠的地方:但在树的节点点击鼠标左键时触发这两个事件,点击右键时触发鼠标事件,所以这两个事件都做监听时,处理一定要注意:

先看TreeSelectionListener的处理:

    @Override

    publicvoid valueChanged(TreeSelectionEvent event) {

然后可以取得TreePath,之后取得Node

  1.     // Returns the current lead path.
  2.     TreePath newPath = event.getNewLeadSelectionPath();
  3.     TreePath oldPath = event.getOldLeadSelectionPath();
复制代码

或者通过JTree取得Node

  1. JTree tree = (JTree) event.getSource();
  2. tree.getLastSelectedPathComponent();
复制代码

再看MouseListener的处理:

      @Override

    publicvoid mouseClicked(MouseEvent e) {

鼠标组件场合比较简单,因为这个时候节点被选中:

  1. if (SwingUtilities.isLeftMouseButton(e)
  2.                     && e.getClickCount() == 1) {
  3.       // Returns the last path component
  4.       DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
  5.                         .getLastSelectedPathComponent();
  6.     }
复制代码

右键则要得出节点位置再处理:

  1.     if (SwingUtilities.isRightMouseButton(e)) {
  2.         // Returns the row for the specified location.
  3.         int selectRow = tree.getRowForLocation(e.getX(), e.getY());
  4.         // Returns the path for the node at the specified location.
  5.         TreePath selectPath = tree.getPathForLocation(e.getX(), e
  6.                         .getY());
  7.         if (selectPath != null) {
  8.             // set select
  9.             tree.setSelectionPath(selectPath);
  10.             // get tree node.
  11.             DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) selectPath.getLastPathComponent();
  12.       }
复制代码

之后有了树和选择节点就可以做自己的业务逻辑了.

另外JTree的节点的增加、修改和删除也需要看一下,如果我们使用DefaultTreeModel的话,这些操作都很简单,通过它的insertNodeInto、

removeNodeFromParent、nodeChanged等方法就可以实现了,但是如果是我们自己实现的TreeModel,必须再做完数据的操作之后UpdateUI更新界面,

或者学习Sun的事件机制,触发事件然后在View层更新画面,一般都不推荐这么做,除非你的TreeModel的数据特别复杂,没办法使用DefaultTreeModel

这个数据容器,例如TreeTable.

到此,除了JTree的Renderer和Editor之外,只剩下JTree的取数据了.JTree的数据取得我们一般都是用递归,这儿写个从任何节点递归其下所有的例子:

  1.     private List<TreeNode> treeNodeList = new ArrayList<TreeNode>();
  2.     publicvoid getChildNodeList(TreeNode treeNode) {
  3.         if (treeNode == null) {
  4.             thrownew RuntimeException("error treenode.");
  5.         }
  6.         if (treeNodeList == null) {
  7.             treeNodeList = new ArrayList<TreeNode>();
  8.         }
  9.         if (treeNode.getChildCount() >= 0) {
  10.             for (Enumeration<TreeNode> e = treeNode.children(); e
  11.                     .hasMoreElements();) {
  12.                 TreeNode childNode = (TreeNode) e.nextElement();
  13.                 treeNodeList.add(childNode);
  14.                 getChildNodeList(childNode);
  15.             }
  16.         }
  17.     }
复制代码

最后我们看一个Renderer的例子,Sun官方提供的:

附件: 1w.jpg

首先看它的Renderer实现,这个是直接继承DefaultTreeCellRenderer

privateclass MyRenderer extends DefaultTreeCellRenderer {

然后复写它的getTreeCellRendererComponent方法:

    @Override

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,

        boolean hasFocus) {

它的默认实现时一个JLabel,在里面我们就可以设置它的效果了,这里设置一个图片:

setIcon(tutorialIcon);

当然我们也可以继承其它组件,实现TreeCellRenderer接口,实现更多效果.

使用很简单,直接使用JTree的setCellRenderer方法就可以了:

tree.setCellRenderer(new MyRenderer(tutorialIcon));

总 结,基本树的操作和呈现设置都这里就完成了,可以看出,树还是比较简单的,后面我预计还有两个主题,一个是关于JTree的Renderer和 Editor的,在那儿实现一棵树的节点的图片特性,可用与否,选择隐藏等;另外就是关于树的选择框了,其实也是Renderer和Editor的使用, 只不过为了逻辑和应用,做的更复杂。(文/zeyuphoenix )

 

你可能感兴趣的:(swing,tree,sun,Path,Components,jcomponent)