swing JTable使用 作者:马育民 • 2025-08-06 14:56 • 阅读:10007 # 例子 实现下图效果: [](https://www.malaoshi.top/upload/0/0/1GW1ctu3KfLq.png) ``` import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumnModel; import java.awt.*; public class TableHeaderCenterExample extends JFrame { protected DefaultTableModel tableModel; public TableHeaderCenterExample() { super("表头居中的JTable示例"); initUI(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(700, 400); setLocationRelativeTo(null); } private void initUI() { // JTable采用MVC设计模式,表头、数据封装在 DefaultTableModel 中 // 定义表格列名 String[] columnNames = {"文件名", "状态", "操作"}; // 创建表格模型(最后一个参数表示不可编辑) tableModel = new DefaultTableModel(columnNames, 0) { @Override public boolean isCellEditable(int row, int column) { // 只有删除按钮列可编辑(否则按钮无法处理事件) return column == 2; } // 设置列数据类型,确保按钮能正确渲染 // @Override // public Class> getColumnClass(int column) { // return (column == 2) ? JButton.class : String.class; // } }; // 2. 创建表格 // JTable table = new JTable(model); JTable table = new JTable(); table.setModel(tableModel); //设置列宽度,必须调用 table.setModel(tableModel) 后才能执行 // 获取列模型 TableColumnModel columnModel = table.getColumnModel(); // 方式1:固定列宽(最常用) columnModel.getColumn(0).setPreferredWidth(800); // 文件名:200像素 // columnModel.getColumn(1).setPreferredWidth(50); // 大小:80像素 TableColumn column2 = columnModel.getColumn(1); column2.setPreferredWidth(220); // 首选宽度 column2.setMinWidth(120); // 最小宽度(不能再小) column2.setMaxWidth(120); // 最大宽度(不能再大) // columnModel.getColumn(2).setPreferredWidth(50); // 类型:120像素 // 方式2:设置最小/最大宽度(限制拉伸范围) TableColumn column3 = columnModel.getColumn(2); column3.setPreferredWidth(100); // 首选宽度 column3.setMinWidth(100); // 最小宽度(不能再小) column3.setMaxWidth(100); // 最大宽度(不能再大) // 设置单元格居中显示 // 创建居中渲染器 DefaultTableCellRenderer headerRenderer = new DefaultTableCellRenderer(); headerRenderer.setHorizontalAlignment(SwingConstants.CENTER); // 水平居中 headerRenderer.setVerticalAlignment(SwingConstants.CENTER); // 垂直居中 column2.setCellRenderer(headerRenderer); // 为第三列设置按钮渲染器和编辑器 column3.setCellRenderer(new ButtonRenderer()); // 点击表格时,会触发表格的编辑事件,而要想触发渲染的按钮的事件,还需要通过修改表格的默认编辑器来实现 column3.setCellEditor( new ButtonEditor(new JCheckBox()) ); // 添加示例数据 addTableRow("document.txt", "已处理"); addTableRow("image.png", "未处理"); addTableRow("data.csv", "处理中"); addTableRow("archive.zip", "已处理"); // 5. 添加到滚动面板 JScrollPane scrollPane = new JScrollPane(table); getContentPane().add(scrollPane); } public void addTableRow(String file, String status) { // 每行数据:文件名、状态、删除按钮(按钮文本会被渲染器忽略) tableModel.addRow(new Object[]{ file, status, "移除" }); } // 按钮渲染器:负责在单元格中显示按钮 private class ButtonRenderer extends JButton implements TableCellRenderer { public ButtonRenderer() { setOpaque(true); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // 设置按钮文本 setText((value == null) ? "删除" : value.toString()); // 选中行时高亮按钮背景 // setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); return this; } } // 按钮编辑器:处理按钮点击事件 private class ButtonEditor extends DefaultCellEditor { private JButton button; private String label; private boolean isPushed; private int selectedRow; public ButtonEditor(JCheckBox checkBox) { super(checkBox); button = new JButton(); button.setOpaque(true); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { fireEditingStopped(); // 停止编辑状态 } }); } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { label = (value == null) ? "删除" : value.toString(); button.setText(label); isPushed = true; selectedRow = row; // 记录当前行 return button; } @Override public Object getCellEditorValue() { if (isPushed) { // 确认删除 int confirm = JOptionPane.showConfirmDialog( table, "确定要移除 " + tableModel.getValueAt(selectedRow, 0) + " 吗?", "警告", JOptionPane.YES_NO_OPTION ); if (confirm == JOptionPane.YES_OPTION) { // 从表格模型中移除行 tableModel.removeRow(selectedRow); } } isPushed = false; return label; } @Override public boolean stopCellEditing() { isPushed = false; return super.stopCellEditing(); } } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { new TableHeaderCenterExample().setVisible(true); }); } } ``` ### 注意 JTable 必须放在 JScrollPanel 中,才能显示表头 # 遍历数据 ### 方式1:通过TableModel遍历(推荐) ``` private void traverseByModel(ActionEvent e) { StringBuilder sb = new StringBuilder(); sb.append("通过模型遍历结果:\n"); // 获取行数和列数 int rowCount = tableModel.getRowCount(); int colCount = tableModel.getColumnCount(); // 遍历所有行和列 for (int row = 0; row < rowCount; row++) { sb.append("第").append(row + 1).append("行:"); for (int col = 0; col < colCount; col++) { // 获取单元格数据 Object value = tableModel.getValueAt(row, col); sb.append(value).append(" | "); } sb.append("\n"); } JOptionPane.showMessageDialog(this, sb.toString()); } ``` ### 方式2:通过JTable组件遍历(受UI状态影响) ``` private void traverseByTable(ActionEvent e) { StringBuilder sb = new StringBuilder(); sb.append("通过表格组件遍历结果:\n"); // 获取行数和列数 int rowCount = dataTable.getRowCount(); int colCount = dataTable.getColumnCount(); // 遍历所有行和列 for (int row = 0; row < rowCount; row++) { sb.append("第").append(row + 1).append("行:"); for (int col = 0; col < colCount; col++) { // 获取单元格数据(注意:这里的row是视图行号,可能与模型行号不同) Object value = dataTable.getValueAt(row, col); sb.append(value).append(" | "); } sb.append("\n"); } JOptionPane.showMessageDialog(this, sb.toString()); } ``` # 清空数据 ``` tableModel.setRowCount(0); ``` # 修改值 将第1行第2列的单元格修改为 `转换成功`: ``` tableModel.setValueAt("转换成功",0, 1); ``` 原文出处:http://www.malaoshi.top/show_1GW1cu0JEpH3.html