本文目录导读:

我来详细介绍JTree树形数据展示的各种操作:
基础树形结构创建
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
public class TreeExample {
public static void main(String[] args) {
JFrame frame = new JFrame("JTree示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
// 创建根节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");
// 创建子节点
DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("节点1");
DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("节点2");
DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("节点3");
// 创建叶子节点
DefaultMutableTreeNode leaf1 = new DefaultMutableTreeNode("叶子1");
DefaultMutableTreeNode leaf2 = new DefaultMutableTreeNode("叶子2");
// 构建树
root.add(node1);
root.add(node2);
root.add(node3);
node1.add(leaf1);
node1.add(leaf2);
// 创建JTree
JTree tree = new JTree(root);
frame.add(new JScrollPane(tree));
frame.setVisible(true);
}
}
动态添加节点
public class DynamicTreeExample {
private DefaultMutableTreeNode selectedNode;
private DefaultTreeModel model;
// 添加子节点
public void addChildNode(String nodeName) {
if (selectedNode != null) {
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(nodeName);
model.insertNodeInto(newNode, selectedNode, selectedNode.getChildCount());
// 展开新节点
tree.scrollPathToVisible(new TreePath(newNode.getPath()));
}
}
// 删除节点
public void removeSelectedNode() {
if (selectedNode != null && selectedNode.getParent() != null) {
model.removeNodeFromParent(selectedNode);
}
}
// 添加根节点
public void addRootNode(String rootName) {
DefaultMutableTreeNode newRoot = new DefaultMutableTreeNode(rootName);
model.setRoot(newRoot);
tree.expandPath(new TreePath(newRoot.getPath()));
}
}
节点事件处理
public class TreeEventListener {
// 节点选择事件
public void setupNodeSelectionListener(JTree tree) {
tree.addTreeSelectionListener(e -> {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
if (selectedNode != null) {
System.out.println("选中节点: " + selectedNode.getUserObject());
System.out.println("层级: " + selectedNode.getLevel());
System.out.println("是否是叶子节点: " + selectedNode.isLeaf());
}
});
}
// 节点展开/折叠事件
public void setupExpandCollapseListener(JTree tree) {
tree.addTreeExpansionListener(new TreeExpansionListener() {
@Override
public void treeExpanded(TreeExpansionEvent event) {
TreePath path = event.getPath();
System.out.println("展开节点: " + path.getLastPathComponent());
}
@Override
public void treeCollapsed(TreeExpansionEvent event) {
TreePath path = event.getPath();
System.out.println("折叠节点: " + path.getLastPathComponent());
}
});
}
}
自定义节点渲染
public class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
// 自定义图标
if (node.isLeaf()) {
setIcon(new ImageIcon("leaf_icon.png"));
} else if (expanded) {
setIcon(new ImageIcon("expanded_icon.png"));
} else {
setIcon(new ImageIcon("collapsed_icon.png"));
}
// 自定义颜色
if (node.getLevel() == 0) {
setForeground(Color.RED);
} else if (node.getLevel() == 1) {
setForeground(Color.BLUE);
}
// 自定义字体
if (node.getLevel() == 0) {
setFont(getFont().deriveFont(Font.BOLD, 14));
}
return this;
}
}
搜索和过滤
public class TreeSearchFilter {
// 搜索节点
public List<TreePath> searchNodes(DefaultMutableTreeNode root, String searchText) {
List<TreePath> result = new ArrayList<>();
if (searchText == null || searchText.isEmpty()) {
return result;
}
searchNodesRecursive(root, new TreePath(root), searchText.toLowerCase(), result);
return result;
}
private void searchNodesRecursive(DefaultMutableTreeNode node,
TreePath path, String searchText, List<TreePath> result) {
String nodeText = node.getUserObject().toString().toLowerCase();
if (nodeText.contains(searchText)) {
result.add(path);
}
for (int i = 0; i < node.getChildCount(); i++) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
searchNodesRecursive(child, path.pathByAddingChild(child), searchText, result);
}
}
// 节点过滤(只显示匹配的节点)
public void filterTree(JTree tree, String filter) {
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
filterNode(root, filter.toLowerCase());
model.reload();
expandAllNodes(tree);
}
private boolean filterNode(DefaultMutableTreeNode node, String filter) {
boolean matches = node.getUserObject().toString().toLowerCase().contains(filter);
// 递归检查子节点
for (int i = node.getChildCount() - 1; i >= 0; i--) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
boolean childMatches = filterNode(child, filter);
if (!childMatches) {
node.remove(i);
}
matches = matches || childMatches;
}
return matches;
}
}
拖拽操作
public class DragDropTreeExample {
public void enableDragDrop(JTree tree) {
// 启用拖拽
tree.setDragEnabled(true);
tree.setTransferHandler(new TreeTransferHandler());
// 设置拖拽模式
tree.getDropTarget().setDefaultActions(DnDConstants.MOVE);
}
// 自定义TransferHandler
class TreeTransferHandler extends TransferHandler {
private DataTransferNode[] nodes = null;
@Override
public int getSourceActions(JComponent c) {
return TransferHandler.COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(JComponent c) {
JTree tree = (JTree) c;
TreePath[] paths = tree.getSelectionPaths();
if (paths != null) {
nodes = new DataTransferNode[paths.length];
for (int i = 0; i < paths.length; i++) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) paths[i].getLastPathComponent();
nodes[i] = new DataTransferNode(node);
}
}
return new DataTransferable(nodes);
}
@Override
public boolean canImport(TransferSupport support) {
return support.isDataFlavorSupported(DataFlavor.stringFlavor);
}
@Override
public boolean importData(TransferSupport support) {
// 实现导入逻辑
return true;
}
}
}
完整示例:文件浏览器
public class FileTreeBrowser extends JPanel {
private JTree tree;
private DefaultTreeModel model;
private DefaultMutableTreeNode root;
public FileTreeBrowser() {
setLayout(new BorderLayout());
// 创建根节点
root = new DefaultMutableTreeNode("我的电脑");
model = new DefaultTreeModel(root);
tree = new JTree(model);
// 添加系统根目录
File[] roots = File.listRoots();
for (File rootFile : roots) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(rootFile);
root.add(node);
// 预加载子文件
addDummyChildren(node);
}
// 设置渲染器
tree.setCellRenderer(new FileTreeCellRenderer());
// 添加展开事件
tree.addTreeWillExpandListener(new TreeWillExpandListener() {
@Override
public void treeWillExpand(TreeExpansionEvent event)
throws ExpandVetoException {
TreePath path = event.getPath();
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) path.getLastPathComponent();
// 动态加载子文件
if (node.getChildCount() == 1 &&
node.getChildAt(0).toString().equals("加载中...")) {
node.removeAllChildren();
loadChildren(node);
}
}
@Override
public void treeWillCollapse(TreeExpansionEvent event)
throws ExpandVetoException {
// 允许折叠
}
});
add(new JScrollPane(tree), BorderLayout.CENTER);
}
private void addDummyChildren(DefaultMutableTreeNode node) {
node.add(new DefaultMutableTreeNode("加载中..."));
}
private void loadChildren(DefaultMutableTreeNode node) {
File file = (File) node.getUserObject();
File[] files = file.listFiles();
if (files != null) {
for (File child : files) {
DefaultMutableTreeNode childNode =
new DefaultMutableTreeNode(child);
node.add(childNode);
// 如果是目录,添加占位节点
if (child.isDirectory()) {
addDummyChildren(childNode);
}
}
}
model.reload(node);
}
// 文件树渲染器
class FileTreeCellRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object userObject = node.getUserObject();
if (userObject instanceof File) {
File file = (File) userObject;
setText(file.getName().isEmpty() ? file.getPath() : file.getName());
// 设置图标
if (file.isDirectory()) {
setIcon(UIManager.getIcon("FileView.directoryIcon"));
} else {
setIcon(UIManager.getIcon("FileView.fileIcon"));
}
}
return this;
}
}
}
性能优化技巧
public class TreePerformanceOptimization {
// 延迟加载
public void lazyLoadChildren(DefaultMutableTreeNode node) {
// 只在节点展开时才加载子节点
if (node.getAllowsChildren() && node.getChildCount() == 0) {
loadChildNodesAsync(node);
}
}
// 异步加载
private void loadChildNodesAsync(DefaultMutableTreeNode node) {
SwingWorker<Void, DefaultMutableTreeNode> worker =
new SwingWorker<Void, DefaultMutableTreeNode>() {
@Override
protected Void doInBackground() throws Exception {
// 模拟耗时操作
Thread.sleep(100);
// 批量添加子节点
for (int i = 0; i < 100; i++) {
DefaultMutableTreeNode child =
new DefaultMutableTreeNode("子节点 " + i);
publish(child);
}
return null;
}
@Override
protected void process(List<DefaultMutableTreeNode> chunks) {
for (DefaultMutableTreeNode child : chunks) {
node.add(child);
}
model.reload(node);
}
};
worker.execute();
}
// 批量更新
public void batchUpdate(DefaultTreeModel model,
DefaultMutableTreeNode parent, List<String> newChildren) {
// 暂时关闭监听器
model.removeTreeModelListener(model.getTreeModelListeners()[0]);
// 批量操作
for (String childName : newChildren) {
DefaultMutableTreeNode child = new DefaultMutableTreeNode(childName);
model.insertNodeInto(child, parent, parent.getChildCount());
}
// 重新启用监听器并刷新
model.addTreeModelListener(new DefaultTreeModelListener());
model.reload();
}
}
这些示例涵盖了JTree的常见操作,你可以根据实际需求选择合适的实现方式,记住要处理好线程安全问题,特别是在Swing事件线程中进行更新操作。