/** * Based on CheckTreeManager (rev 120, 2007-07-20) * By Santhosh Kumar T * https://java.net/projects/myswing * * https://java.net/projects/myswing/sources/svn/content/trunk/src/skt/swing/tree/check/CheckTreeManager.java?rev=120 */ /** * MySwing: Advanced Swing Utilites * Copyright (C) 2005 Santhosh Kumar T * <p/> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * <p/> * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package net.vhati.modmanager.ui.tree; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import net.vhati.modmanager.ui.tree.ChecklistTreePathFilter; import net.vhati.modmanager.ui.tree.ChecklistTreeSelectionModel; public class ChecklistTreeManager extends MouseAdapter implements TreeSelectionListener { private ChecklistTreeSelectionModel selectionModel; private ChecklistTreePathFilter checklistFilter; protected JTree tree = new JTree(); protected int checkMaxX = 0; /** * Constructor. * * Modifies a given tree to add checkboxes. * - The tree's existing cell renderer will be wrapped with a ChecklistTreeCellRenderer. * - A MouseListener will be added to the tree to detect clicks, which will toggle checkboxes. * * A secondary ChecklistTreeSelectionModel will track checkboxes' states (independent of row * highlighting). * * @param tree a tree to modify * @param dig true show that a node is partially selected by scanning its descendents, false otherwise * @checklistFilter a filter to decide which TreePaths need checkboxes, or null */ public ChecklistTreeManager( JTree tree, boolean dig, ChecklistTreePathFilter checklistFilter ) { this.tree = tree; this.checklistFilter = checklistFilter; // Note: If largemodel is not set then treenodes are getting truncated. // Need to debug further to find the problem. if ( checklistFilter != null ) tree.setLargeModel( true ); selectionModel = new ChecklistTreeSelectionModel( tree.getModel(), dig ); ChecklistTreeCellRenderer checklistRenderer = new ChecklistTreeCellRenderer( tree.getCellRenderer(), selectionModel, checklistFilter ); setCheckboxMaxX( checklistRenderer.getCheckboxMaxX() ); tree.setCellRenderer( checklistRenderer ); selectionModel.addTreeSelectionListener( this ); tree.addMouseListener( this ); } /** * Sets the checkbox's right edge (in the TreeCellRenderer component's coordinate space). * * Values less than that will be interpreted as within the checkbox's bounds. * X=0 is the renderer component's left edge. */ public void setCheckboxMaxX( int x ) { checkMaxX = x; } public ChecklistTreePathFilter getChecklistFilter() { return checklistFilter; } public ChecklistTreeSelectionModel getSelectionModel() { return selectionModel; } @Override public void mouseClicked( MouseEvent e ) { TreePath path = tree.getPathForLocation( e.getX(), e.getY() ); if ( path == null ) return; if ( e.getX() > tree.getPathBounds(path).x + checkMaxX ) return; if ( checklistFilter != null && !checklistFilter.isSelectable(path) ) return; boolean selected = selectionModel.isPathSelected( path, selectionModel.isDigged() ); selectionModel.removeTreeSelectionListener( this ); try { if ( selected ) { selectionModel.removeSelectionPath( path ); } else { selectionModel.addSelectionPath( path ); } } finally { selectionModel.addTreeSelectionListener( this ); tree.treeDidChange(); } } @Override public void valueChanged( TreeSelectionEvent e ) { tree.treeDidChange(); } }