Java 如何在JTree中手动选择节点[嵌套节点的问题]
我无法通过java代码在JTree中手动选择项。我用谷歌搜索了这个问题,并在这里和这里找到了解决方案: 这个代码只对我起了部分作用。一旦我尝试选择更深的嵌套节点,我就遇到了问题。由于我的产品代码非常混乱,我构建了一个示例,并在其中重现了我的确切问题 DummyView.javaJava 如何在JTree中手动选择节点[嵌套节点的问题],java,swing,jtree,treenode,Java,Swing,Jtree,Treenode,我无法通过java代码在JTree中手动选择项。我用谷歌搜索了这个问题,并在这里和这里找到了解决方案: 这个代码只对我起了部分作用。一旦我尝试选择更深的嵌套节点,我就遇到了问题。由于我的产品代码非常混乱,我构建了一个示例,并在其中重现了我的确切问题 DummyView.java package de.fortis.tcws.client.controller; import java.awt.BorderLayout; import java.awt.Dimension; import ja
package de.fortis.tcws.client.controller;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class DummyView extends JFrame {
private static final long serialVersionUID = 7301762327073611779L;
private static final String ROOT_NAME = "Root";
public JTree tree;
public DefaultTreeModel model;
public JPanel right;
public DummyView() {
super();
initGui();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initGui() {
setSize(1600, 800);
tree = new JTree();
tree.setEditable(false);
tree.addTreeSelectionListener(new DumSelectionListener());
tree.addTreeExpansionListener(new DumExpansionListener());
DefaultMutableTreeNode root = new DefaultMutableTreeNode(ROOT_NAME);
tree.setModel(model = new DefaultTreeModel(root, true));
refreshNode(root);
tree.setPreferredSize(new Dimension(200, 800));
getContentPane().add(new JScrollPane(tree), BorderLayout.WEST);
JScrollPane rightPan = new JScrollPane(right = new JPanel());
right.add(new JLabel("Empty"));
getContentPane().add(rightPan, BorderLayout.CENTER);
}
public void manualSelect(Object[] path) {
DefaultMutableTreeNode target = (DefaultMutableTreeNode) tree.getModel().getRoot();
for (Object uo : path) {
refreshNode(target);
target = getNodeByUserObject(target, uo);
}
navigateToNode(target);
}
public void navigateToNode(DefaultMutableTreeNode node) {
TreeNode[] nodes = model.getPathToRoot(node);
TreePath tpath = new TreePath(nodes);
tree.scrollPathToVisible(tpath);
tree.setSelectionPath(tpath);
}
public DefaultMutableTreeNode getNodeByUserObject(DefaultMutableTreeNode node, Object o) {
for (int i = 0; i < node.getChildCount(); i++) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
if (child.getUserObject().equals(o)) {
return child;
}
}
return null;
}
private class DumSelectionListener implements TreeSelectionListener {
@Override
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
e.getNewLeadSelectionPath().getLastPathComponent();
right.removeAll();
right.add(new JLabel("Node: " + node.getUserObject().toString()));
right.revalidate();
right.repaint();
}
}
private class DumExpansionListener implements TreeExpansionListener {
@Override
public void treeExpanded(TreeExpansionEvent event) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
refreshNode(node);
}
@Override
public void treeCollapsed(TreeExpansionEvent event) {
}
}
private void refreshNode(DefaultMutableTreeNode node) {
node.removeAllChildren();
Object uo = node.getUserObject();
if (uo.equals(ROOT_NAME)) {
for (int i = 1; i <= 10; i++) {
DefaultMutableTreeNode n = new DefaultMutableTreeNode(new Integer(i));
node.add(n);
}
} else if (uo instanceof Integer) {
int num = (Integer) uo;
for (int i = 1; i <= 9; i++) {
DefaultMutableTreeNode n = new DefaultMutableTreeNode("" + num + "." + i);
node.add(n);
}
} else {
String uos = (String) uo;
String[] split = uos.split("[.]");
if (split.length == 2) {
for (String let : new String[] {
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"
}) {
DefaultMutableTreeNode n = new DefaultMutableTreeNode(let);
node.add(n);
}
} else {
String value = uos;
DefaultMutableTreeNode parSplit = (DefaultMutableTreeNode) node.getParent();
value = parSplit + value;
DefaultMutableTreeNode parNum = (DefaultMutableTreeNode) parSplit.getParent();
value = parNum + value;
DefaultMutableTreeNode parRoot = (DefaultMutableTreeNode) parNum.getParent();
value = parRoot + value;
value = mdfive(value);
DefaultMutableTreeNode n = new DefaultMutableTreeNode(value);
node.add(n);
}
}
model.nodeStructureChanged(node);
}
private String mdfive(String in) {
String out = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(in.getBytes());
byte[] bytes = md.digest();
for (int i = 0; i < bytes.length; i++) {
out += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return out.substring(0, 10);
}
}
重要的方法是“manualSelectString[]”。
它通过比较用户对象来遍历树,并找到目标节点。然后调用“navigateToNode”,它使用上面链接中讨论的解决方案
此方法的行为不一致:
如果使用空数组调用它,它将正确选择根节点。右侧窗格显示所选节点的文本对的
如果使用目标节点1调用它,它将正确选择节点1。右侧窗格显示所选节点的文本对的
如果使用目标节点1.1调用它,它将选择节点1.1,但由于某些原因,它不会显示为标记为无背景。右侧窗格显示所选节点的文本只是部分正确
如果使用目标节点A调用它,它将遇到异常。调试表明,选择首先正确发生。您还可以观察右侧窗格,其中显示已选择“A”。但之后,另一个TreeSelection事件正在发生,其NewLeadSelectionPath为null。我不知道第二个SelectionEvent是从哪里触发的。
我做错什么了吗?有人对解决这个问题有什么想法吗
这段代码是用Java 1.6.039运行的,这也是我在生产中必须使用的
您好,
奥立
编辑:拼写选择节点时,树正在刷新。。。 拆下这两条线,它就会工作:
@Override
public void treeExpanded(TreeExpansionEvent event) {
//DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
//refreshNode(node);
}
工作完美。手动单步遍历树时,需要临时删除Expansionlistener。谢谢
@Override
public void treeExpanded(TreeExpansionEvent event) {
//DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
//refreshNode(node);
}