- 浏览: 151060 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jinianjun:
请问加的那个函数是什么意思呢?
Linux下DHCP不能自动获取IP问题解决 -
liujiaoshui:
看来你们都没玩过《天龙八部》,那才真 叫一个坑,MB的,有个3 ...
淘宝,真的好烦啊。 -
云中苍月:
呃。。这位仁兄忘性真不小。别怪TB了,自己找个小本本把账号/密 ...
淘宝,真的好烦啊。 -
finallygo:
这也是我不用支付宝的原因
淘宝,真的好烦啊。 -
三单联咖啡色:
涉及到个人财产,还是复杂点的好,自己修改密码都那么麻烦,那其他 ...
淘宝,真的好烦啊。
Let me explain what is "JTree with CheckBoxes".
Each node of the JTree contains a CheckBox.
When a node's checkbox is selected, all its descendants should also get checked and vice versa.
When all descendants of a node are not checked but some of them are checked (i.e, partial selection) then the node should be checked with a gray tick.
When all children of a node are unselected, the node should unselected.
If you google for "JTree CheckBox" you will get :
http://www.java2s.com/ExampleCode/Swing-Components/CheckboxNodeTreeExample.htm
There are many drawbacks in the above implementation. The major drawback is, It restricts to use DefaultTreeModel whose nodes are CheckNode.
JTree should have two selections: one is normal selection and another is checkSelection (checkbox selected)
Why don't we use TreeSelectionModel to maintain checkSelection. But we can't use DefaultTreeSelection as-it-is without any changes. because we have to restrict the selection as explained in the above points:
In our check selection model, it contains only the selected node but not all its descendants. i.e. let us say Node A has children B, C, D;
When user checks Node A, the tree shows B, C and D also checked. But the selectionModel actually contains only A,
You can ask the the above selection model whether B is selected as below:
checkSelectionModel.isPathSelected(getPath(B), true); // the second argument tells that selection is to be digged.
Please take time to understand the above code (It is little bit complex, I guess).
As usual we attacked the model. next is renderer, In the google link I specified in the beginning restricts you to use its renderer. But in our implementation we let user add checkbox to any TreeCellRenderer:
I used TristateCheckBox from http://www.javaspecialists.co.za/archive/Issue082.html
We can also implement editor in the same way such that it can wrap any TreeCellEditor implementation. But I am leaving it as exercise for you
The next question comes is:
We have SelectionModel and renderer. But who will listen of mouseclicks in checkbox and update the selectionmodel ???
updates the tree (repaints) when checkselection is changed
listens for selectionmodel changes and updates the view. Because it allows you tocheck a node programmatically..
How to use this:
// makes your tree as CheckTree
CheckTreeManager checkTreeManager = new CheckTreeManager(yourTree);
// to get the paths that were checked
TreePath checkedPaths[] = checkTreeManager.getSelectionModel().getSelectionPaths();
See how powerful our solution is:
You can convert any JTree (with any TreeModel and any TreeCellRenderer) just by one line.
normal selection doesn't interfere with checkselection. In the google link i specified, when you select a node, it gets checked.
you can reuse your renderers/editors
The webstart demo shows the selection at the bottom of the window in a JLable. This lets you understand how our CheckSelectionModel is updated with your changes to checkselection.
Each node of the JTree contains a CheckBox.
When a node's checkbox is selected, all its descendants should also get checked and vice versa.
When all descendants of a node are not checked but some of them are checked (i.e, partial selection) then the node should be checked with a gray tick.
When all children of a node are unselected, the node should unselected.
If you google for "JTree CheckBox" you will get :
http://www.java2s.com/ExampleCode/Swing-Components/CheckboxNodeTreeExample.htm
There are many drawbacks in the above implementation. The major drawback is, It restricts to use DefaultTreeModel whose nodes are CheckNode.
JTree should have two selections: one is normal selection and another is checkSelection (checkbox selected)
Why don't we use TreeSelectionModel to maintain checkSelection. But we can't use DefaultTreeSelection as-it-is without any changes. because we have to restrict the selection as explained in the above points:
In our check selection model, it contains only the selected node but not all its descendants. i.e. let us say Node A has children B, C, D;
When user checks Node A, the tree shows B, C and D also checked. But the selectionModel actually contains only A,
// @author Santhosh Kumar T - santhosh@in.fiorano.com public class CheckTreeSelectionModel extends DefaultTreeSelectionModel{ private TreeModel model; public CheckTreeSelectionModel(TreeModel model){ this.model = model; setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); } // tests whether there is any unselected node in the subtree of given path public boolean isPartiallySelected(TreePath path){ if(isPathSelected(path, true)) return false; TreePath[] selectionPaths = getSelectionPaths(); if(selectionPaths==null) return false; for(int j = 0; j<selectionPaths.length; j++){ if(isDescendant(selectionPaths[j], path)) return true; } return false; } // tells whether given path is selected. // if dig is true, then a path is assumed to be selected, if // one of its ancestor is selected. public boolean isPathSelected(TreePath path, boolean dig){ if(!dig) return super.isPathSelected(path); while(path!=null && !super.isPathSelected(path)) path = path.getParentPath(); return path!=null; } // is path1 descendant of path2 private boolean isDescendant(TreePath path1, TreePath path2){ Object obj1[] = path1.getPath(); Object obj2[] = path2.getPath(); for(int i = 0; i<obj2.length; i++){ if(obj1!=obj2) return false; } return true; } public void setSelectionPaths(TreePath[] pPaths){ throw new UnsupportedOperationException("not implemented yet!!!"); } public void addSelectionPaths(TreePath[] paths){ // unselect all descendants of paths[] for(int i = 0; i<paths.length; i++){ TreePath path = paths; TreePath[] selectionPaths = getSelectionPaths(); if(selectionPaths==null) break; ArrayList toBeRemoved = new ArrayList(); for(int j = 0; j<selectionPaths.length; j++){ if(isDescendant(selectionPaths[j], path)) toBeRemoved.add(selectionPaths[j]); } super.removeSelectionPaths((TreePath[])toBeRemoved.toArray(new TreePath[0])); } // if all siblings are selected then unselect them and select parent recursively // otherwize just select that path. for(int i = 0; i<paths.length; i++){ TreePath path = paths; TreePath temp = null; while(areSiblingsSelected(path)){ temp = path; if(path.getParentPath()==null) break; path = path.getParentPath(); } if(temp!=null){ if(temp.getParentPath()!=null) addSelectionPath(temp.getParentPath()); else{ if(!isSelectionEmpty()) removeSelectionPaths(getSelectionPaths()); super.addSelectionPaths(new TreePath[]{temp}); } }else super.addSelectionPaths(new TreePath[]{ path}); } } // tells whether all siblings of given path are selected. private boolean areSiblingsSelected(TreePath path){ TreePath parent = path.getParentPath(); if(parent==null) return true; Object node = path.getLastPathComponent(); Object parentNode = parent.getLastPathComponent(); int childCount = model.getChildCount(parentNode); for(int i = 0; i<childCount; i++){ Object childNode = model.getChild(parentNode, i); if(childNode==node) continue; if(!isPathSelected(parent.pathByAddingChild(childNode))) return false; } return true; } public void removeSelectionPaths(TreePath[] paths){ for(int i = 0; i<paths.length; i++){ TreePath path = paths; if(path.getPathCount()==1) super.removeSelectionPaths(new TreePath[]{ path}); else toggleRemoveSelection(path); } } // if any ancestor node of given path is selected then unselect it // and selection all its descendants except given path and descendants. // otherwise just unselect the given path private void toggleRemoveSelection(TreePath path){ Stack stack = new Stack(); TreePath parent = path.getParentPath(); while(parent!=null && !isPathSelected(parent)){ stack.push(parent); parent = parent.getParentPath(); } if(parent!=null) stack.push(parent); else{ super.removeSelectionPaths(new TreePath[]{path}); return; } while(!stack.isEmpty()){ TreePath temp = (TreePath)stack.pop(); TreePath peekPath = stack.isEmpty() ? path : (TreePath)stack.peek(); Object node = temp.getLastPathComponent(); Object peekNode = peekPath.getLastPathComponent(); int childCount = model.getChildCount(node); for(int i = 0; i<childCount; i++){ Object childNode = model.getChild(node, i); if(childNode!=peekNode) super.addSelectionPaths(new TreePath[]{temp.pathByAddingChild(childNode)}); } } super.removeSelectionPaths(new TreePath[]{parent}); } }
You can ask the the above selection model whether B is selected as below:
checkSelectionModel.isPathSelected(getPath(B), true); // the second argument tells that selection is to be digged.
Please take time to understand the above code (It is little bit complex, I guess).
As usual we attacked the model. next is renderer, In the google link I specified in the beginning restricts you to use its renderer. But in our implementation we let user add checkbox to any TreeCellRenderer:
public class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer{ private CheckTreeSelectionModel selectionModel; private TreeCellRenderer delegate; private TristateCheckBox checkBox = new TristateCheckBox(); public CheckTreeCellRenderer(TreeCellRenderer delegate, CheckTreeSelectionModel selectionModel){ this.delegate = delegate; this.selectionModel = selectionModel; setLayout(new BorderLayout()); setOpaque(false); checkBox.setOpaque(false); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){ Component renderer = delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); TreePath path = tree.getPathForRow(row); if(path!=null){ if(selectionModel.isPathSelected(path, true)) checkBox.setState(Boolean.TRUE); else checkBox.setState(selectionModel.isPartiallySelected(path) ? null : Boolean.FALSE); } removeAll(); add(checkBox, BorderLayout.WEST); add(renderer, BorderLayout.CENTER); return this; } }The above renderer can wrap any of your TreeCellRenderer implementation.
I used TristateCheckBox from http://www.javaspecialists.co.za/archive/Issue082.html
We can also implement editor in the same way such that it can wrap any TreeCellEditor implementation. But I am leaving it as exercise for you
The next question comes is:
We have SelectionModel and renderer. But who will listen of mouseclicks in checkbox and update the selectionmodel ???
Here is that class, CheckTreeManager: public class CheckTreeManager extends MouseAdapter implements TreeSelectionListener{ private CheckTreeSelectionModel selectionModel; private JTree tree = new JTree(); int hotspot = new JCheckBox().getPreferredSize().width; public CheckTreeManager(JTree tree){ this.tree = tree; selectionModel = new CheckTreeSelectionModel(tree.getModel()); tree.setCellRenderer(new CheckTreeCellRenderer(tree.getCellRenderer(), selectionModel)); tree.addMouseListener(this); selectionModel.addTreeSelectionListener(this); } public void mouseClicked(MouseEvent me){ TreePath path = tree.getPathForLocation(me.getX(), me.getY()); if(path==null) return; if(me.getX()>tree.getPathBounds(path).x+hotspot) return; boolean selected = selectionModel.isPathSelected(path, true); selectionModel.removeTreeSelectionListener(this); try{ if(selected) selectionModel.removeSelectionPath(path); else selectionModel.addSelectionPath(path); } finally{ selectionModel.addTreeSelectionListener(this); tree.treeDidChange(); } } public CheckTreeSelectionModel getSelectionModel(){ return selectionModel; } public void valueChanged(TreeSelectionEvent e){ tree.treeDidChange(); } }It listens for mouse clicks in the hotspot (inside checkbox) and updates the selection
updates the tree (repaints) when checkselection is changed
listens for selectionmodel changes and updates the view. Because it allows you tocheck a node programmatically..
How to use this:
// makes your tree as CheckTree
CheckTreeManager checkTreeManager = new CheckTreeManager(yourTree);
// to get the paths that were checked
TreePath checkedPaths[] = checkTreeManager.getSelectionModel().getSelectionPaths();
See how powerful our solution is:
You can convert any JTree (with any TreeModel and any TreeCellRenderer) just by one line.
normal selection doesn't interfere with checkselection. In the google link i specified, when you select a node, it gets checked.
you can reuse your renderers/editors
The webstart demo shows the selection at the bottom of the window in a JLable. This lets you understand how our CheckSelectionModel is updated with your changes to checkselection.
发表评论
-
SLF4J这东西太邪恶了
2011-09-02 23:54 929版本弄得乱七八遭的。动不动就报错。 老子恨他不是一年两年了! ... -
每秒多少次是怎么算出来的?
2011-08-05 15:47 1121看到有的大拿写他写的程序执行效率高,每秒多少次,多少次,这个次 ... -
最简获取文件扩展名
2011-05-10 15:42 3467写道 fileName.replaceAll(" ... -
log4j.properties记录
2010-04-06 15:21 939log4j.rootLogger=All,A1,A2,A3 ... -
全面的汉字转拼音与读音包
2009-10-30 23:28 1772最近因需要做汉字转拼音的一个小功能,上网找了一些,不是很好用, ... -
JFreeChart1.0.13API
2009-04-26 01:34 1559方便自己看,也拿出来,方便大家看:)希望有用吧~ -
JTree 的装饰器演示
2009-01-05 10:13 1411今天工作中,遇到小问 ... -
全半角转换
2008-12-07 21:09 1073[size=medium]/** * 半角转全角 ... -
Java调用jacob出错问题:java.library.path解决
2008-11-10 10:22 8284关于java使用jacob.jar调用word的配置问题 最 ... -
JMF
2008-11-08 23:51 1880Java术语 术语名称:Java媒体框架(JMF) ... -
使用JMF播放音乐
2008-11-08 23:48 4100[size=medium]转载的!! JMF现在还不支持WM ... -
处理文件夹有空格问题及按系统方式打开文件
2008-10-31 09:37 3085[size=medium]取得文件路径: String fil ... -
创建数组的几种方式
2008-10-26 14:35 1322在C语言中: Example: 1、 int nu ... -
java中实现IP地址的各种表现形式之间的转换
2008-10-24 11:34 1399[size=medium]class ip { pri ... -
HttpClient之Session维持
2008-10-23 18:15 10717由于需要,用到了HttpClient在网上查阅了很多资料 ... -
在Swing UI界面定义默认获得焦点的组件
2008-10-23 09:49 8941最近写了个小的UI界面的程序.程序运行后,为方便使用,应该自动 ... -
Serializable java序列化
2008-10-21 14:57 1502[size=medium]Bean Serializable ...
相关推荐
Jtree with checkbox and textField
在特定场景下,我们可能希望在`JTree`的节点上添加复选框(CheckBox),以便用户可以进行多选操作。在本示例中,我们将深入探讨如何实现`JTree`与复选框结合的代码实例。 首先,我们需要创建一个自定义的`...
JFrame frame = new JFrame("JTree with CheckBoxes"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new JScrollPane(tree)); frame.pack(); frame.setVisible(true); ...
在Java Swing库中,JTree组件是一个非常有用的可视化控件,用于展示层次化的数据结构,如文件系统目录或组织结构图。这篇博文将探讨如何在Java应用程序中有效地使用JTree。 首先,理解JTree的基本概念至关重要。...
在Java Swing库中,`JTree`是一个组件,用于显示层次结构的数据,而`JCheckBox`则是一个可以勾选或取消勾选的图形用户界面元素。将`JCheckBox`与`JTree`结合使用,可以在树形结构的节点上提供复选框功能,允许用户...
在Java的Swing库中,`JTree`组件是一个用于展示层次数据的控件,它以树状结构显示数据。`jtree`标题所指的可能是关于如何在`JTree`中添加复选框(checkboxes)的功能。这通常是为了让用户能够多选树中的节点,进行...
### 如何使用JTree:详解与实践 #### JTree简介 `JTree`是Java Swing中的一个组件,用于展示层次化的数据结构。它允许用户在应用程序中构建树形视图来表示目录结构、组织结构图等。`JTree`继承自`JComponent`类,...
实现jTable和jTree的双向联动,点击jTree会选中jTable单元格,点击jTable会选中jTree节点。
在Java Swing库中,`JTree`是一个非常重要的组件,用于显示和操作树形数据结构。这个例子展示了如何实现一个可拖动节点的`JTree`,这在用户界面设计中是一个常见且实用的功能,特别是在需要展示层次结构信息时。`...
在Java Swing库中,JTree和JTable是两个非常重要的组件,它们被广泛用于构建用户界面,特别是处理数据展示和交互。JTree用于显示层次结构的数据,而JTable则适用于二维表格形式的数据展现。 首先,我们来深入了解...
**JTree 深度解析** `JTree` 是Java Swing库中的一个重要组件,它用于在用户界面中显示树状数据结构。这个组件允许用户以图形化的方式浏览和操作层次结构的数据,例如文件系统目录、数据库结构或者组织结构图。在...
在Java Swing库中,`JTree`和`JTable`是两种非常重要的组件,用于创建用户界面。`JTree`通常用于展示层次化的数据结构,而`JTable`则适用于二维表格数据的显示和操作。本项目是关于如何在Java应用程序中结合使用这两...
在IT领域,尤其是在Web开发中,`JTree`是一个常用组件,它用于在用户界面中展示数据的层次结构,比如文件系统、组织架构等。在本案例中,我们讨论的是一个使用JavaScript实现的JTree,这通常是通过HTML、CSS和...
### Java组件之JTree使用详解 #### 一、引言 `JTree`是Java Swing中的一个重要组件,用于展示层次化的数据结构。它提供了一种直观的方式来表示具有层级关系的数据,例如文件系统的目录结构或者组织架构等。本文将...
**JTree的Doc文档详解** Java Swing库中的`JTree`组件是用于显示和操作树状数据结构的可视化工具。这个组件允许用户以图形化的方式查看层次化的信息,如文件系统目录、数据库结构或者应用程序的对象模型。在Java...
在IT领域,JTree是一种广泛使用的Java Swing组件,它允许用户以树形结构来展示数据。这个组件在GUI(图形用户界面)应用中特别常见,因为它能清晰地组织层次化的信息,比如文件系统目录、数据库结构或者项目组织。...
### JTree用法详解:Swing中的树状结构控件 在Java Swing中,`JTree`是一个非常重要的组件,用于展示层次结构的数据,如文件系统、组织结构图等。本文将详细介绍`JTree`的各种使用方法,包括如何创建、自定义外观、...
**JTree 2.0:构建直观的目录树视图** `JTree`是Java Swing库中的一个组件,用于在用户界面中展示层次结构数据,通常表现为目录树的形式。在`JTree2.0`版本中,这个组件得到了进一步的改进和增强,提供更丰富的功能...
在Java编程中,`JTree`是Swing库中的一个组件,用于展示树形数据结构。这个组件在GUI(图形用户界面)应用中非常常见,因为它可以清晰地展示层次关系的数据,比如文件系统目录结构。在Java中动态实现二叉树,即在...
### JTree的用法详解 #### 一、引言 `JTree` 是 Java Swing 库中的一个重要组件,用于在图形用户界面 (GUI) 中显示层次结构数据。它非常适合用来展示具有分层关系的信息,例如文件系统目录结构、组织结构等。 ####...