我正在处理的事情:
我正在使用几个Checkboxes Tree(Java Swing)创建一个窗口,我使用了stackoverflow中的代码示例来创建一个带有JCheckBox对象的JTree。所以我创建了一个类CheckBoxNode,一个类CheckBoxNodeRenderer和一个类CheckBoxNodeEditor。 然而,当我检查树中的一个方框时,我不明白究竟发生了什么。我使用了一个非常简单的“println”来查看许多函数中发生的事情,例如类CheckBoxNodeRenderer的getTreeCellRendererComponent。
我想做什么:
我有三棵树,我希望将每棵树的所有已检查元素放在一个单独的元素,一个数组或一个ArrayList中。那么,只需读取这些数组或ArrayLists,我就可以使用所选元素。当然,如果我取消选中一个框,则必须从数组中删除该元素。
我已尝试过的内容:
我必须承认我没有太多想法。我试着准确理解当我选中一个方框时会发生什么,包含许多函数中的日志,我可以观察到当我检查树中的元素时,我的日志被写了三次以上(例如登录getTreeCellRenderer)。 / p>
我的代码:
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;
}
}
构建窗口和树:包括从数据库中提取数据并构建复选框树以及包含树和其他面板的应用程序的主窗口
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);
}
}
主要课程
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);
}
}
如果您需要有关我的代码的更多信息,请告诉我,我非常感谢你们所有人。
答案 0 :(得分:1)
我根据这个答案改编了解决方案: How to get all the checked boxes of several trees in a same window?
我认为你的类CheckBoxNode缺少功能,基本上是状态的repo信息,但是在你的CheckBoxNodeEditor类中你只添加一个JCheckBox,在我看来它必须是一个数组或列表,而checkBoxNode必须处理要检查或取消选中的事件。
主类:
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);
}
}
}
输出: 选择项目 JTree的,颜色,蓝色, JTree的,颜色,红色, JTree的,颜色, JTree的,颜色,黄色, JTree的,