一、表格基础操作
1. 表头可以使用任意类型的一维数组
String[] cols = {“”,””,””};
2. 表格数据可以使用任意类型的二维数组
String[][] rows={{},{},{}};
3.获得行数
tableModel.getRowCount()
4. 获得列数
tableModel.getColumnCount()
5. 添加一行
Object[] obj={};
tableModel.addRow(obj);
6. 删除一行
tableModel.removeRow(table.getSelectedRow());//删除被选中的行
7. 获得具体单元格的数值
tableModel.getValueAt(row, col);
8. 直接修改具体单元格数据,必须这样才能使得模型被改变
table.getModel().addTableModelListener(
new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
// TODO
}
});
9. 使用JScrollPane才能显示表头
JScrollPane sp = new JScrollPane(table);
二、高级
1. 自定义数据模型
假设有Student类,需要把一个学生列表渲染成表格的形式
public class Student{
Integer id;
String name;
Integer age;
//此处省略了setter和getter和toString()
}
(1). 继承AbstractTableModel
StudentTableModel类中成员可以这样设计:
String[] columns={"学号","姓名","年龄"}; //列名
ArrayList<Student> list = new ArrayList<Student>(); //单元格数据
(2). 覆盖以下方法:
① getRowCount() //计算行数
@Override
public int getRowCount() {
return list.size();
}
② getColumnCount() //计算列数
@Override
public int getColumnCount() {
return columns.length;
}
③ getValueAt(int row,int column) //获得某单元格的值
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student stu = list.get(rowIndex);
switch(columnIndex){
case 0: return stu.id;
case 1: return stu.name;
case 2: return stu.age;
default: return "";
}
}
④ getColumnName(int col) //自定义列名,默认为A,B,C.
public String getColumnName(int col){
return columns[col];
}
⑤ isCellEditable(int row,int col) //判断单元格是否可以编辑
设置任意单元格都可以编辑
public boolean isCellEditable(int rowIndex, int columnIndex){
return true;
}
指定某一列或者某几列可以编辑,下面指定的是第1列和第2列可以编辑:
@Override
public boolean isCellEditable(int row, int column) {
return column==0 || column==1;
}
⑥ getColumnClass() //处理列类型
@SuppressWarnings("unchecked")
public Class getColumnClass(int col){
Class c = null;
try{
c = getValueAt(0, col).getClass(); //元素是什么类型就那对应的列就什么类型
}catch(Exception e){
//发生异常时,不显示任何数据,主要处理空值异常
}
return c;
}
(7) setValue() //修改单元格的值
@Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
// 单元格原始值
Object origin = this.getValueAt(rowIndex, columnIndex);
// 获得表格行对应的数据对象
Student stu = list.get(rowIndex);
// 如果是第2列,并且修改后的值与原值不同,第2列对应的是学生姓名
if (columnIndex == 1 && !origin.equals(value)) {
// 修改对象的属性
stu.setName((String) value);
//可以进行数据库更新或其他操作
//如果处理成功,通知table单元格有更新,视图才会进行更新
fireTableCellUpdated(rowIndex, columnIndex);
//如果不成功可以设置回原来的值
}
// 修改第3列,第3列对应的是学生年龄
else if (columnIndex == 2 && !origin.equals(value)) {
// 修改对象的属性
stu.setAge((Integer) value);
//可以进行存库等操作
//如果处理成功,通知table单元格有更新,视图才会进行更新
fireTableCellUpdated(rowIndex, columnIndex);
//如果不成功可以设置回原来的值
}
}
(8) 模型中可以自定义addRow方法、removeRow方法等,对应的操作就是对list进行添加和删除
/**
* 行索引
* @param rowIndex
*/
public void removeRow(int rowIndex) {
//获得表格行对应的对象
Student grp = list.get(rowIndex);
//可以进行更新数据库或其他操作
//从模型中删除
list.remove(rowIndex);
}
2.表格外观及单元格渲染
(1). 单元格内容居中显示
//获得单元格渲染器
DefaultTableCellRenderer r = new DefaultTableCellRenderer();
//设置水平对齐方式
r.setHorizontalAlignment(JLabel.CENTER);
//将上述渲染器安装在表格上,第一个参数表示无论列是什么类型,都安装
t.setDefaultRenderer(Object.class, r);
(2). 设置行高
- table.setRowHeight(height); //每一行的行高
- table.setRowHeight(row,height); //某一行的行高
- table.setRowMargin(margin); //行边距,默认行边距为一个像素
实际行高 = 所设置的行高 - 行边距
(3) 列的大小
//通过表格的列模型根据列索引获得对应的列
TableColumn col=table.getColumnModel().getColumn(index);
col.setPreferredWidth(width);//首选宽度
col.setMinWidth(width);//最小宽度
col.setMaxWidth(width);//最大宽度
(4) 隐藏和显示列
TableColumn col=table.getColumnModel().getColumn(index);
table.removeColumn(col);//隐藏列
table.addColumn(col);//显示列,在最后一列之后
table.addColumn(new TableColumn(index));//显示在任意列之后
(5). 绘制表头
下面代码是设置简单的图片表头,实现复选框表头等复杂表头可以参考:复选框表头的实现
//获得某列
TableColumn col=table.getColumnModel().getColumn(index);
//设置表头值
col.setHeaderValue(new ImageIcon(“image.jpg”));
//安装绘制器
col.setHeaderRenderer(table.getDefaultRenderer(ImageIcon.class));
//设置表头文字居中
DefaultTableCellRenderer renderer =
(DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
renderer.setHorizontalAlignment(renderer.CENTER);
(6). 网格线
3. 排序
(1) 自动排序
table.setAutoCreateRowSorter();
(2) 自定义排序规则
TableRowSorter<TableModel> sorter=new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
sorter.setSorterable(colIndex,false);//某些列不需要排序
4. 自定义单元格编辑器
比如某单元格需要打开日期选择器来编辑日期。由于swing未提供默认的日期选择器,所以这里使用的是第三方库。
(1) 实现日期单元格编辑器
package ui.editor;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import com.toedter.calendar.JDateChooser;
/**
* Title: DateTableCellEditor
* Description: 日期表格编辑器
* @author Herrona
*/
public class DateTableCellEditor extends AbstractCellEditor implements TableCellEditor {
JDateChooser calendar; //日期选择器
JLabel status = new JLabel(); //编辑状态提示标签
/**
* 编辑器的实现,当单元格处于编辑状态,将打开一个日期选择器
*/
@Override
public JComponent getTableCellEditorComponent(final JTable table,
Object value, boolean isSelected, int row,int column) {
//格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//如果原来单元格有值,则将该值转换成日期作为编辑器的默认值,原来的值通常是一个字符串
if (value != null) {
Date date;
try {
date = sdf.parse(value.toString());
calendar = new JDateChooser(date);
} catch (ParseException e) {
//转换失败,则不作为默认值显示
calendar = new JDateChooser();
}
} else
calendar = new JDateChooser();
return calendar;
}
/**
* 编辑完成后返回的值
*/
@Override
public Object getCellEditorValue() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String text = sdf.format(calendar.getDate());
return text;
}
}
(2) 给表格安装编辑器
//获得具体的列,假设第2列是需要日期编辑器
TableColumn dateCol = table.getColumnModel().getColumn(1);
//给列安装日期编辑器
dateCol.setCellEditor(new DateTableCellEditor());
(3) 实现效果