本文目录导读:

我来详细介绍Java Swing中JTable表格的数据展示和编辑功能。
基本JTable创建
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
public class JTableDemo extends JFrame {
public JTableDemo() {
setTitle("JTable示例");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
// 创建表格数据
String[] columnNames = {"ID", "姓名", "年龄", "性别", "部门"};
Object[][] data = {
{1, "张三", 28, "男", "技术部"},
{2, "李四", 32, "女", "市场部"},
{3, "王五", 25, "男", "人事部"},
{4, "赵六", 30, "女", "财务部"}
};
// 创建表格
JTable table = new JTable(data, columnNames);
// 添加到滚动面板
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane, BorderLayout.CENTER);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new JTableDemo().setVisible(true);
});
}
}
使用TableModel实现数据编辑
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
// 自定义数据模型
class Employee {
private int id;
private String name;
private int age;
private String gender;
private String department;
private double salary;
// 构造器、getter/setter
public Employee(int id, String name, int age, String gender, String department, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.department = department;
this.salary = salary;
}
// getter和setter方法
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getGender() { return gender; }
public void setGender(String gender) { this.gender = gender; }
public String getDepartment() { return department; }
public void setDepartment(String department) { this.department = department; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }
}
// 自定义表格模型
class EmployeeTableModel extends AbstractTableModel {
private String[] columnNames = {"ID", "姓名", "年龄", "性别", "部门", "薪资"};
private List<Employee> employees;
private boolean[] editableColumns = {false, true, true, true, true, true}; // ID列不可编辑
public EmployeeTableModel(List<Employee> employees) {
this.employees = employees;
}
@Override
public int getRowCount() {
return employees.size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Employee emp = employees.get(rowIndex);
switch (columnIndex) {
case 0: return emp.getId();
case 1: return emp.getName();
case 2: return emp.getAge();
case 3: return emp.getGender();
case 4: return emp.getDepartment();
case 5: return emp.getSalary();
default: return null;
}
}
@Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
Employee emp = employees.get(rowIndex);
switch (columnIndex) {
case 1: emp.setName((String) value); break;
case 2: emp.setAge(Integer.parseInt(value.toString())); break;
case 3: emp.setGender((String) value); break;
case 4: emp.setDepartment((String) value); break;
case 5: emp.setSalary(Double.parseDouble(value.toString())); break;
}
fireTableCellUpdated(rowIndex, columnIndex);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return editableColumns[columnIndex];
}
// 获取指定行的数据类型
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0: return Integer.class;
case 2: return Integer.class;
case 5: return Double.class;
default: return String.class;
}
}
public void addEmployee(Employee emp) {
employees.add(emp);
fireTableRowsInserted(employees.size() - 1, employees.size() - 1);
}
public void removeEmployee(int row) {
employees.remove(row);
fireTableRowsDeleted(row, row);
}
}
// 使用示例
public class EditableJTableDemo extends JFrame {
private EmployeeTableModel tableModel;
private JTable table;
public EditableJTableDemo() {
setTitle("可编辑的JTable示例");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 500);
setLocationRelativeTo(null);
// 准备初始数据
List<Employee> employees = new ArrayList<>();
employees.add(new Employee(1, "张三", 28, "男", "技术部", 8000.0));
employees.add(new Employee(2, "李四", 32, "女", "市场部", 7500.0));
employees.add(new Employee(3, "王五", 25, "男", "人事部", 6500.0));
// 创建表格模型和表格
tableModel = new EmployeeTableModel(employees);
table = new JTable(tableModel);
// 设置表格属性
table.setRowHeight(30);
table.setFont(new Font("微软雅黑", Font.PLAIN, 14));
table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 14));
// 设置列宽
table.getColumnModel().getColumn(0).setPreferredWidth(50);
table.getColumnModel().getColumn(1).setPreferredWidth(100);
table.getColumnModel().getColumn(5).setPreferredWidth(100);
// 滚动面板
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane, BorderLayout.CENTER);
// 控制面板
JPanel controlPanel = new JPanel();
JButton addBtn = new JButton("添加行");
JButton deleteBtn = new JButton("删除选中行");
JButton saveBtn = new JButton("保存数据");
addBtn.addActionListener(e -> addRow());
deleteBtn.addActionListener(e -> deleteSelectedRow());
saveBtn.addActionListener(e -> saveData());
controlPanel.add(addBtn);
controlPanel.add(deleteBtn);
controlPanel.add(saveBtn);
add(controlPanel, BorderLayout.SOUTH);
}
private void addRow() {
int newId = tableModel.getRowCount() + 1;
Employee emp = new Employee(newId, "新员工", 20, "男", "待分配", 5000.0);
tableModel.addEmployee(emp);
}
private void deleteSelectedRow() {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
int confirmed = JOptionPane.showConfirmDialog(
this,
"确认删除第 " + (selectedRow + 1) + " 行?",
"确认删除",
JOptionPane.YES_NO_OPTION
);
if (confirmed == JOptionPane.YES_OPTION) {
tableModel.removeEmployee(selectedRow);
}
} else {
JOptionPane.showMessageDialog(this, "请先选择要删除的行");
}
}
private void saveData() {
// 停止单元格编辑
if (table.isEditing()) {
table.getCellEditor().stopCellEditing();
}
// 这里可以保存数据到数据库或文件
JOptionPane.showMessageDialog(this, "数据保存成功!");
// 打印当前数据
System.out.println("当前数据:");
for (int i = 0; i < tableModel.getRowCount(); i++) {
for (int j = 0; j < tableModel.getColumnCount(); j++) {
System.out.print(tableModel.getValueAt(i, j) + "\t");
}
System.out.println();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new EditableJTableDemo().setVisible(true);
});
}
}
单元格编辑器定制
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.text.NumberFormat;
// 自定义单元格编辑器
public class CustomCellEditorDemo extends JFrame {
public CustomCellEditorDemo() {
setTitle("自定义单元格编辑器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
// 创建表格数据
String[] columnNames = {"姓名", "年龄", "性别", "城市", "评分"};
Object[][] data = {
{"张三", 28, "男", "北京", 85.5},
{"李四", 32, "女", "上海", 92.3},
{"王五", 25, "男", "广州", 78.0}
};
JTable table = new JTable(data, columnNames);
// 为性别列设置下拉框编辑器
JComboBox<String> genderCombo = new JComboBox<>(new String[]{"男", "女"});
TableColumn genderColumn = table.getColumnModel().getColumn(2);
genderColumn.setCellEditor(new DefaultCellEditor(genderCombo));
// 为年龄列设置数字限制
TableColumn ageColumn = table.getColumnModel().getColumn(1);
ageColumn.setCellEditor(new DefaultCellEditor(new JTextField()) {
@Override
public boolean stopCellEditing() {
try {
String value = (String) getCellEditorValue();
int age = Integer.parseInt(value);
if (age < 0 || age > 150) {
throw new NumberFormatException();
}
return super.stopCellEditing();
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(
CustomCellEditorDemo.this,
"请输入有效的年龄 (0-150)",
"输入错误",
JOptionPane.ERROR_MESSAGE
);
return false;
}
}
});
// 为城市列设置自动完成文本框
JTextField cityField = new JTextField();
TableColumn cityColumn = table.getColumnModel().getColumn(3);
cityColumn.setCellEditor(new DefaultCellEditor(cityField));
// 设置表格属性
table.setRowHeight(30);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new CustomCellEditorDemo().setVisible(true);
});
}
}
单元格渲染器定制
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
// 自定义单元格渲染器
public class CustomCellRendererDemo extends JFrame {
public CustomCellRendererDemo() {
setTitle("自定义单元格渲染器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
// 创建表格数据
String[] columnNames = {"姓名", "年龄", "性别", "成绩", "状态"};
Object[][] data = {
{"张三", 28, "男", 85, "及格"},
{"李四", 32, "女", 45, "不及格"},
{"王五", 25, "男", 92, "优秀"},
{"赵六", 30, "女", 60, "及格"},
{"钱七", 27, "男", 38, "不及格"}
};
JTable table = new JTable(data, columnNames);
// 自定义成绩列渲染器
TableColumn scoreColumn = table.getColumnModel().getColumn(3);
scoreColumn.setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
int score = (int) value;
if (score >= 90) {
c.setBackground(new Color(144, 238, 144)); // 浅绿色
c.setForeground(Color.BLACK);
} else if (score >= 60) {
c.setBackground(new Color(255, 255, 224)); // 浅黄色
c.setForeground(Color.BLACK);
} else {
c.setBackground(new Color(255, 182, 193)); // 浅红色
c.setForeground(Color.RED);
}
if (isSelected) {
c.setBackground(c.getBackground().darker());
}
setHorizontalAlignment(CENTER);
return c;
}
});
// 自定义状态列渲染器
TableColumn statusColumn = table.getColumnModel().getColumn(4);
statusColumn.setCellRenderer(new StatusCellRenderer());
// 自定义性别列显示
TableColumn genderColumn = table.getColumnModel().getColumn(2);
genderColumn.setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
String gender = (String) value;
if ("男".equals(gender)) {
setIcon(new ImageIcon("male_icon.png")); // 使用图标
setText("♂ " + gender);
} else {
setIcon(new ImageIcon("female_icon.png"));
setText("♀ " + gender);
}
setHorizontalAlignment(CENTER);
return c;
}
});
// 交替行颜色
table.setRowHeight(30);
table.setFont(new Font("微软雅黑", Font.PLAIN, 14));
// 设置表格外观
table.setShowGrid(true);
table.setGridColor(Color.LIGHT_GRAY);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
// 自定义状态渲染器
class StatusCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
String status = (String) value;
switch (status) {
case "优秀":
setBackground(new Color(0, 128, 0));
setForeground(Color.WHITE);
break;
case "及格":
setBackground(new Color(255, 165, 0));
setForeground(Color.BLACK);
break;
case "不及格":
setBackground(new Color(255, 0, 0));
setForeground(Color.WHITE);
break;
}
if (isSelected) {
setBackground(setBackground.getDarker());
}
setHorizontalAlignment(CENTER);
setFont(getFont().deriveFont(Font.BOLD));
return c;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new CustomCellRendererDemo().setVisible(true);
});
}
}
高级功能:多选和排序
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.Comparator;
public class AdvancedJTableDemo extends JFrame {
public AdvancedJTableDemo() {
setTitle("高级JTable功能");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 500);
setLocationRelativeTo(null);
String[] columnNames = {"编号", "姓名", "年龄", "薪资", "入职日期"};
Object[][] data = {
{1, "张三", 28, 8000.0, "2023-01-15"},
{2, "李四", 32, 9500.0, "2022-06-20"},
{3, "王五", 25, 7000.0, "2024-03-01"},
{4, "赵六", 30, 8800.0, "2023-09-10"}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public boolean isCellEditable(int row, int column) {
return column > 0; // 除了编号都可以编辑
}
};
JTable table = new JTable(model);
// 启用自动排序
table.setAutoCreateRowSorter(true);
// 设置选择模式
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// 设置列宽
table.getColumnModel().getColumn(0).setPreferredWidth(60);
table.getColumnModel().getColumn(1).setPreferredWidth(100);
table.getColumnModel().getColumn(2).setPreferredWidth(60);
table.getColumnModel().getColumn(3).setPreferredWidth(100);
table.getColumnModel().getColumn(4).setPreferredWidth(120);
// 自定义排序器(按年龄排序时特殊处理)
TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
sorter.setComparator(2, (Integer o1, Integer o2) -> o1.compareTo(o2));
table.setRowSorter(sorter);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane, BorderLayout.CENTER);
// 添加选择监听
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int[] selectedRows = table.getSelectedRows();
if (selectedRows.length > 0) {
StringBuilder sb = new StringBuilder("选中的行: ");
for (int row : selectedRows) {
int modelRow = table.convertRowIndexToModel(row);
sb.append("行").append(modelRow + 1).append(" ");
}
System.out.println(sb.toString());
}
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new AdvancedJTableDemo().setVisible(true);
});
}
}
注意事项
- 性能优化:大数据量时使用虚拟模式
- 线程安全:Swing组件操作应在EDT线程中进行
- 数据验证:在
setValueAt()中进行数据验证 - 模型-视图分离:尽量使用TableModel而非直接操作数据
这些示例涵盖了JTable的展示、编辑、自定义渲染和高级功能,可以根据具体需求进行调整和扩展。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播