如何使用JTree
来源:互联网 发布:手机淘宝可以注册账号 编辑:程序博客网 时间:2024/06/05 05:11
如何使用 Jtree
(1)创建树
(2)对节点的选择做出响应
(3)自定义树的外观表现
(4)动态改变一棵树
(5)创建树的数据模型
(6)懒加载孩子
(7)如何写expansion linstener
(8)如何写tree-will-expand listener
利用 JTree 类,你可以显示等级体系的数据。一个 JTree对象并没有包含实际的数据;它只是提供了数据的一个视图。像其他非平凡的( nontrivial ) Swing 组件一样,这种Jtree 通过查询她的数据模型获得数据。这是一个 Jtree :
如上面的图片所显示, Jtree 垂直显示它的数据。树中显示的每一行包含一项数据,称之为节点( node)。每颗树有一个根节点( root node),其他所有节点是它的子孙。默认情况下,树只显示根节点,但是你可以设置改变默认显示方式。一个节点可以拥有孩子也可以不拥有任何子孙。我们称那些可以拥有孩子(不管当前是否有孩子)的节点为“分支节点”(branch nodes ),而不能拥有孩子的节点为“叶子节点”( leaf nodes )。
分支节点可以有任意多个孩子。通常,用户可以通过点击实现展开或者折叠分支节点,使得他们的孩子可见或者不可见。默认情况下,除了根节点以外的所有分支节点默认呈现折叠状态。程序中,通过监听tree expansion 或者 tree-will-expand 事件可以检测分支节点的展开状态。监听事件在下面两节内容中描述How to Write a Tree Expansion Listener andHow to Write a Tree-Will-Expand Listener .
(1)创建一棵 Tree
接下来的代码是从
http://download.oracle.com/javase/tutorial/uiswing/examples/components/TreeDemoProject/src/components/TreeDemo.java获得,创建了一个JTree 对象,并将之放到一个scroll pane 上
- //Where
instance variables are declared: -
private JTree tree; -
... -
public TreeDemo() { -
... -
DefaultMutableTreeNode top = -
new DefaultMutableTreeNode("The Java Series"); -
createNodes(top); -
tree = new JTree(top); -
... -
JScrollPane treeView = new JScrollPane(tree); -
... -
}
//Where instance variables are declared: private JTree tree; ... public TreeDemo() { ... DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series"); createNodes(top); tree = new JTree(top); ... JScrollPane treeView = new JScrollPane(tree); ... }
- private
void createNodes(DefaultMutableTreeNode top) { -
DefaultMutableTreeNode category = null; -
DefaultMutableTreeNode book = null; -
-
category = new DefaultMutableTreeNode("Books for Java Programmers"); -
top.add(category); -
-
//original Tutorial -
book = new DefaultMutableTreeNode(new BookInfo -
("The Java Tutorial: A Short Course on the Basics", -
"tutorial.html")); -
category.add(book); -
-
//Tutorial Continued -
book = new DefaultMutableTreeNode(new BookInfo -
("The Java Tutorial Continued: The Rest of the JDK", -
"tutorialcont.html")); -
category.add(book); -
-
//JFC Swing Tutorial -
book = new DefaultMutableTreeNode(new BookInfo -
("The JFC Swing Tutorial: A Guide to Constructing GUIs", -
"swingtutorial.html")); -
category.add(book); -
-
//...add more books for programmers... -
-
category = new DefaultMutableTreeNode("Books for Java Implementers"); -
top.add(category); -
-
//VM -
book = new DefaultMutableTreeNode(new BookInfo -
("The Java Virtual Machine Specification", -
"vm.html")); -
category.add(book); -
-
//Language Spec -
book = new DefaultMutableTreeNode(new BookInfo -
("The Java Language Specification", -
"jls.html")); -
category.add(book); - }
private void createNodes(DefaultMutableTreeNode top) { DefaultMutableTreeNode category = null; DefaultMutableTreeNode book = null; category = new DefaultMutableTreeNode("Books for Java Programmers"); top.add(category); //original Tutorial book = new DefaultMutableTreeNode(new BookInfo ("The Java Tutorial: A Short Course on the Basics", "tutorial.html")); category.add(book); //Tutorial Continued book = new DefaultMutableTreeNode(new BookInfo ("The Java Tutorial Continued: The Rest of the JDK", "tutorialcont.html")); category.add(book); //JFC Swing Tutorial book = new DefaultMutableTreeNode(new BookInfo ("The JFC Swing Tutorial: A Guide to Constructing GUIs", "swingtutorial.html")); category.add(book); //...add more books for programmers... category = new DefaultMutableTreeNode("Books for Java Implementers"); top.add(category); //VM book = new DefaultMutableTreeNode(new BookInfo ("The Java Virtual Machine Specification", "vm.html")); category.add(book); //Language Spec book = new DefaultMutableTreeNode(new BookInfo ("The Java Language Specification", "jls.html")); category.add(book);}
(2)对节点的选择作出响应
对于树节点的选择做出响应是简单的。你可以实现一个树节点选择监听器,并且注册在这棵树上。接下来的代码显示了TreeDemo.java 中有关选择的代码:
- //Where
the tree is initialized: -
tree.getSelectionModel().setSelectionMode -
(TreeSelectionModel.SINGLE_TREE_SELECTION); -
-
//Listen for when the selection changes. -
tree.addTreeSelectionListener (this); -
... -
public void valueChanged(TreeSelectionEvent e) { -
//Returns the last path element of the selection. -
//This method is useful only when the selection model allows a single selection. -
DefaultMutableTreeNode node = (DefaultMutableTreeNode) -
tree.getLastSelectedPathCompo nent(); -
-
if (node == null) -
//Nothing is selected. -
return; -
-
Object nodeInfo = node.getUserObject(); -
if (node.isLeaf()) { -
BookInfo book = (BookInfo)nodeInfo; -
displayURL(book.bookURL); -
} else { -
displayURL(helpURL); -
} - }
//Where the tree is initialized: tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION); //Listen for when the selection changes. tree.addTreeSelectionListener(this); ... public void valueChanged(TreeSelectionEvent e) { //Returns the last path element of the selection. //This method is useful only when the selection model allows a single selection. DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathCompo nent(); if (node == null) //Nothing is selected. return; Object nodeInfo = node.getUserObject(); if (node.isLeaf()) { BookInfo book = (BookInfo)nodeInfo; displayURL(book.bookURL); } else { displayURL(helpURL); }}
上面的代码执行了一下任务:
这里给出一些树节点的图片,分别通过 Java 、 Windows 和 MacOS 样式绘得。
(依次为 java look 、 windows look 和 MacOS look )
像之前图片显示一样,一棵树按照惯例,对于每个基点显示了一个图标和一些文字。像我们简短的展示一样,你可以指定这些样式。
- tree.putClientProperty(“Jtree.lineStyle”,
“Horizontal”);
tree.putClientProperty(“Jtree.lineStyle”, “Horizontal”);
指定 JAVA 样式在节点间不显示任何行线,则使用以下代码:
- tree.putClientProperty(“Jtree.lineStyle”,
“None”);
tree.putClientProperty(“Jtree.lineStyle”, “None”);
(3)自定义树的外观表现
不管你使用那种样式( java、 windows 、mac ) , 默认情况下,节点显示的图标决定于节点是否为叶子节点和是否可展开。例如,在windwos样式中,每个叶子节点的默认图标是一个点;在 JAVA样式中,叶子节点默认图标是一个类似白纸的符号。在所有样式中,分支节点被一个文件夹符号所标识。不同样式对于可展开分支和对应的可折叠分支,可能有不同的图标。
一定你创建了这些图标,使用树的 setCellRender 方法去指定这个 DefaultTreeCellRender 来绘制它的节点。这里有一个来自TreeIconDemo 的例子
- ImageIcon
leafIcon "images/middle.gif");= createImageIcon( - if
(leafIcon null)!= { -
DefaultTreeCellRenderer renderer = -
DefaultTreeCellRenderer(); -
renderer.setLeafIcon(leafIcon); -
tree.setCellRenderer(renderer); - }
ImageIcon leafIcon = createImageIcon("images/middle.gif");if (leafIcon != null) { DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); renderer.setLeafIcon(leafIcon); tree.setCellRenderer(renderer);}
这是一个截图:
如果你想更精巧的控制节点图标,或者你想提供一些工具,你可以创建 DefaultTreeCellRender的子类,然后覆盖他的getTreeCellRendererCompo
- //...where
the tree is initialized: -
//Enable tool tips. -
ToolTipManager.sharedInstance().registerComponent(tree); -
-
ImageIcon tutorialIcon = createImageIcon("images/middle.gif"); -
if (tutorialIcon != null) { -
tree.setCellRenderer(new MyRenderer(tutorialIcon)); -
} - ...
- class
MyRenderer extends DefaultTreeCellRenderer { -
Icon tutorialIcon; -
-
public MyRenderer(Icon icon) { -
tutorialIcon = icon; -
} -
-
public Component getTreeCellRendererCompo nent( -
JTree tree, -
Object value, -
boolean sel, -
boolean expanded, -
boolean leaf, -
int row, -
boolean hasFocus) { -
-
super.getTreeCellRendererCompo nent( -
tree, value, sel, -
expanded, leaf, row, -
hasFocus); -
if (leaf && isTutorialBook(value)) { -
setIcon(tutorialIcon); -
setToolTipText("This book is in the Tutorial series."); -
} else { -
setToolTipText(null); //no tool tip -
} -
-
return this; -
} -
-
protected boolean isTutorialBook(Object value) { -
DefaultMutableTreeNode node = -
(DefaultMutableTreeNode)value; -
BookInfo nodeInfo = -
(BookInfo)(node.getUserObject()); -
String title = nodeInfo.bookName; -
if (title.indexOf("Tutorial") >= 0) { -
return true; -
} -
-
return false; -
} - }
//...where the tree is initialized: //Enable tool tips. ToolTipManager.sharedInstance().registerComponent(tree); ImageIcon tutorialIcon = createImageIcon("images/middle.gif"); if (tutorialIcon != null) { tree.setCellRenderer(new MyRenderer(tutorialIcon)); }...class MyRenderer extends DefaultTreeCellRenderer { Icon tutorialIcon; public MyRenderer(Icon icon) { tutorialIcon = icon; } public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererCompo nent( tree, value, sel, expanded, leaf, row, hasFocus); if (leaf && isTutorialBook(value)) { setIcon(tutorialIcon); setToolTipText("This book is in the Tutorial series."); } else { setToolTipText(null); //no tool tip } return this; } protected boolean isTutorialBook(Object value) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; BookInfo nodeInfo = (BookInfo)(node.getUserObject()); String title = nodeInfo.bookName; if (title.indexOf("Tutorial") >= 0) { return true; } return false; }}
下面是结果的截图:
你可能会疑惑单元绘制器( cell renderer )是如何工作的。当一个 tree 在话每个节点的时候,不管是 Jtree或是他的样式表现都包含了绘制节点的代码。 Tree 可以使用 cell renderer的绘图代码代替前者去绘制节点。例如,画一个包含字符串“ The Java Programming Language ”的叶子节点,tree 会要求 cell renderer 返回一个组件,该组件能够绘制一个包含该字符串的叶子节点。如果这个 cellrenderer 是一个 DefaultTreeCellRender ,它就返回一个 label (DefaultTreeCellRender 继承于 Jlabel ),它绘制默认的叶子节点图标,紧随一段字符串。
(4)动态地改变一棵 Tree
接下来的图片展示了一个叫 DynamicTreeDemo 的应用程序,它允许你从一颗可视 tree中增加或者移除节点。你也可以编辑每个节点的文本。
这里给出了树初始化的代码:
- rootNode
= new DefaultMutableTreeNode("Root Node"); - treeModel
= new DefaultTreeModel(rootNode); - treeModel.addTreeModelListener(new
MyTreeModelListener()); -
- tree
= new JTree(treeModel); - tree.setEditable(true);
- tree.getSelectionModel().setSelectionMode
-
(TreeSelectionModel.SINGLE_TREE_SELECTION); - tree.setShowsRootHandles(true);
rootNode = new DefaultMutableTreeNode("Root Node");treeModel = new DefaultTreeModel(rootNode);treeModel.addTreeModelListener(new MyTreeModelListener());tree = new JTree(treeModel);tree.setEditable(true);tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION);tree.setShowsRootHandles(true);
- class
MyTreeModelListener implements TreeModelListener { -
public void treeNodesChanged(TreeModelEvent e) { -
DefaultMutableTreeNode node; -
node = (DefaultMutableTreeNode) -
(e.getTreePath().getLastPathComponent()); -
-
-
try { -
int index = e.getChildIndices()[0]; -
node = (DefaultMutableTreeNode) -
(node.getChildAt(index)); -
} catch (NullPointerException exc) {} -
-
System.out.println("The user has finished editing the node."); -
System.out.println("New value: " + node.getUserObject()); -
} -
public void treeNodesInserted(TreeModelEvent e) { -
} -
public void treeNodesRemoved(TreeModelEvent e) { -
} -
public void treeStructureChanged(TreeModelEvent e) { -
} - }
class MyTreeModelListener implements TreeModelListener { public void treeNodesChanged(TreeModelEvent e) { DefaultMutableTreeNode node; node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent()); try { int index = e.getChildIndices()[0]; node = (DefaultMutableTreeNode) (node.getChildAt(index)); } catch (NullPointerException exc) {} System.out.println("The user has finished editing the node."); System.out.println("New value: " + node.getUserObject()); } public void treeNodesInserted(TreeModelEvent e) { } public void treeNodesRemoved(TreeModelEvent e) { } public void treeStructureChanged(TreeModelEvent e) { }}
这里是一些增加按钮事件处理器(用于增加节点)的代码:
- treePanel.addObject("New
Node " + newNodeSuffix++); - ...
- public
DefaultMutableTreeNode addObject(Object child) { -
DefaultMutableTreeNode parentNode = null; -
TreePath parentPath = tree.getSelectionPath(); -
-
if (parentPath == null) { -
//There is no selection. Default to the root node. -
parentNode = rootNode; -
} else { -
parentNode = (DefaultMutableTreeNode) -
(parentPath.getLastPathComponent()); -
} -
-
return addObject(parentNode, child, true); - }
- ...
- public
DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, -
Object child, -
boolean shouldBeVisible) { -
DefaultMutableTreeNode childNode = -
new DefaultMutableTreeNode(child); -
... -
treeModel.insertNodeInto(childNode, parent, -
parent.getChildCount()); -
-
//Make sure the user can see the lovely new node. -
if (shouldBeVisible) { -
tree.scrollPathToVisible(new TreePath(childNode.getPath())); -
} -
return childNode; - }
treePanel.addObject("New Node " + newNodeSuffix++);...public DefaultMutableTreeNode addObject(Object child) { DefaultMutableTreeNode parentNode = null; TreePath parentPath = tree.getSelectionPath(); if (parentPath == null) { //There is no selection. Default to the root node. parentNode = rootNode; } else { parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent()); } return addObject(parentNode, child, true);}...public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible) { DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child); ... treeModel.insertNodeInto(childNode, parent, parent.getChildCount()); //Make sure the user can see the lovely new node. if (shouldBeVisible) { tree.scrollPathToVisible(new TreePath(childNode.getPath())); } return childNode;}
(5)创建一个数据模型
在 GenealogyModel.java
中,你可以找到这个自定义的tree model 的实现。因为这个 model 通过一个 DefaultTreeModel 的子类实现,他必须实现TreeModel 接口。这就需要实现获得节点信息的一系列方法,例如,哪个是根节点、某个节点的子孙是哪些节点。在GenealogyModel 的例子中,每个节点表现为一个 Person 类型的对象,这是一个未实现 TreeNode接口的自定义类。
(这里涉及的四个 java 文件都挺值得读,里面的编程思想跟技巧很值得学习)
(6)“懒加载”孩子
- class
DemoArea extends JScrollPane -
-
implements TreeWillExpandListener { -
....... -
....... -
-
private TreeNode createNodes() { -
DefaultMutableTreeNode root; -
DefaultMutableTreeNode grandparent; -
DefaultMutableTreeNode parent; -
-
root = new DefaultMutableTreeNode("San Francisco"); -
grandparent = new DefaultMutableTreeNode("Potrero Hill"); -
root.add(grandparent); -
-
parent = new DefaultMutableTreeNode("Restaurants"); -
grandparent.add(parent); -
-
dummyParent = parent; -
return root; -
-
}
class DemoArea extends JScrollPane implements TreeWillExpandListener { ....... ....... private TreeNode createNodes() { DefaultMutableTreeNode root; DefaultMutableTreeNode grandparent; DefaultMutableTreeNode parent; root = new DefaultMutableTreeNode("San Francisco"); grandparent = new DefaultMutableTreeNode("Potrero Hill"); root.add(grandparent); parent = new DefaultMutableTreeNode("Restaurants"); grandparent.add(parent); dummyParent = parent; return root; }
- TreeNode
rootNode = createNodes(); - tree
= new JTree(rootNode); -
tree.addTreeExpansionListener (this); - tree.addTreeWillExpandListene
r(this); -
....... -
....... -
setViewportView(tree);
TreeNode rootNode = createNodes();tree = new JTree(rootNode); tree.addTreeExpansionListener(this);tree.addTreeWillExpandListene r(this); ....... ....... setViewportView(tree);
- private
void LoadLazyChildren(){ -
DefaultMutableTreeNode child; -
child = new DefaultMutableTreeNode("Thai Barbeque"); -
dummyParent.add(child); -
child = new DefaultMutableTreeNode("Goat Hill Pizza"); -
dummyParent.add(child); -
textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily"); -
} -
-
....... -
....... -
- public
void treeWillExpand(TreeExpansionEvent e) -
throws ExpandVetoException { -
saySomething("You are about to expand node ", e); -
int n = JOptionPane.showOptionDialog( -
this, willExpandText, willExpandTitle, -
JOptionPane.YES_NO_OPTION, -
JOptionPane.QUESTION_MESSAGE, -
null, -
willExpandOptions, -
willExpandOptions[1]); -
-
LoadLazyChildren(); -
}
private void LoadLazyChildren(){ DefaultMutableTreeNode child; child = new DefaultMutableTreeNode("Thai Barbeque"); dummyParent.add(child); child = new DefaultMutableTreeNode("Goat Hill Pizza"); dummyParent.add(child); textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily"); } ....... .......public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException { saySomething("You are about to expand node ", e); int n = JOptionPane.showOptionDialog( this, willExpandText, willExpandTitle, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, willExpandOptions, willExpandOptions[1]); LoadLazyChildren(); }
(7)如何写 Tree Expansion Listener (监听器)
来自 TreeExpandEventDemo.java
.
- private
void LoadLazyChildren(){ -
DefaultMutableTreeNode child; -
child = new DefaultMutableTreeNode("Thai Barbeque"); -
dummyParent.add(child); -
child = new DefaultMutableTreeNode("Goat Hill Pizza"); -
dummyParent.add(child); -
textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily"); -
} -
-
....... -
....... -
- public
void treeWillExpand(TreeExpansionEvent e) -
throws ExpandVetoException { -
saySomething("You are about to expand node ", e); -
int n = JOptionPane.showOptionDialog( -
this, willExpandText, willExpandTitle, -
JOptionPane.YES_NO_OPTION, -
JOptionPane.QUESTION_MESSAGE, -
null, -
willExpandOptions, -
willExpandOptions[1]); -
-
LoadLazyChildren(); -
}
private void LoadLazyChildren(){ DefaultMutableTreeNode child; child = new DefaultMutableTreeNode("Thai Barbeque"); dummyParent.add(child); child = new DefaultMutableTreeNode("Goat Hill Pizza"); dummyParent.add(child); textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily"); } ....... .......public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException { saySomething("You are about to expand node ", e); int n = JOptionPane.showOptionDialog( this, willExpandText, willExpandTitle, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, willExpandOptions, willExpandOptions[1]); LoadLazyChildren(); }
(8)如何写 Tree-Will-Expand Listener
TreeExpandEventDemo2.java
- 如何使用JTree
- 如何使用 Jtree
- 如何使用JTree
- 如何使用JTree
- 如何使用 Jtree
- Java Swing 如何使用JTree(1)
- Java Swing 如何使用JTree(2)
- Java Swing 如何使用JTree(3)
- 使用JTree
- 如何设置jtree 图标
- JTree用法及JTree使用经验总结
- JTree用法及JTree使用经验总结(转)
- JTree用法及JTree使用经验总结(转)
- JTree用法及JTree使用经验总结
- JTree用法及JTree使用经验总结(转)
- JTree用法及JTree使用经验总结
- JTree用法及JTree使用经验总结
- JTree用法及JTree使用经验总结
- java中的递归调用
- 40 位改变了互联网的人(上…
- 马云的三大信仰
- JS中的window.setTimeout()…
- Linux命令行操作基础
- 如何使用JTree
- XManager5连接CentOS7
- Linux7.3.1611安装Oracle11g
- CentO7安装部署应用服务器—resin
- 【数据结构实验八】排序
- Oracle的KILL锁表及清除sess…
- js 获取浏览器类别
- 1.android studio配置----Terminal命令窗口
- Oracle的KILL锁表及清除sess…