jtable树形表
时间: 2023-08-23 09:06:47 浏览: 122
JTable 是 Java Swing 中的一个组件,用于显示表格数据。如果需要在 JTable 中显示树形结构的数据,可以通过使用 JTree 和 JTable 的组合来实现。
实现步骤如下:
1. 创建一个 JTree 对象来表示树形结构的数据。
2. 创建一个 DefaultTableModel 对象作为 JTable 的数据模型。
3. 将 JTable 的数据模型设置为一个可编辑的 TreeTableModel,其中 TreeTableModel 是一个自定义的接口,继承了 TableModel 和 TreeModel 接口。
4. 将 JTable 和 JTree 进行组合,使得 JTable 中每一行的第一列是一个可展开/折叠的树形节点。
以下是一个简单的示例代码:
```java
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public class JTableTreeDemo extends JFrame {
private static final long serialVersionUID = 1L;
public JTableTreeDemo() {
super("JTableTreeDemo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建树形结构的数据
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("Node1");
DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("Node2");
DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("Node3");
root.add(node1);
root.add(node2);
node2.add(node3);
JTree tree = new JTree(root);
// 创建 JTable 的数据模型
DefaultTableModel model = new DefaultTableModel(new Object[][] {
{ "Node1", "Value1" },
{ "Node2", "Value2" },
{ "Node3", "Value3" },
}, new String[] { "Name", "Value" });
// 创建 TreeTableModel 对象,将 JTable 的数据模型设置为可编辑的 TreeTableModel
TreeTableModel treeTableModel = new TreeTableModel(tree.getModel(), model);
JTable table = new JTable(treeTableModel);
// 设置 JTable 中第一列为树形结构
table.getColumnModel().getColumn(0).setCellRenderer(new TreeTableCellRenderer());
table.setPreferredScrollableViewportSize(new Dimension(300, 200));
// 监听树形结构的变化,更新 JTable 的数据模型
tree.getModel().addTreeModelListener(new TreeModelListener() {
@Override
public void treeStructureChanged(TreeModelEvent e) {
treeTableModel.setTreeModel(tree.getModel());
}
@Override
public void treeNodesRemoved(TreeModelEvent e) {
treeTableModel.setTreeModel(tree.getModel());
}
@Override
public void treeNodesInserted(TreeModelEvent e) {
treeTableModel.setTreeModel(tree.getModel());
}
@Override
public void treeNodesChanged(TreeModelEvent e) {
treeTableModel.setTreeModel(tree.getModel());
}
});
// 将 JTable 和 JTree 进行组合
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setRowHeaderView(tree);
getContentPane().add(scrollPane, BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
JTableTreeDemo demo = new JTableTreeDemo();
demo.setVisible(true);
}
// TreeTableModel 接口的实现
private static class TreeTableModel implements TableModel, TreeModel {
private TreeModel treeModel;
private TableModel tableModel;
public TreeTableModel(TreeModel treeModel, TableModel tableModel) {
this.treeModel = treeModel;
this.tableModel = tableModel;
}
public void setTreeModel(TreeModel treeModel) {
this.treeModel = treeModel;
}
@Override
public int getRowCount() {
return tableModel.getRowCount();
}
@Override
public int getColumnCount() {
return tableModel.getColumnCount();
}
@Override
public String getColumnName(int columnIndex) {
return tableModel.getColumnName(columnIndex);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return tableModel.getColumnClass(columnIndex);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return tableModel.isCellEditable(rowIndex, columnIndex);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return tableModel.getValueAt(rowIndex, columnIndex);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
tableModel.setValueAt(aValue, rowIndex, columnIndex);
}
@Override
public void addTableModelListener(TableModelListener l) {
tableModel.addTableModelListener(l);
}
@Override
public void removeTableModelListener(TableModelListener l) {
tableModel.removeTableModelListener(l);
}
@Override
public Object getRoot() {
return treeModel.getRoot();
}
@Override
public Object getChild(Object parent, int index) {
return treeModel.getChild(parent, index);
}
@Override
public int getChildCount(Object parent) {
return treeModel.getChildCount(parent);
}
@Override
public boolean isLeaf(Object node) {
return treeModel.isLeaf(node);
}
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
treeModel.valueForPathChanged(path, newValue);
}
@Override
public int getIndexOfChild(Object parent, Object child) {
return treeModel.getIndexOfChild(parent, child);
}
@Override
public void addTreeModelListener(TreeModelListener l) {
treeModel.addTreeModelListener(l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
treeModel.removeTreeModelListener(l);
}
}
// 自定义的 TableCellRenderer,用于显示树形结构的数据
private static class TreeTableCellRenderer extends JTree implements javax.swing.table.TableCellRenderer {
private static final long serialVersionUID = 1L;
private int visibleRow;
public TreeTableCellRenderer() {
setRootVisible(false);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
visibleRow = row;
return this;
}
@Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
if (visibleRow >= 0) {
preferredSize.width = getParent().getWidth();
}
return preferredSize;
}
}
}
```
运行该示例代码,可以看到一个包含树形结构的 JTable。
阅读全文