How to get all marked fields of multiple trees in one window?
What I mean:
I am working on a window with multiple Checkboxes (Java Swing) and I used the sample codes I found on stackoverflow to create a JTree with JCheckBox objects. So I created a CheckBoxNode class, a CheckBoxNodeRenderer class and a CheckBoxNodeEditor class. However, I don't understand what actually happens when I check the box on the tree. I used a very simple "println" to see what is going on in many functions, such as the getTreeCellRendererComponent of the CheckBoxNodeRenderer class.
What I would like to do:
I have three trees and I would like to get all checked elements of each tree in a separate element, array or ArrayList. So, I can work with the selected items just by looking at those Arrays or ArrayLists. Of course, if I uncheck the box, the item has to be removed from the array.
What I've already tried:
I have to admit that I didn't have many ideas. I tried to understand what happens when I check the logs field in many functions, and I could notice that when I check the item in the tree, my logs are written more than three times (for example, the getTreeCellRenderer log).
My code:
class CheckBoxNode extends DefaultMutableTreeNode {
/**
*
*/
private static final long serialVersionUID = 1155080395876568819L;
private String _title;
private boolean _selectedStatus;
public CheckBoxNode(String name, boolean isSelected) {
this._title = name;
this._selectedStatus = isSelected;
}
//GETTERS
public String getTitle() {
return this._title;
}
public boolean isSelected() {
return this._selectedStatus;
}
//SETTERS
public void setTitle(String newTitle) {
this._title = newTitle;
}
public void setSelected(boolean isSelected) {
this._selectedStatus = isSelected;
}
public String toString() {
return _title;
}
}
CheckBoxNodeEditor
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
/**
*
*/
private static final long serialVersionUID = 2616799535763664121L;
private CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
//CONSTRUCTOR
public CheckBoxNodeEditor() {}
//METHODS
public Object getCellEditorValue() {
JCheckBox checkBox = renderer.getNodeRenderer();
CheckBoxNode checkBoxNode = new CheckBoxNode(checkBox.getText(), checkBox.isSelected());
return checkBoxNode;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value,
true, expanded, leaf, row, true);
// editor always selected / focused
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
};
if (editor instanceof JCheckBox) {
((JCheckBox) editor).addItemListener(itemListener);
}
return editor;
}
}
CheckBoxNodeRenderer
class CheckBoxNodeRenderer implements TreeCellRenderer {
private JCheckBox nodeRenderer = new JCheckBox();
private Color selectionForeground, selectionBackground, textForeground, textBackground;
//CONSTRUCTOR
public CheckBoxNodeRenderer() {
Font fontValue;
fontValue = UIManager.getFont("Tree.font");
if (fontValue != null) {
nodeRenderer.setFont(fontValue);
}
Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
nodeRenderer.setFocusPainted((booleanValue != null)&& (booleanValue.booleanValue()));
selectionForeground = UIManager.getColor("Tree.selectionForeground");
selectionBackground = UIManager.getColor("Tree.selectionBackground");
textForeground = UIManager.getColor("Tree.textForeground");
textBackground = UIManager.getColor("Tree.textBackground");
}
//METHODS
protected JCheckBox getNodeRenderer() {
return nodeRenderer;
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component returnValue;
String stringValue = tree.convertValueToText(value, selected, expanded,
leaf, row, false);
nodeRenderer.setText(stringValue);
nodeRenderer.setSelected(false);
nodeRenderer.setEnabled(tree.isEnabled());
if (selected) {
nodeRenderer.setForeground(selectionForeground);
nodeRenderer.setBackground(selectionBackground);
} else {
nodeRenderer.setForeground(textForeground);
nodeRenderer.setBackground(textBackground);
}
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value)
.getUserObject();
if (userObject instanceof CheckBoxNode) {
CheckBoxNode node = (CheckBoxNode) userObject;
nodeRenderer.setText(node.getTitle());
nodeRenderer.setSelected(node.isSelected());
}
}
returnValue = nodeRenderer;
return returnValue;
}
}
Building window and trees: This consists of extracting data from the database and creating checkbox trees, as well as in the main application window containing trees and other panels.
public class WindowBuilding extends JFrame {
/**
*
*/
private static final long serialVersionUID = -634017858375515775L;
private Parser _parser;
// CONSTRUCTOR
public WindowBuilding() {
this._parser = new Parser(); //parser to extract data from the database containining all the informations
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS)); //gridlayout to have all the elements in the same window
}
// METHODS
public void buildTrees() throws SQLException {
_parser.extractData();
_parser.sortModels();
_parser.sortCustomers();
_parser.sortGroups();
System.out.println(_parser.getNumberOfCustomers());
System.out.println(_parser.getNumberOfGroups());
// Families, Types and Models arrays
CheckBoxNode[] myFamilies = new CheckBoxNode[_parser.getNumberOfFamilies()];
CheckBoxNode[] myTypes = new CheckBoxNode[_parser.getNumberOfTypes()];
CheckBoxNode[] myModels = new CheckBoxNode[_parser.getNumberOfModels()];
// Root
CheckBoxNode root = new CheckBoxNode("All", false);
// Complete the arrays
for (int i = 0; i < _parser.getNumberOfFamilies(); i++) {
myFamilies[i] = new CheckBoxNode(_parser.getFamily(i), false);
}
for (int i = 0; i < _parser.getNumberOfTypes(); i++) {
myTypes[i] = new CheckBoxNode(_parser.getType(i), false);
}
for (int i = 0; i < _parser.getNumberOfModels(); i++) {
myModels[i] = new CheckBoxNode(_parser.getModel(i), false);
}
// Add Models to Types
for (int i = 0; i < myModels.length; i++) {
if (myModels[i].toString().startsWith("T119")) {
myTypes[1].add(myModels[i]);
}
if (myModels[i].toString().startsWith("T120")) {
myTypes[2].add(myModels[i]);
}
if (myModels[i].toString().startsWith("T121")) {
myTypes[3].add(myModels[i]);
}
if (myModels[i].toString().startsWith("T130")) {
myTypes[4].add(myModels[i]);
}
if (myModels[i].toString().startsWith("T150")) {
myTypes[7].add(myModels[i]);
}
}
// Add Types to Families
for (int i = 0; i < myTypes.length; i++) {
if (myTypes[i].toString().startsWith("T119") || myTypes[i].toString().startsWith("T12")) {
myFamilies[0].add(myTypes[i]);
}
if (myTypes[i].toString().startsWith("T13")) {
myFamilies[1].add(myTypes[i]);
}
if (myTypes[i].toString().startsWith("T15")) {
myFamilies[3].add(myTypes[i]);
}
}
// Add Families to Root
for (int i = 0; i < _parser.getNumberOfFamilies(); i++) {
if (i != 2) {
root.add(myFamilies[i]);
}
}
// Customers and Groups arrays
CheckBoxNode[] myCustomers = new CheckBoxNode[_parser.getNumberOfCompanies()];
CheckBoxNode[] myGroups = new CheckBoxNode[_parser.getNumberOfFleets()];
// Root for Groups
CheckBoxNode rootGroups = new CheckBoxNode("All", false);
// Complete the arrays
for (int i = 0; i < _parser.getNumberOfCustomers(); i++) {
myCustomers[i] = new CheckBoxNode(_parser.getCustomer(i), false);
}
for (int i = 0; i < _parser.getNumberOfGroups(); i++) {
myGroups[i] = new CheckBoxNode(_parser.getGroup(i), false);
}
// Add Groups to Customers
for (int i = 0; i < myCustomers.length; i++) {
for (int j = 0; j < Groups.length; j++) {
if (myFleets[j].getTitle()
.startsWith(myCustomers[i].getTitle())) {
myCustomers[i].add(myGroups[j]);
}
}
}
// Add Companies to Root
for (int i = 0; i < myCustomers.length; i++) {
rootGroups.add(myCustomers[i]);
}
// Test Types array
CheckBoxNode[] myTests = new CheckBoxNode[8];
// Root
CheckBoxNode rootTests = new CheckBoxNode("All", false);
// Complete the arrays
myTests[0] = new CheckBoxNode("FIRST TEST", false);
myTests[1] = new CheckBoxNode("SECOND TEST", false);
myTests[2] = new CheckBoxNode("CHECK TEST", false);
myTests[3] = new CheckBoxNode("RUN TEST", false);
myTests[4] = new CheckBoxNode("STATIC", false);
myTests[5] = new CheckBoxNode("TYPICAL TEST", false);
myTests[6] = new CheckBoxNode("SIMU VALIDATION", false);
myTests[7] = new CheckBoxNode("OTHER", false);
// Add Test Types to root
for(int i=0; i<8; i++) {
rootTests.add(myTests[i]);
}
// TPP Array
CheckBoxNode[] myTpp = new CheckBoxNode[30];
// Root
CheckBoxNode rootTpp = new CheckBoxNode("All", false);
// Complete the arrays
for(int i=0; i<30; i++) {
myTpp[i] = new CheckBoxNode("TPP "+(i+1), false);
}
// Add Tpp to root
for(int i=0; i<myTpp.length; i++) {
rootTpp.add(myTpp[i]);
}
// Create objects JTree
JTree treeProducts = new JTree(root);
JTree treeGroups = new JTree(rootGroups);
JTree treeTests = new JTree(rootTests);
JTree treeTpp = new JTree(rootTpp);
// Trees renderer
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
// Products tree parameters
treeProducts.setCellRenderer(renderer);
treeProducts.setCellEditor(new CheckBoxNodeEditor());
treeProducts.setEditable(true);
// Groups tree parameters
treeGroups.setCellRenderer(renderer);
treeGroups.setCellEditor(new CheckBoxNodeEditor());
treeGroups.setEditable(true);
// Test Types tree parameters
treeTests.setCellRenderer(renderer);
treeTests.setCellEditor(new CheckBoxNodeEditor());
treeTests.setEditable(true);
// Tpp tree parameters
treeTpp.setCellRenderer(renderer);
treeTpp.setCellEditor(new CheckBoxNodeEditor());
treeTpp.setEditable(true);
// Building panels
JPanel mainPanel = new JPanel();
JPanel titlePanel = new JPanel();
JPanel dataPropPanel = new JPanel();
JPanel topPanel = new JPanel();
JPanel bottomPanel = new JPanel();
JPanel spinnersPanel = new JPanel();
JPanel msnPanel = new JPanel();
JPanel datePanel = new JPanel();
JPanel selectTppPanel = new JPanel();
JPanel tppPanel = new JPanel();
JPanel descPanel = new JPanel();
JPanel labelsPanel= new JPanel();
JPanel fieldsPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
spinnersPanel.setLayout(new BoxLayout(spinnersPanel, BoxLayout.Y_AXIS));
labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS));
fieldsPanel.setLayout(new BoxLayout(fieldsPanel, BoxLayout.Y_AXIS));
descPanel.setLayout(new BoxLayout(descPanel, BoxLayout.Y_AXIS));
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
tppPanel.setLayout(new BoxLayout(tppPanel, BoxLayout.X_AXIS));
msnPanel.setLayout(new BoxLayout(msnPanel, BoxLayout.X_AXIS));
datePanel.setLayout(new BoxLayout(datePanel, BoxLayout.X_AXIS));
titlePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
dataPropPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
selectTppPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
// Dimensions
Dimension dimLabel = new Dimension(300,35);
// JScrollPane for trees
JScrollPane prodPane = new JScrollPane(treeProducts); // ScrollPane products
prodPane.setMaximumSize(new Dimension(250,300));
JScrollPane groupPane = new JScrollPane(treeGroups); // ScrollPane groups
groupPpane.setMaximumSize(new Dimension(250,300));
JScrollPane tePane = new JScrollPane(treeTests);
tePane.setMaximumSize(new Dimension(250,300));
JScrollPane tppPane = new JScrollPane(treeTpp);
tppPane.setMaximumSize(new Dimension(600,300));
// Labels for main panel
JLabel title = new JLabel("Generate Test Points");
titlePanel.add(title);
JLabel topLabel = new JLabel("Data properties");
dataPropPanel.add(topLabel);
JLabel bottomLabel = new JLabel("Select TPP");
selectTppPanel.add(bottomLabel);
// MSN Panel
SpinnerModel model1 = new SpinnerNumberModel(0,0,10000,1);
SpinnerModel model2 = new SpinnerNumberModel(0,0,10000,1);
JSpinner spinner1 = new JSpinner(model1);
JSpinner spinner2 = new JSpinner(model2);
msnPanel.add(spinner1);
msnPanel.add(new JLabel(" to "));
msnPanel.add(spinner2);
msnPanel.setMaximumSize(dimLabel);
// Date Panel
SpinnerModel date1 = new SpinnerDateModel();
SpinnerModel date2 = new SpinnerDateModel();
JSpinner dateSpinner1 = new JSpinner(date1);
JSpinner dateSpinner2 = new JSpinner(date2);
datePanel.add(dateSpinner1);
datePanel.add(new JLabel(" to "));
datePanel.add(dateSpinner2);
datePanel.setMaximumSize(dimLabel);
// Spinners Panel
JLabel msnRangeLabel = new JLabel("MSN Range");
spinnersPanel.add(msnRangeLabel);
spinnersPanel.add(msnPanel);
spinnersPanel.add(new JLabel("Test Date Range"));
spinnersPanel.add(datePanel);
// Top Panel
JLabel acPropertiesLabel = new JLabel("Product properties");
topPanel.add(prodPropertiesLabel);
topPanel.add(prodPane);
topPanel.add(new JLabel("Groups"));
topPanel.add(groupPane);
topPanel.add(new JLabel("Test properties"));
topPanel.add(tePane);
topPanel.add(spinnersPanel);
// Labels Panel
JLabel tppName = new JLabel("TPP Name");
tppName.setMaximumSize(new Dimension(100,35));
labelsPanel.add(tppName);
labelsPanel.add(new JLabel("TPP List"));
// Fields Panel
JTextField textField = new JTextField();
textField.setMaximumSize(new Dimension(600,35));
fieldsPanel.add(textField);
fieldsPanel.add(tppane);
// TPP Panel
tppPanel.add(labelsPanel);
tppPanel.add(fieldsPanel);
// Desc Panel
descPanel.add(new JLabel("label for description"));
descPanel.add(new JLabel("label for description"));
descPanel.add(new JLabel("label for description"));
descPanel.add(new JLabel("label for description"));
descPanel.add(new JLabel("label for description"));
// Bottom Panel
bottomPanel.add(tppPanel);
bottomPanel.add(descPanel);
// Main Panel
mainPanel.add(titlePanel);
mainPanel.add(dataPropPanel);
mainPanel.add(topPanel);
mainPanel.add(selectTppPanel);
mainPanel.add(bottomPanel);
this.getContentPane().add(mainPanel);
// Window parameters
((JComponent) this.getContentPane()).setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); //add a border to the window
this.setSize(1600,900);
this.setTitle("Generate Test Points");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
Main class
public class TestPointGeneration {
/**
* @param args
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
* @throws SQLException
*/
public static void main(String[] args) throws SQLException {
WindowBuilding window = new WindowBuilding();
window.buildTrees();
window.setVisible(true);
}
}
Let me know if you need more information on my code and I am very grateful to all of you.
source to share
I adapted the solution from this answer: How to get all the marked fields of multiple trees in one window?
I think your CheckBoxNode class is missing functionality, basically it is repo information for status, but then in your CheckBoxNodeEditor class you only add JCheckBox, in my opinion it should be an array or list and checkBoxNode should handle events to check if they are marked or not marked.
Main class:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.tree.TreePath;
public class Main extends JFrame {
private static final long serialVersionUID = 4648172894076113183L;
public Main() {
super();
setSize(500, 500);
this.getContentPane().setLayout(new BorderLayout());
final JCheckBoxTree cbt = new JCheckBoxTree();
final JButton button = new JButton("get checked");
JPanel panel = new JPanel();
panel.add(cbt);
panel.add(button);
this.getContentPane().add(panel);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
printChecked(cbt);
}
});
cbt.addCheckChangeEventListener(new JCheckBoxTree.CheckChangeEventListener() {
public void checkStateChanged(JCheckBoxTree.CheckChangeEvent event) {
printChecked(cbt);
}
});
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void printChecked(final JCheckBoxTree cbt) {
System.out.println("Select items");
TreePath[] paths = cbt.getCheckedPaths();
for (TreePath tp : paths) {
for (Object pathPart : tp.getPath()) {
System.out.print(pathPart + ",");
}
System.out.println();
}
}
public static void main(String args[]) {
Main m = new Main();
m.setVisible(true);
}
}
JTree class
package com.stackoverflow.checkedboxes;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventListener;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.EventListenerList;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JCheckBoxTree extends JTree {
private static final long serialVersionUID = -4194122328392241790L;
JCheckBoxTree selfPointer = this;
// Defining data structure that will enable to fast check-indicate the state of each node
// It totally replaces the "selection" mechanism of the JTree
private class CheckedNode {
boolean isSelected;
boolean hasChildren;
boolean allChildrenSelected;
public CheckedNode(boolean isSelected_, boolean hasChildren_, boolean allChildrenSelected_) {
isSelected = isSelected_;
hasChildren = hasChildren_;
allChildrenSelected = allChildrenSelected_;
}
}
HashMap<TreePath, CheckedNode> nodesCheckingState;
HashSet<TreePath> checkedPaths = new HashSet<TreePath>();
// Defining a new event type for the checking mechanism and preparing event-handling mechanism
protected EventListenerList listenerList = new EventListenerList();
public class CheckChangeEvent extends EventObject {
private static final long serialVersionUID = -8100230309044193368L;
public CheckChangeEvent(Object source) {
super(source);
}
}
public interface CheckChangeEventListener extends EventListener {
public void checkStateChanged(CheckChangeEvent event);
}
public void addCheckChangeEventListener(CheckChangeEventListener listener) {
listenerList.add(CheckChangeEventListener.class, listener);
}
public void removeCheckChangeEventListener(CheckChangeEventListener listener) {
listenerList.remove(CheckChangeEventListener.class, listener);
}
void fireCheckChangeEvent(CheckChangeEvent evt) {
Object[] listeners = listenerList.getListenerList();
for (int i = 0; i < listeners.length; i++) {
if (listeners[i] == CheckChangeEventListener.class) {
((CheckChangeEventListener) listeners[i + 1]).checkStateChanged(evt);
}
}
}
// Override
public void setModel(TreeModel newModel) {
super.setModel(newModel);
resetCheckingState();
}
// New method that returns only the checked paths (totally ignores original "selection" mechanism)
public TreePath[] getCheckedPaths() {
return checkedPaths.toArray(new TreePath[checkedPaths.size()]);
}
// Returns true in case that the node is selected, has children but not all of them are selected
public boolean isSelectedPartially(TreePath path) {
CheckedNode cn = nodesCheckingState.get(path);
return cn.isSelected && cn.hasChildren && !cn.allChildrenSelected;
}
private void resetCheckingState() {
nodesCheckingState = new HashMap<TreePath, CheckedNode>();
checkedPaths = new HashSet<TreePath>();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)getModel().getRoot();
if (node == null) {
return;
}
addSubtreeToCheckingStateTracking(node);
}
// Creating data structure of the current model for the checking mechanism
private void addSubtreeToCheckingStateTracking(DefaultMutableTreeNode node) {
TreeNode[] path = node.getPath();
TreePath tp = new TreePath(path);
CheckedNode cn = new CheckedNode(false, node.getChildCount() > 0, false);
nodesCheckingState.put(tp, cn);
for (int i = 0 ; i < node.getChildCount() ; i++) {
addSubtreeToCheckingStateTracking((DefaultMutableTreeNode) tp.pathByAddingChild(node.getChildAt(i)).getLastPathComponent());
}
}
// Overriding cell renderer by a class that ignores the original "selection" mechanism
// It decides how to show the nodes due to the checking-mechanism
private class CheckBoxCellRenderer extends JPanel implements TreeCellRenderer {
private static final long serialVersionUID = -7341833835878991719L;
JCheckBox checkBox;
public CheckBoxCellRenderer() {
super();
this.setLayout(new BorderLayout());
checkBox = new JCheckBox();
add(checkBox, BorderLayout.CENTER);
setOpaque(false);
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
Object obj = node.getUserObject();
TreePath tp = new TreePath(node.getPath());
CheckedNode cn = nodesCheckingState.get(tp);
if (cn == null) {
return this;
}
checkBox.setSelected(cn.isSelected);
checkBox.setText(obj.toString());
checkBox.setOpaque(cn.isSelected && cn.hasChildren && ! cn.allChildrenSelected);
return this;
}
}
public JCheckBoxTree() {
super();
// Disabling toggling by double-click
this.setToggleClickCount(0);
// Overriding cell renderer by new one defined above
CheckBoxCellRenderer cellRenderer = new CheckBoxCellRenderer();
this.setCellRenderer(cellRenderer);
// Overriding selection model by an empty one
DefaultTreeSelectionModel dtsm = new DefaultTreeSelectionModel() {
private static final long serialVersionUID = -8190634240451667286L;
// Totally disabling the selection mechanism
public void setSelectionPath(TreePath path) {
}
public void addSelectionPath(TreePath path) {
}
public void removeSelectionPath(TreePath path) {
}
public void setSelectionPaths(TreePath[] pPaths) {
}
};
// Calling checking mechanism on mouse click
this.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
TreePath tp = selfPointer.getPathForLocation(arg0.getX(), arg0.getY());
if (tp == null) {
return;
}
boolean checkMode = ! nodesCheckingState.get(tp).isSelected;
checkSubTree(tp, checkMode);
updatePredecessorsWithCheckMode(tp, checkMode);
// Firing the check change event
fireCheckChangeEvent(new CheckChangeEvent(new Object()));
// Repainting tree after the data structures were updated
selfPointer.repaint();
}
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
});
this.setSelectionModel(dtsm);
}
// When a node is checked/unchecked, updating the states of the predecessors
protected void updatePredecessorsWithCheckMode(TreePath tp, boolean check) {
TreePath parentPath = tp.getParentPath();
// If it is the root, stop the recursive calls and return
if (parentPath == null) {
return;
}
CheckedNode parentCheckedNode = nodesCheckingState.get(parentPath);
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) parentPath.getLastPathComponent();
parentCheckedNode.allChildrenSelected = true;
parentCheckedNode.isSelected = false;
for (int i = 0 ; i < parentNode.getChildCount() ; i++) {
TreePath childPath = parentPath.pathByAddingChild(parentNode.getChildAt(i));
CheckedNode childCheckedNode = nodesCheckingState.get(childPath);
// It is enough that even one subtree is not fully selected
// to determine that the parent is not fully selected
if (! childCheckedNode.allChildrenSelected) {
parentCheckedNode.allChildrenSelected = false;
}
// If at least one child is selected, selecting also the parent
if (childCheckedNode.isSelected) {
parentCheckedNode.isSelected = true;
}
}
if (parentCheckedNode.isSelected) {
checkedPaths.add(parentPath);
} else {
checkedPaths.remove(parentPath);
}
// Go to upper predecessor
updatePredecessorsWithCheckMode(parentPath, check);
}
// Recursively checks/unchecks a subtree
protected void checkSubTree(TreePath tp, boolean check) {
CheckedNode cn = nodesCheckingState.get(tp);
cn.isSelected = check;
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
for (int i = 0 ; i < node.getChildCount() ; i++) {
checkSubTree(tp.pathByAddingChild(node.getChildAt(i)), check);
}
cn.allChildrenSelected = check;
if (check) {
checkedPaths.add(tp);
} else {
checkedPaths.remove(tp);
}
}
}
Conclusion: Select Products JTree, Color, Blue, JTree, Colors, Red, JTree, Colors, JTree, Colors, Yellow, JTree,
source to share