如果您想在鼠标点击其他地方时取消选择树中的所有选定节点,您需要在用户点击其他地方时收到通知。要获取它,您可以使用全局事件侦听器 (Toolkit.getDefaultToolkit().addAWTEventListener())。
如果你想在你的树中显示一些复选框,你需要一个自定义的单元格渲染器,它对于一个条件返回一个复选框。您还需要一个数据容器来保存节点是否被选中,最后您需要一个例程来更新您的数据模型,当单击节点时。最后一件事通常由单元格编辑器提供(更多关于editors and renderes 的文章),但在您的情况下,使用我们之前安装的全局鼠标侦听器更容易。
当然,我的示例包含一点“摇摆魔法”,所以当您有不明白的地方,请随时向我提问;)
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
/**
* <code>JTreeDeselected</code>.
*/
public class JTreeSelectDeselect {
private final JTree tree = new JTree();
// model to hold nodes that must be presented as check boxes
// and whether the check boxes are selected
private final Map<Object, Boolean> checkMap = new HashMap<>();
// listener as method reference
private AWTEventListener awtListener = this::mouseClicked;
public static void main(String[] args) {
SwingUtilities.invokeLater(new JTreeSelectDeselect()::start);
}
private void start() {
checkMap.put("football", true);
checkMap.put("soccer", false);
checkMap.put("violet", true);
checkMap.put("yellow", false);
checkMap.put("pizza", true);
checkMap.put("ravioli", false);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
// JTree tree = new JTree();
tree.setCellRenderer(new DeselectTreeCellRenderer(checkMap));
panel.add(new JScrollPane(tree), BorderLayout.LINE_START);
panel.add(new JScrollPane(new JTextArea(10, 30)));
frame.add(panel);
// register global listener
Toolkit.getDefaultToolkit().addAWTEventListener(awtListener, AWTEvent.MOUSE_EVENT_MASK);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void mouseClicked(AWTEvent evt) {
if (evt instanceof MouseEvent) {
MouseEvent me = (MouseEvent) evt;
if (me.getID() == MouseEvent.MOUSE_PRESSED) {
if (me.getComponent().equals(tree)) {
TreePath path = tree.getPathForLocation(me.getX(), me.getY());
if (path == null) {
tree.clearSelection();
} else {
// update check box value
String pathString = Objects.toString(path.getLastPathComponent(), "");
Boolean val = checkMap.get(pathString);
if (val != null) {
checkMap.put(pathString, !val);
((DefaultTreeModel) tree.getModel()).valueForPathChanged(path, pathString);
}
}
} else {
tree.clearSelection();
}
}
}
}
}
class DeselectTreeCellRenderer extends DefaultTreeCellRenderer {
private final JCheckBox checkBox = new JCheckBox();
private final Map<Object, Boolean> checkMap;
public DeselectTreeCellRenderer(Map<Object, Boolean> checkMap) {
this.checkMap = checkMap;
}
@Override
public Color getBackgroundSelectionColor() {
return new Color(86, 92, 160);
}
@Override
public Color getBackground() {
return (null);
}
@Override
public Color getBackgroundNonSelectionColor() {
return new Color(23, 27, 36);
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean exp, boolean leaf, int row,
boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, exp, leaf, row, hasFocus);
setForeground(new Color(225, 225, 221, 255));
setOpaque(false);
// if our "check model" contains an entry for the node,
// present the node as check box
if (checkMap.containsKey(Objects.toString(value))) {
checkBox.setOpaque(true);
checkBox.setSelected(Boolean.TRUE == checkMap.get(Objects.toString(value)));
checkBox.setBackground(sel ? getBackgroundSelectionColor() : getBackgroundNonSelectionColor());
checkBox.setForeground(getForeground());
checkBox.setFont(getFont());
checkBox.setBorder(getBorder());
checkBox.setText(getText());
return checkBox;
}
return this;
}
}