TableModel类本身是一个interface,在这个interface里面定义了若干的方法:包括了存取表格字段(cell)的内容、计算表格的列数等等 的基本存取操作,让设计者可以简单地利用TableModel来实作他所想要的表格。TableModel界面是放在javax.swing.table package中,这 个package定义了许多JTable会用到的各种Model,读者可利用java api文件找到这个package,并由此package找到各类或界面所定义的方法 。
void addTableModelListener(TableModelListener l):使表格具有处理TableModelEvent的能力。当表格的Table Model有所 变化时,会发出TableModel Event事件信息. Class getColumnClass(int columnIndex):返回字段数据类型的类名称. int getColumnCount():返回字段(行)数量. String getColumnName(int columnIndex):返回字段名称. int getRowCount():返回数据列数量. Object getValueAt(int rowIndex,int columnIndex):返回数据某个cell中的值. boolean isCellEditable(int rowIndex,int columnIndex):返回cell是否可编辑,true的话为可编辑. void removeTableModelListener(TableModelListener l):从TableModelListener中移除一个listener. void setValueAt(Object aValue,int rowIndex,int columnIndex):设置某个cell(rowIndex,columnIndex)的值;
由于TableModel本身是一个Interface,因此若要直接实现此界面来建立表格并不是件轻松的事.幸好java提供了两个类分别实现了这个 界面,一个是AbstractTableModel抽象类,一个是DefaultTableModel实体类.前者实现了大部份的TableModel方法,让用户可以很有弹性地构 造自己的表格模式;后者继承前者类,是java默认的表格模式.这三者的关系如下所示:
TableModel---implements--->AbstractTableModel-----extends--->DefaultTableModel
java提供的AbstractTableModel是一个抽象类,这个类帮我们实现大部份的TableModel方法,除了getRowCount(),getColumnCount(), getValueAt()这三个方法外.因此我们的主要任务就是去实现这三个方法.利用这个抽象类就可以设计出不同格式的表格.我们来看看它所 提供的方法:
若你仔细比较TableModel所定义的方法与上述AbstractTableModel所提供的方法,你可以发现,AbstractTableModel抽象类并没有实现 getRowCount(),getColumnCount(),getValueAt()这三个方法,这也就是为什么我们要去实现这三个方法的原因.下面我们来看如何使用 AbstractTableModel来实作出自己想要的表格模式.
import javax.swing.table.AbstractTableModel; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TableModel1 { public TableModel1() { JFrame f = new JFrame(); MyTable mt = new MyTable(); JTable t = new JTable(mt); t.setPreferredScrollableViewportSize(new Dimension(550, 30)); JScrollPane s = new JScrollPane(t); f.getContentPane().add(s, BorderLayout.CENTER); f.setTitle("JTable1"); f.pack(); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public static void main(String args[]) { new TableModel1(); } } class MyTable extends AbstractTableModel { Object[][] p = { { "阿呆", new Integer(66), new Integer(32), new Integer(98), new Boolean(false), new Boolean(false) }, { "阿瓜", new Integer(85), new Integer(69), new Integer(154), new Boolean(true), new Boolean(false) }, }; String[] n = { "姓名", "语文", "数学", "总分", "及格", "作弊" }; public int getColumnCount() { return n.length; } public int getRowCount() { return p.length; } public String getColumnName(int col) { return n[col]; } public Object getValueAt(int row, int col) { return p[row][col]; } public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } }
上例中表格内的数据类型不论是String,int或是Boolean类型,都均以string的类型显示.例如在及格的字段中,原本的数据是以Boolean 类型来表示,但显示在JTable上时便转换成字符串形式,若想要使表格能显示出不同的数据类型,我们要在MyTable中Override写getColumnCl ass()方法,这个方法可以让我们分辨出表格中每一行的数据类型,并将此类型作适当的显示:
public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); }
这样"作弊"会以Check Box显示,数据类型一律靠右显示,String类型一律靠左显示.
import javax.swing.table.AbstractTableModel; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TableModel2 implements ActionListener { JTable t = null; public TableModel2() { JFrame f = new JFrame("DataModel"); JButton b1 = new JButton("数学老师"); b1.addActionListener(this); JButton b2 = new JButton("学生阿呆"); b2.addActionListener(this); JPanel panel = new JPanel(); panel.add(b1); panel.add(b2); t = new JTable(new MyTable(1)); t.setPreferredScrollableViewportSize(new Dimension(550, 30)); JScrollPane s = new JScrollPane(t); f.getContentPane().add(panel, BorderLayout.NORTH); f.getContentPane().add(s, BorderLayout.CENTER); f.pack(); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("学生阿呆")) t.setModel(new MyTable(1)); if (e.getActionCommand().equals("数学老师")) t.setModel(new MyTable(2)); t.revalidate(); } public static void main(String args[]) { new TableModel2(); } } class MyTable extends AbstractTableModel { Object[][] p1 = { { "阿呆", "1234", new Integer(66), new Integer(50), new Integer(116), new Boolean(false), new Boolean(false) } }; String[] n1 = { "姓名", "学号", "语文", "数学", "总分", "及格", "作弊" }; Object[][] p2 = { { "阿呆", "1234", new Integer(50), new Boolean(false), new Boolean(false), "01234" }, { "阿瓜", "1235", new Integer(75), new Boolean(true), new Boolean(false), "05678" } }; String[] n2 = { "姓名", "学号", "数学", "及格", "作弊", "电话" }; int model = 1; public MyTable(int i) { model = i; } public int getColumnCount() { if (model == 1) return n1.length; else return n2.length; } public int getRowCount() { if (model == 1) return p1.length; else return p2.length; } public String getColumnName(int col) { if (model == 1) return n1[col]; else return n2[col]; } public Object getValueAt(int row, int col) { if (model == 1) return p1[row][col]; else return p2[row][col]; } public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } }