aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes JCheckBox in Jtree Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "JCheckBox in Jtree Problem" Watch "JCheckBox in Jtree Problem" New topic
Author

JCheckBox in Jtree Problem

satya sahu
Ranch Hand

Joined: Mar 26, 2003
Posts: 97
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();
}
}
}
Craig Wood
Ranch Hand

Joined: Jan 14, 2004
Posts: 1535
make the leaf nodes as folder node
satya sahu
Ranch Hand

Joined: Mar 26, 2003
Posts: 97
Thanks for the reply.
Now i have some other problem.
The nodes of the tree are not visible properly. The nodes are visible only half HORIZONTALLY. The text, the folder icon, the checkbox are only rendered half. The code runs fine in Linux, but when i run it in windows XP, this above problem is happening. I don't know where is the mistake and what to do to solve this.
Can anybody has any idea to solve this ?
I have already tried repainting,revalidating, preferred size.....
Please help me.
Thanks in advance.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JCheckBox in Jtree Problem