8-2:TableModel

8-2:TableModel

TableModel类本身是一个interface,在这个interface里面定义了若干的方法:包括了存取表格字段(cell)的内容、计算表格的列数等等 的基本存取操作,让设计者可以简单地利用TableModel来实作他所想要的表格。TableModel界面是放在javax.swing.table package中,这 个package定义了许多JTable会用到的各种Model,读者可利用java api文件找到这个package,并由此package找到各类或界面所定义的方法 。

TableModel方法:
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

8-3:AbstractTableModel:

java提供的AbstractTableModel是一个抽象类,这个类帮我们实现大部份的TableModel方法,除了getRowCount(),getColumnCount(), getValueAt()这三个方法外.因此我们的主要任务就是去实现这三个方法.利用这个抽象类就可以设计出不同格式的表格.我们来看看它所 提供的方法:

AbstractTableModel方法:
  • void addTableModelListener(TableModelListener l):使表格具有处理TableModelEvent的能力.当表格的Table Model有所变化时,会发 出TableModelEvent事件信息.
  • int findColumn(String columnName):寻找在行名称中是否含有columnName这个项目.若有,则返回其所在行的位置;反之则返回-1表示 未找到. void fireTableCellUpdated(int row, int column):通知所有的Listener在这个表格中的(row,column)字段的内容已经改变了.
  • void fireTableChanged(TableModelEvent e):将所收的事件通知传送给所有在这个table model中注册过的TableModelListeners.
  • void fireTableDataChanged():通知所有的listener在这个表格中列的内容已经改变了.列的数目可能已经改变了,因此JTable可能需要 重新显示此表格的结构.
  • void fireTableRowsDeleted(int firstRow, int lastRow):通知所有的listener在这个表格中第firstrow行至lastrow列已经被删除了.
  • void fireTableRowsUpdated(int firstRow, int lastRow) :通知所有的listener在这个表格中第firstrow行至lastrow列已经被修改了.
  • void fireTableRowsInserted(int firstRow, int lastRow):通知所有的listener在这个表格中第firstrow行至lastrow列已经被加入了 .
  • void fireTableStructureChanged():通知所有的listener在这个表格的结构已经改变了.行的数目,名称以及数据类型都可能已经改变了 .
  • Class getColumnClass(int columnIndex):返回字段数据类型的类名称.
  • String getColumnName(int column):若没有设置列标题则返回默认值,依次为A,B,C,...Z,AA,AB,..;若无此column,则返回一个空的String .
  • Public EventListener[] getListeners(Class listenerType):返回所有在这个table model所建立的listener中符合listenerType的 listener,并以数组形式返回.
  • boolean isCellEditable(int rowIndex, int columnIndex) :返回所有在这个table model所建立的listener中符合listenerType形式的 listener,并以数组形式返回.
  • void removeTableModelListener(TableModelListener l):从TableModelListener中移除一个listener.
  • void setValueAt(Object aValue, int rowIndex, int columnIndex) :设置某个cell(rowIndex,columnIndex)的值.

若你仔细比较TableModel所定义的方法与上述AbstractTableModel所提供的方法,你可以发现,AbstractTableModel抽象类并没有实现 getRowCount(),getColumnCount(),getValueAt()这三个方法,这也就是为什么我们要去实现这三个方法的原因.下面我们来看如何使用 AbstractTableModel来实作出自己想要的表格模式.

范例:TableModel1.java
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类型一律靠左显示.

TableModel2.java
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();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 AbstractTableModel 构建Table 在表格中添加JButton按钮,之前在网上找了2天没有找到好用的程序,最终终于找到一个好用的例子。 不要使,我退你们分。。 sing the Swing JTable class can quickly become a sticky business when you want to customize it to your specific needs. First you must become familiar with how the JTable class is organized. Individual cells are rendered by TableCellRenderer implementations. The table contents are represented by an implementation of the TableModel interface. By default, JTable uses DefaultTableCellRenderer to draw its cells. DefaultTableCellRenderer recognizes a few primitive types, rendering them as strings, and can even display Boolean types as checkboxes. But it defaults to displaying the value returned by toString() for types it does not specifically handle. You have to provide your own TableCellRenderer implementation if you want to display buttons in a JTable. The TableCellRenderer interface contains only one method, getTableCellRendererComponent(...), which returns a java.awt.Component that knows how to draw the contents of a specific cell. Usually, getTableCellRendererComponent() will return the same component for every cell of a column, to avoid the unnecessary use of extra memory. But when the contents of a cell is itself a component, it is all right to return that component as the renderer. Therefore, the first step towards having JButtons display correctly in a JTable is to create a TableCellRenderer implementation that returns the JButton contained in the cell being rendered. In the accompanying code listing, JTableButtonRenderer demonstrates how to do this. Even after creating a custom TableCellRenderer, you're still not done. The TableModel associated with a given JTable does not only keep track of the contents of each cell, but it also keeps track of the class of data stored in each column. DefaultTableModel is designed to work with DefaultTableCellRenderer and will return java.lang.String.class for columns containing data types that it does not specifically handle. The exact method that does this is getColumnClass(int column). Your second step is to create a TableModel implementation that returns JButton.class for cells that contain JButtons. JTableButtonModel shows one way to do this. It just returns the result of getClass() for each piece of cell data. At this point, you're almost done, but not quite. What's the use of putting a JButton in a JTable if you can't press the darn thing? By default, JTable will not forward mouse events to components contained in its cells. If you want to be able to press the buttons you add to JTable, you have to create your own MouseListener that forwards events to the JButton cells. JTableButtonMouseListener demonstrates how you could do this.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值