java JTree JCheckBox樹(shù)復(fù)選框詳解
本文實(shí)例為大家分享了java JTree JCheckBox樹(shù)復(fù)選框展示的具體代碼,供大家參考,具體內(nèi)容如下
1.CheckTreeManager.java
public class CheckTreeManager extends MouseAdapter implements TreeSelectionListener { private CheckTreeSelectionModel selectionModel = null; // private JTree tree = new JTree(); private JTree tree = null; 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); //鼠標(biāo)監(jiān)聽(tīng) selectionModel.addTreeSelectionListener(this); //樹(shù)選擇監(jiān)聽(tīng) } 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(); } }
2.CheckTreeSelectionModel.java
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[i]!=obj2[i]) 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[i]; 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[i]; 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[i]; 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}); } }
3.CheckTreeCellRenderer .java
public class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer { private CheckTreeSelectionModel selectionModel; private TreeCellRenderer delegate; // private TristateCheckBox checkBox = new TristateCheckBox(); private JCheckBox checkBox = new JCheckBox(); 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) { System.out.println(path); if(selectionModel.isPathSelected(path, true)) checkBox.setSelected(true); else { System.out.println(selectionModel.isPartiallySelected(path)); checkBox.setSelected(selectionModel.isPartiallySelected(path) ? true : false); } } removeAll(); add(checkBox, BorderLayout.WEST); add(renderer, BorderLayout.CENTER); return this; } }
4.用法
CheckTreeManager checkTreeManager = new CheckTreeManager(jTree);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)
在開(kāi)發(fā)中,動(dòng)態(tài)數(shù)據(jù)源配置還是用的比較多的,比如在多數(shù)據(jù)源使用方面,又或者是在多個(gè)DB之間切換方面。這里給出一個(gè)動(dòng)態(tài)數(shù)據(jù)源的配置方案,感興趣的可以了解一下2021-07-07Java基于中介者模式實(shí)現(xiàn)多人聊天室功能示例
這篇文章主要介紹了Java基于中介者模式實(shí)現(xiàn)多人聊天室功能,詳細(xì)分析了中介者模式的概念、原理以及使用中介模式實(shí)現(xiàn)多人聊天的步驟、操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-05-05Java數(shù)據(jù)結(jié)構(gòu)之單鏈表詳解
在之前的學(xué)習(xí)中,我們主要了解了很多 Java 的 基本語(yǔ)法,但是在之后的 Java學(xué)習(xí)中,了解基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)的知識(shí)非常重要,數(shù)據(jù)結(jié)構(gòu)的思想可以幫助我們更加清晰明白的了解 Java 的解題思路等等.今天我們就來(lái)開(kāi)始學(xué)習(xí)實(shí)現(xiàn)一個(gè)Java基礎(chǔ)的單鏈表,需要的朋友可以參考下2021-05-05Java實(shí)現(xiàn)的數(shù)組去重與排序操作詳解
這篇文章主要介紹了Java實(shí)現(xiàn)的數(shù)組去重與排序操作,結(jié)合實(shí)例形式分析了Java針對(duì)數(shù)組去重及排序操作相關(guān)遍歷、排序、判斷等使用技巧與注意事項(xiàng),需要的朋友可以參考下2018-07-07Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案
這篇文章主要介紹了Spring?@Cacheable注解類內(nèi)部調(diào)用失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01