【发布时间】:2015-05-07 21:34:11
【问题描述】:
我一直在尝试很多方法来限制我的代码仅将节点添加到第一级。这意味着用户只能将节点添加到 JTree 的第一级子级。
在我的程序中添加节点可以通过两种方式完成 1.添加节点按钮 2.选择>右键单击>添加节点(在这里,如果选择了非一级子节点,我想禁用此行为。虽然这是一个很长的镜头)
我需要一个允许在其他级别添加节点的验证。谢谢!
这是工作代码:
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.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class ProblemTree extends JFrame {
private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
private DefaultTreeModel model = new DefaultTreeModel(root);
private JTree tree = new JTree(model);
private JButton addButton = new JButton("Add Node to 1st level only");
public ProblemTree() {
DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(
"1st level: Child 1");
n1.add(new DefaultMutableTreeNode("2nd level: Child l"));
DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(
"1st level: Child 2");
n2.add(new DefaultMutableTreeNode("2nd level: Child 2"));
DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(
"1st level: Child 3");
n3.add(new DefaultMutableTreeNode("2nd level: Child 3"));
root.add(n1);
root.add(n2);
root.add(n3);
tree.setEditable(true);
tree.setSelectionRow(0);
tree.setRootVisible(true);
tree.setShowsRootHandles(true);
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem runTask = new JMenuItem("New Node for 1st level only =( ");
runTask.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
.getLastSelectedPathComponent();
if (selNode == null) {
return;
}
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
"New Node");
model.insertNodeInto(newNode, selNode, selNode.getChildCount());
TreeNode[] nodes = model.getPathToRoot(newNode);
TreePath path = new TreePath(nodes);
tree.scrollPathToVisible(path);
tree.setSelectionPath(path);
tree.startEditingAtPath(path);
}
});
popupMenu.add(runTask);
tree.setComponentPopupMenu(popupMenu);
JScrollPane scrollPane = new JScrollPane(tree);
getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
.getLastSelectedPathComponent();
if (selNode == null) {
return;
}
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
"New Node");
model.insertNodeInto(newNode, selNode, selNode.getChildCount());
TreeNode[] nodes = model.getPathToRoot(newNode);
TreePath path = new TreePath(nodes);
tree.scrollPathToVisible(path);
tree.setSelectionPath(path);
tree.startEditingAtPath(path);
}
});
panel.add(addButton);
getContentPane().add(panel, BorderLayout.SOUTH);
setSize(700, 400);
setVisible(true);
}
public static void main(String[] arg) {
ProblemTree pt = new ProblemTree();
}
}
【问题讨论】:
-
您可以同时使用 TreeModel 和自定义 TreeNode,这样当调用 insertNodeInto 之类的东西时,您可以检查父节点是否为第一级节点,如果不是,则拒绝插入.您的自定义节点还可以进一步限制子节点的添加,因此您的第一级节点将只接受非可变树节点......作为一个想法
-
@MadProgrammer 那么应该调用 model.reload
-
@mKorbel 我不这么认为,
insertNodeInto应该触发和事件通知,调用model.reload就像在AbstractTableModel上调用fireTableStructureChanged,这将导致树完全重绘,会影响当前展开的节点... -
@mKorbel 同意重新绘制,但您可能会在 JTree 视图中丢失最后插入的节点,这可能是 JTree(以及相关)API 中缺少抽象的原因之一,它无法正常工作在某些情况下,AFAIK 在这里几次
标签: java swing validation nodes jtree