Hi friends,
As i am browsing the file system, i want to disply all the nodes with folder icon. But in this code i am not able to make the leaf nodes as folder node. Can some body correct the code below. There are 5 files. Run the CheckBoxMain.java file to execute.
import javax.swing.tree.*;
import java.awt.*;
import javax.swing.*;
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(TristateCheckBox.SELECTED);
else
checkBox.setState(selectionModel.isPartiallySelected(path) ? null : TristateCheckBox.NOT_SELECTED);
}
removeAll();
add(checkBox, BorderLayout.WEST);
add(renderer, BorderLayout.CENTER);
return this;
}
}
import javax.swing.*;
import java.awt.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeNode;
public class CheckBoxMain
extends JFrame {
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane jScrollPane1 = new JScrollPane();
static JTree jTree1 = new JTree();
public CheckBoxMain() {
try {
jbInit();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
void jbInit() throws Exception {
this.getContentPane().setLayout(borderLayout1);
this.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
jScrollPane1.getViewport().add(jTree1, null);
}
public static void main(
String args[]) {
CheckBoxMain mainObj = new CheckBoxMain();
mainObj.createTree();
CheckTreeManager obj = new CheckTreeManager(jTree1);
mainObj.setSize(400, 300);
mainObj.setVisible(true);
}
private void createTree() {
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("e:\\");
DefaultMutableTreeNode nodeOne = new DefaultMutableTreeNode("Node - 1");
DefaultMutableTreeNode nodeTwo = new DefaultMutableTreeNode("Node - 2");
DefaultMutableTreeNode nodeThree = new DefaultMutableTreeNode("Node - 3");
rootNode.add(nodeOne);
rootNode.add(nodeTwo);
rootNode.add(nodeThree);
DefaultMutableTreeNode nodeTwo1 = new DefaultMutableTreeNode("Node - 2.1");
DefaultMutableTreeNode nodeTwo2 = new DefaultMutableTreeNode("Node - 2.2");
DefaultMutableTreeNode nodeTwo3 = new DefaultMutableTreeNode("Node - 2.3");
nodeTwo.add(nodeTwo1);
nodeTwo.add(nodeTwo2);
nodeTwo.add(nodeTwo3);
DefaultMutableTreeNode nodeThree1 = new DefaultMutableTreeNode("Node - 3.1");
nodeThree.add(nodeThree1);
jTree1.setModel(new DefaultTreeModel(rootNode));
jTree1.putClientProperty ("JTree.lineStyle", "Angled");
}
}
import javax.swing.event.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.tree.TreePath;
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){
System.out.println("DDDDDDDDDDDDDDDDDd");
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();
}
}
import javax.swing.tree.*;
import java.util.*;
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});
}
}
import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ActionMapUIResource;
import java.awt.event.*;
public class TristateCheckBox extends JCheckBox {
/** This is a type-safe enumerated type */
public static class State { private State() { } }
public static final State NOT_SELECTED = new State();
public static final State SELECTED = new State();
public static final State DONT_CARE = new State();
private final TristateDecorator model;
public TristateCheckBox(String text, Icon icon, State initial){
super(text, icon);
// Add a listener for when the mouse is pressed
super.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
grabFocus();
model.nextState();
}
});
// Reset the keyboard action map
ActionMap map = new ActionMapUIResource();
map.put("pressed", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
grabFocus();
model.nextState();
}
});
map.put("released", null);
SwingUtilities.replaceUIActionMap(this, map);
// set the model to the adapted model
model = new TristateDecorator(getModel());
setModel(model);
setState(initial);
}
public TristateCheckBox(String text, State initial) {
this(text, null, initial);
}
public TristateCheckBox(String text) {
this(text, DONT_CARE);
}
public TristateCheckBox() {
this(null);
}
/** No one may add mouse listeners, not even Swing! */
public void addMouseListener(MouseListener l) { }
/**
* Set the new state to either SELECTED, NOT_SELECTED or
* DONT_CARE. If state == null, it is treated as DONT_CARE.
*/
public void setState(State state) { model.setState(state); }
/** Return the current state, which is determined by the
* selection status of the model. */
public State getState() { return model.getState(); }
public void setSelected(boolean b) {
if (b) {
setState(SELECTED);
} else {
setState(NOT_SELECTED);
}
}
/**
* Exactly which Design
Pattern is this? Is it an Adapter,
* a Proxy or a Decorator? In this case, my vote lies with the
* Decorator, because we are extending functionality and
* "decorating" the original model with a more powerful model.
*/
private class TristateDecorator implements ButtonModel {
private final ButtonModel other;
private TristateDecorator(ButtonModel other) {
this.other = other;
}
private void setState(State state) {
if (state == NOT_SELECTED) {
other.setArmed(false);
setPressed(false);
setSelected(false);
} else if (state == SELECTED) {
other.setArmed(false);
setPressed(false);
setSelected(true);
} else { // either "null" or DONT_CARE
other.setArmed(true);
setPressed(true);
setSelected(true);
}
}
/**
* The current state is embedded in the selection / armed
* state of the model.
*
* We return the SELECTED state when the checkbox is selected
* but not armed, DONT_CARE state when the checkbox is
* selected and armed (grey) and NOT_SELECTED when the
* checkbox is deselected.
*/
private State getState() {
if (isSelected() && !isArmed()) {
// normal black tick
return SELECTED;
} else if (isSelected() && isArmed()) {
// don't care grey tick
return DONT_CARE;
} else {
// normal deselected
return NOT_SELECTED;
}
}
/** We rotate between NOT_SELECTED, SELECTED and DONT_CARE.*/
private void nextState() {
State current = getState();
if (current == NOT_SELECTED) {
setState(SELECTED);
} else if (current == SELECTED) {
setState(DONT_CARE);
} else if (current == DONT_CARE) {
setState(NOT_SELECTED);
}
}
/** Filter: No one may change the armed status except us. */
public void setArmed(boolean b) {
}
/** We disable focusing on the component when it is not
* enabled. */
public void setEnabled(boolean b) {
setFocusable(b);
other.setEnabled(b);
}
/** All these methods simply delegate to the "other" model
* that is being decorated. */
public boolean isArmed() { return other.isArmed(); }
public boolean isSelected() { return other.isSelected(); }
public boolean isEnabled() { return other.isEnabled(); }
public boolean isPressed() { return other.isPressed(); }
public boolean isRollover() { return other.isRollover(); }
public void setSelected(boolean b) { other.setSelected(b); }
public void setPressed(boolean b) { other.setPressed(b); }
public void setRollover(boolean b) { other.setRollover(b); }
public void setMnemonic(int key) { other.setMnemonic(key); }
public int getMnemonic() { return other.getMnemonic(); }
public void setActionCommand(String s) {
other.setActionCommand(s);
}
public String getActionCommand() {
return other.getActionCommand();
}
public void setGroup(ButtonGroup group) {
other.setGroup(group);
}
public void addActionListener(ActionListener l) {
other.addActionListener(l);
}
public void removeActionListener(ActionListener l) {
other.removeActionListener(l);
}
public void addItemListener(ItemListener l) {
other.addItemListener(l);
}
public void removeItemListener(ItemListener l) {
other.removeItemListener(l);
}
public void addChangeListener(ChangeListener l) {
other.addChangeListener(l);
}
public void removeChangeListener(ChangeListener l) {
other.removeChangeListener(l);
}
public Object[] getSelectedObjects() {
return other.getSelectedObjects();
}
}
}