JTable作为java swing中一个最为常用的组件在日常的UI设计中有重要的作用,最近在写代码的过程中总结了一点心得,现少做总结。
生成JTable时自己比较习惯下面的构造方法(摘自JDK Doc):
JTable(TableModel dm):构造 JTable,使用 dm 作为数据模型、默认的列模型和默认的选择模型对其进行初始化。
如果只是显示一个表格而并不编辑它,则可以通过模型的setValueAt方法直接为单元格进行一次初始化赋值即可,但是如果需要对表格内容进行增删改,这种方法就有点捉襟见肘了。
TableModel接口的实现类有AbstractTableModel, DefaultTableModel。其中DefaultTableModel类继承自AbstractTableModel类,除了AbstractTableModel类的基本方法 :
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
外,还为表格模型提供了更多的方便表格操作的方法,如:insertRow,removeRow,addRow等方法。可以利用DefaultTableModel实现表格的操作控制。但是defaultTableModel的一些方法可能对你又用不到,此时便可以参考DefaultTableModel类的源码定制一个自己的TableModel类。
其实,定制一个TableModel类主要从两个方面着手:
第一:知道表格显示一个单元格内容时是根据getValueAt方法来获取的。为了更好管理表格,需要将表格所有的行数据关联一个Vector(ArrayList或LinkedList),而其中的元素为一个bean,对应了一个表格行数据,而具体到某个单元格数据则是行bean的某个字段的值,由此实现Vector(ArrayList或LinkedList)与表格关联。
第二:为了实现Vector(ArrayList或LinkedList)与表格的同步,更改了Vector(ArrayList或LinkedList)的内容后,需要通知监听器,表格内容需要改变。一般通过下面三个方法:
每次修改了Vector一个元素时,调用fireTableRowsUpdated(row,row)方法,通知表格该行数据已经改变,以实时刷新表格显示正确内容。
每次删除了Vector一个元素时,调用fireTableRowsDeleted(row,row)方法,通知表格该行数据已经删除,以实时刷新表格显示正确内容。
每次插入了Vector一个元素时,调用fireTableRowsInserted(row, row)方法,通知表格该行数据已经插入,以实时刷新表格显示正确内容。
而初始化一个表格时一般调用fireTableDataChanged()方法。
此处以包含学生学号,学生姓名,学生成绩三列的表格为例,首先写一个bean Student,然后给出相应的StudenttableModel,并给出了测试的例子TestFrame。
附测试源码:
/**
*Student.java
**/
public class Student {
private Integer sId;
private String sName;
private Integer sScore;
public Integer getSId() {
return sId;
}
public void setSId(Integer id) {
sId = id;
}
public String getSName() {
return sName;
}
public void setSName(String name) {
sName = name;
}
public Integer getSScore() {
return sScore;
}
public void setSScore(Integer score) {
sScore = score;
}
}
/**
*StudentTableModel.java
**/
import java.util.LinkedList;
import javax.swing.table.AbstractTableModel;
public class StudentTableModel extends AbstractTableModel{
private LinkedList sData;//元素类型为Student
private String[] columnName = new String[]{"学号","姓名","成绩"};
public StudentTableModel(){
}
public StudentTableModel(LinkedList sData){
this();
setSData(sData);
}
public void setSData(LinkedList sData){
this.sData = sData;
fireTableDataChanged();
}
public int getColumnCount() {
return columnName.length;
}
public String getColumnName(int i){
return columnName[i];
}
public int getRowCount() {
return sData.size();
}
public Object getValueAt(int rowIndex, int columnIndex) {
Student s = (Student) sData.get(rowIndex);
return getPropertyValueByCol(s,columnIndex);
}
public void addSData(int index, Student s){
if(index<0 || index>sData.size() -1){
sData.add(s);
fireTableRowsInserted(sData.size(),sData.size());
}
else{
sData.add(index, s);
fireTableRowsInserted(index,index);
}
}
public boolean deleteSData(int index){
if(index>=0 && index<sData.size()){
sData.remove(index);
fireTableRowsDeleted(index,index);
return true;
}
else
return false;
}
public boolean updateSData(int index, Student s){
if(index>=0 && index<sData.size()){
sData.set(index, s);
fireTableRowsUpdated(index,index);
return true;
}
else
return false;
}
public Student getSData(int index){
if(index>=0 && index<sData.size()){
return (Student) sData.get(index);
}
else
return null;
}
/**
* 将表格列映射到bean的字段
* @param s
* @param col
* @return
*/
public Object getPropertyValueByCol(Student s, int col){
switch(col){
case 0:
return s.getSId();
case 1:
return s.getSName();
case 2:
return s.getSScore();
}
return null;
}
}
/**
*TestFrame.java
*测试代码
**/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
public class TestFrame extends JFrame{
private JPanel pnlTop = null;
private JLabel lblSName = null;
private JLabel lblSId = null;
private JLabel lblSScore = null;
private JTextField txtSName = null;
private JTextField txtSId = null;
private JTextField txtSScore = null;
private JButton btnAdd = null;
private JButton btnDelete = null;
private JButton btnUpdate = null;
private JScrollPane panTable = null;
private JTable tblStudent = null;
private StudentTableModel tmdStudent = null;
private LinkedList lstStudent = null;
public StudentTableModel getTmdStudent(){
if(null == tmdStudent){
tmdStudent = new StudentTableModel(lstStudent);
return tmdStudent;
}
return tmdStudent;
}
public JTable getTblStudent(){
if(null == tblStudent){
tblStudent = new JTable(getTmdStudent());
return tblStudent;
}
return tblStudent;
}
public JScrollPane getPanTable(){
if (null == panTable){
panTable = new JScrollPane();
panTable.setViewportView(getTblStudent());
return panTable;
}
return panTable;
}
public JPanel getPnlTop(){
if(null == pnlTop){
pnlTop = new JPanel();
pnlTop.setLayout(new FlowLayout(FlowLayout.CENTER));
pnlTop.add(getLblSId());
pnlTop.add(getTxtSId());
pnlTop.add(getLblSName());
pnlTop.add(getTxtSName());
pnlTop.add(getLblSScore());
pnlTop.add(getTxtSScore());
pnlTop.add(getBtnAdd());
pnlTop.add(getBtnDelete());
pnlTop.add(getBtnUpdate());
return pnlTop;
}
return pnlTop;
}
public JLabel getLblSId(){
if(null == lblSId){
lblSId = new JLabel("学生学号:");
return lblSId;
}
return lblSId;
}
public JLabel getLblSName(){
if(null == lblSName){
lblSName = new JLabel("学生姓名:");
return lblSName;
}
return lblSName;
}
public JLabel getLblSScore(){
if(null == lblSScore){
lblSScore = new JLabel("学生成绩:");
return lblSScore;
}
return lblSScore;
}
public JTextField getTxtSId(){
if(null == txtSId){
txtSId = new JTextField(10);
return txtSId;
}
return txtSId;
}
public JTextField getTxtSName(){
if(null == txtSName){
txtSName = new JTextField(10);
return txtSName;
}
return txtSName;
}
public JTextField getTxtSScore(){
if(null == txtSScore){
txtSScore = new JTextField(10);
return txtSScore;
}
return txtSScore;
}
public JButton getBtnAdd(){
if(null == btnAdd){
btnAdd = new JButton("添加");
btnAdd.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
addStudent();
}
}
);
return btnAdd;
}
return btnAdd;
}
public JButton getBtnDelete(){
if(null == btnDelete){
btnDelete = new JButton("删除");
btnDelete.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
deleteStudent();
}
}
);
return btnDelete;
}
return btnDelete;
}
public JButton getBtnUpdate(){
if(null == btnUpdate){
btnUpdate = new JButton("更新");
btnUpdate.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
updateStudent();
}
}
);
return btnUpdate;
}
return btnUpdate;
}
public void addStudent(){
Student s = new Student();
s.setSId(new Integer(getTxtSId().getText()));
s.setSName(getTxtSName().getText());
s.setSScore(new Integer(getTxtSScore().getText()));
getTmdStudent().addSData(getTblStudent().getSelectedRow(),s);
}
public void updateStudent(){
Student s = getTmdStudent().getSData(getTblStudent().getSelectedRow());
if(s != null){
s.setSId(new Integer(getTxtSId().getText()));
s.setSName(getTxtSName().getText());
s.setSScore(new Integer(getTxtSScore().getText()));
getTmdStudent().updateSData(getTblStudent().getSelectedRow(),s);
}
}
public void deleteStudent(){
getTmdStudent().deleteSData(getTblStudent().getSelectedRow());
}
public void initData(){
lstStudent = new LinkedList();
}
public TestFrame(){
initData();
Container c= this.getContentPane();
c.setLayout(new BorderLayout());
c.add(getPnlTop(),BorderLayout.NORTH);
c.add(getPanTable(),BorderLayout.CENTER);
this.setSize(new Dimension(800,600));
this.setVisible(true);
}
public static void main(String[] args){
new TestFrame();
}
}