引自:http://blog.csdn.net/jimmy292/archive/2010/03/03/5341192.aspx
1.1 创建树组件
1.1.1 最简方式 :
JTree tree = new JTree();
在显示时,树组件会带上JTree默认的节点。
1.1.2 指定树的节点后创建树:
DefaultMutableTreeNode root = new DefaultMutableTreeNode( " 根节点 " );
root.add( new DefaultMutableTreeNode( " 子节点 " ));
JTree tree = new JTree(root);
1.1.3 将树加入到面板中
以下是将树加上滚动窗格后加入一个面板的示例程序。
JPanel panel = new JPanel();
panel.setLayout( new GridLayout( 1 , 1 ));
panel.add( new JScrollPane(tree));
1.2 树节点相关
1.2.1 取得树的根节点
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
1.2.2 更新树的根节点
DefaultMutableTreeNode newRoot = ;
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
model.setRoot(newRoot);
model.reload();
tree.updateUI();
1.2.3 从一个节点开始递归遍历其下的所有节点
private String getNodeText(DefaultMutableTreeNode node){
Category category = (Category)node.getUserObject();
StringBuilder sb = new StringBuilder(category.getText());
if (node.getChildCount() >= 0 ) {
for (Enumeration <?> e = node.children(); e.hasMoreElements(); ) {
DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)e.nextElement();
sb.append(getNodeText(childNode));
}
}
return sb.toString();
}
1.2.4 在某节点下创建一个节点
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode();
childNode.setUserObject( );
parentNode.add(childNode);
1.2.5 节点改名
Category selectedCategory = (Category)clickedNode.getUserObject();
selectedCategory.setName( " " );
clickedNode.setUserObject(selectedCategory);
1.2.6 删除节点
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
model.removeNodeFromParent(clickedNode);
注意被删除的节点必须有父节点,若要删除根节点直接用null去替代原有根节点即可,
1.2.7 遍历用户选择的树节点
TreePath[] paths = tree.getSelectionPaths();
for (TreePath selPath:paths){
Object[] nodes = selPath.getPath();
DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes[nodes.length - 1 ];
// 对node进行处理
}
1.3 树的事件处理
1.3.1 左键点击事件处理
tree.addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY()); // 返回节点所在的行,-1表示鼠标定位不在显示的单元边界内
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); // 返回指定节点的树路径
boolean condition = true ;
condition = condition && (selRow != - 1 ); // 如果选中
// condition = condition && (e.getButton() == 1); // 左键 e.getButton() == 1 右键 e.getButton() == 3
condition = condition && (e.getClickCount() == 1 ); // 单击
// 如果是左键点击
if (condition == true && (e.getButton() == 1 )) {
Object[] nodes = selPath.getPath();
DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes[nodes.length - 1 ];
Category selectedCategory = (Category)node.getUserObject();
}
}
});
1.3.2 在树节点上点击右键弹出右键菜单
tree.addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY()); // 返回节点所在的行,-1表示鼠标定位不在显示的单元边界内
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); // 返回指定节点的树路径
boolean condition = true ;
condition = condition && (selRow != - 1 ); // 如果选中
condition = condition && (e.getClickCount() == 1 ); // 单击
// 如果是右键点击
if (condition == true && (e.getButton() == 3 )){
Object[] nodes = selPath.getPath();
DefaultMutableTreeNode rightClickedNode = (DefaultMutableTreeNode) nodes[nodes.length - 1 ];
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
1.4 树的渲染
1.4.1 树节点渲染器示例
public class CategoryNodeRenderer extends DefaultTreeCellRenderer{
private static final long serialVersionUID = 8532405600839140757L ;
private static final ImageIcon categoryLeafIcon = new ImageIcon(CategoryNodeRenderer. class .getResource( " /categoryLeaf.gif " ));
private static final ImageIcon openFolderIcon = new ImageIcon(CategoryNodeRenderer. class .getResource( " /openFolder.gif " ));
private static final ImageIcon closedFolderIcon = new ImageIcon(CategoryNodeRenderer. class .getResource( " /closedFolder.gif " ));
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus){
super .getTreeCellRendererComponent(tree,
value,
sel,
expanded,
leaf,
row,
hasFocus);
if (leaf){
setIcon(categoryLeafIcon);
}
else if (expanded){
setIcon(openFolderIcon);
}
else {
setIcon(closedFolderIcon);
}
return this ;
}
}
1.4.2 用树节点渲染器渲染一棵树
DefaultMutableTreeNode root = null ;
JTree tree = new JTree(root);
tree.setCellRenderer( new CategoryNodeRenderer());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
一个目录缓存设计的进化过程:
任务:数据库中有六千余条目录(id,pid,name)数据组成一棵目录树,需要通过WebService服务提供给客户端显示出来(Swing中的JTree)。
实现功能的第一步:在客户端的树显示时通过网络得到顶层目录,再根据用户的点击逐级展开下级目录。此方案优点:实现简单;缺点:点击多次容易使人厌烦,速度不行。
客户端实现改善的第二步:启动一个线程从服务器加载数据逐渐生成一个节点树,再交给界面上的JTree命其更新。此举对操作友好型有改进,速度上也有所提高。
客户端实现改善的第三步:先起线程从服务器端一次性下载完全部数据,而后置入内存,再以此为基础构建树。此举对速度也有明显提高。
客户端实现改善的第四步:将已经加载的节点从内存中删除,使查找时间逐渐减小。此举对速度有一定提高。
服务器端实现改善的第四步:不使用Hibernate的对象映射而单独遴选字段组建成一个包装类,此举对速度有一定提高。
服务器端实现改善的第五步:直接采用优化的存储过程将表中必要行集的数据在数据库段形成大文本,一次性传出,WS服务器端只负责传输,此举对速度有明显提高。
通过以上措施,完成包括六千个节点的树显示速度数量级的提高,综合评价一下,以上逐步中,第三步:在客户端另起线程从内存加载数据形成一棵完整的节点树再通知界面更新 和 第五步:通过存储过程直接取得行集合并结果对提高速度帮助最大。
分享到:
相关推荐
例如,在已经添加的节点中不能更改其文本信息和图片信息,而且所有的叶子节点的图片都是通过 DefaultTreeCellRenderer 的方法 setLeafIcon() 来实现的,这点在实际的软件开发中是一个致命的漏洞。 为了解决这个问题...
// 设置叶子节点不采用图标 treeCellRenderer.setClosedIcon(null);// 设置节点折叠时不采用图标 treeCellRenderer.setOpenIcon(null);// 设置节点展开时不采用图标 Enumeration<?> enumeration; // 按...
// 自定义叶子节点的图标 setIcon(leafIcon); } else if (expanded) { // 自定义展开节点的图标 setIcon(openIcon); } else { // 自定义未展开节点的图标 setIcon(closeIcon); } return c; } }); ``` ...
6. **Icons**:可以通过设置图标来美化`JTree`,例如,可以为展开的节点、未展开的节点、叶子节点设置不同的图标。 7. **Rendering**:`JTree`使用`TreeCellRenderer`来决定如何显示每个节点,包括文本颜色、字体、...
leafIcon: 'fa fa-file' // 叶子节点图标 } }); ``` - **操作JTree**:通过提供的API进行节点的操作,例如添加、删除、更新节点。 ```javascript // 添加节点 tree.addNode({ text: '新节点', parent: '节点1' }...
- **图标支持**: 每个节点可以关联一个图标,表示其状态,如打开、关闭、叶子节点等。 - **键盘导航**: 用户可以通过键盘进行导航和操作,如使用`Space`键展开/折叠节点,`Arrow`键移动焦点。 ### 3. JTree的使用...
- `isExpanded(int row)` 和 `isLeaf(int row)` 分别检查节点是否展开和是否为叶子节点。 6. **数据绑定**: - JTree可以与JavaBeans或其他数据源绑定,通过`Binding`机制实现数据的动态更新。 7. **性能优化**...
TreeNode类可以代表一个叶子节点(没有子节点)或一个分支节点(有子节点)。你可以根据需要创建自定义的TreeModel来适应特定的数据结构。 其次,**事件处理**是JTree交互性的关键。JTree提供了多种事件监听器,如...
Java Swing 中的 JTree 是一个用于展示层次结构数据的组件,它使用类似文件系统目录的图形界面,由一系列节点组成,这些节点可以是文件夹或叶子节点。文件夹节点可以有子节点,而叶子节点没有。JTree 依赖于一个模型...
//设置叶子节点图标为空 renderer.setClosedIcon(null); //设置关闭节点的图标为空 renderer.setOpenIcon(null); //设置打开节点的图标为空 tree.addTreeSelectionListener(new TreeSelectionListener() {//...
//设置叶子节点图标为空 renderer.setClosedIcon(null); //设置关闭节点的图标为空 renderer.setOpenIcon(null); //设置打开节点的图标为空 tree.addTreeSelectionListener(new ...
此外,DefaultMutableTreeNode还提供了isLeaf()方法来判断节点是否为叶子节点。 3. **TreeModel接口**: TreeModel是树数据模型的接口,定义了树结构如何被访问和修改。Swing中的JTree组件使用这个接口来获取和...
4. **图标**:JTree可以为不同状态的节点设置不同的图标,比如展开、折叠、叶子节点等,通过设置CellRenderer来定制节点的外观。 5. **事件处理**:当用户与JTree交互时,会触发相应的事件,如TreeSelectionEvent。...
禁用节点可以是叶子节点(无子节点)或非叶子节点(有子节点)。 8. **仅文本节点**: `OnlyTextTreeExample.java`则专注于仅显示文本的节点,没有图标或其他视觉装饰,简化了界面,使其更加专注和清晰。 9. **...
每个节点代表一个项目,可以包含子节点或叶子节点(没有子节点的项)。用户可以通过点击加号(+)或减号(-)图标来展开或折叠节点,从而查看或隐藏子级内容。这种交互方式使用户能够快速浏览和访问大量信息,尤其...
实例中,通过设置不同的图标来区分展开、折叠和叶子节点,同时可以设置背景颜色和选中颜色。 6. **事件监听**: 实例中使用了`ActionListener`来处理按钮点击事件。`addSiblingButton`、`addChildButton`和`delete...
树形控件(Tree Control)是一种控件元素,它以层级结构显示数据,每个层级称为一个节点,节点可以包含子节点或叶子节点。通常,根节点位于顶部,而叶子节点没有子节点。用户可以通过展开和折叠节点来查看或隐藏子...
- `setLeafIcon(ImageIcon icon)`:设置叶子节点的图标。 - `setTextSelectionColor(Color color)`:设置选中时文本的颜色。 - `setFont(Font font)`:设置字体。 6. **TreeSelectionListener:** - **用途**:...
根节点没有父节点,而叶子节点则没有子节点。通过展开和折叠节点,用户可以方便地浏览和操作多层次的信息。 2. **工作原理** 树型控件通常由一个控件容器和一组可交互的节点构成。用户可以通过点击加号(+)来展开...