类层次结构图:
java.lang.Object
--java.awt.Component
--java.awt.Container
--javax.swing.JComponent
--javax.swing.JTabel
在使用JTable以前,我们先看一下它的构造函数有哪些, 以及应该如何使用:
JTabel构造函数:
JTable():建立一个新的JTables,并使用系统默认的Model.
JTable(int numRows,int numColumns):建立一个具有numRows行,numColumns列的空表格,使用的是DefaultTableModel.
JTable(Object[][] rowData,Object[][] columnNames):建立一个显示二维数组数据的表格,且可以显示列的名称。
JTable(TableModel dm):建立一个JTable,有默认的字段模式以及选择模式,并设置数据模式。
JTable(TableModel dm,TableColumnModel cm):建立一个JTable,设置数据模式与字段模式,并有默认的选择模式。
JTable(TableModel dm,TableColumnModel cm,ListSelectionModel sm):建立一个JTable,设置数据模式、字段模式、与选择模式。
JTable(Vector rowData,Vector columnNames):建立一个以Vector为输入来源的数据表格,可显示行的名称。
简单的构造方式表格中每个单元(cell)中的数据类型将会被视为同一种,原来的数据类型声明为Boolean的数据会以String的形式出现而不是以检查框(Check Box)出现。为了因应这些种种复杂情况,简单的构造方式已不宜使用,Swing提供各种Model(如:TableModel、 TableColumnModel与ListSelectionModel)来解决上述的不便,以增加我们设计表格的弹性。TableModel类本身是一个interface,在这个interface里面定义了若干的方法:包括了存取表格字段(cell)的内容、计算表格 的列数等等的基本存取操作,让设计者可以简单地利用TableModel来实作他所想要的表格。
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
java提供的AbstractTableModel是一个抽象类,这个类帮我们实现大部份的TableModel方法,除了 getRowCount()、getColumnCount()、getValueAt()这三个方法外,因此我们的主要任务就是去实现这三个方法.利用 这个抽象类就可以设计出不同格式的表格。
下面看个简单的例子:
public class MyFrame {
JFrame frame = null;
JTable table = null;
JToolBar toolBar = null;
JComboBox box = null;
private Vector conferences = new Vector();
private Map conference_id = new HashMap();
public MyFrame() {
frame = new JFrame();
frame.setBounds(100,40,1000,750);
toolBar = new JToolBar();
//绘制边框
toolBar.setBorderPainted(true);
//如果 rollover 状态为 true,则仅当鼠标指针悬停在工具栏按钮上时,才绘制该工具栏按钮的边框。
toolBar.setRollover(true);
conferences.add("未选择任何会议");
box = new JComboBox(conferences);
Dimension d = box.getPreferredSize();
box.setMaximumSize(d);
toolBar.add(box);
// 添加分割线
JSeparator js1 = new JSeparator();
js1.setOrientation(SwingConstants.VERTICAL);
js1.setMaximumSize(new Dimension(10, 32767));
js1.setMinimumSize(new Dimension(0, 0));
js1.setPreferredSize(new Dimension(10, 0));
toolBar.add(js1);
addConference();
final JScrollPane scrollPane = new JScrollPane();
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
JButton query = new JButton("查询");
query.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
table = new JTable(new MyTableModel());
scrollPane.setViewportView(table);
}
});
toolBar.add(query);
JPanel panel = new JPanel();
panel.add(box);
panel.add(query);
frame.getContentPane().add(panel,BorderLayout.NORTH);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new MyFrame();
}
private void addConference() {
String sql = "select conference_ID,conference_name from cms_conference_summary";
Connection con = DBTools.getConnect();
Statement state = null;
ResultSet rs = null;
try {
state = con.createStatement();
rs = state.executeQuery(sql);
while (rs.next()) {
String title = rs.getString("conference_name");
int id = rs.getInt("conference_ID");
if (id == 1)
continue;
conferences.add(title);
conference_id.put(title, id);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "数据库连接错误!", "ERROR",
JOptionPane.INFORMATION_MESSAGE);
} finally {
DBTools.closeResult(rs);
DBTools.closeState(state);
DBTools.closeConn(con);
}
}
class MyTableModel extends AbstractTableModel{
private static final long serialVersionUID = 1L;
String[] name = {"序号","论文题目","作者","是否已下载"};
Vector> papers = new Vector>();
Vector temp1 = new Vector();
Vector temp2 = new Vector();
public MyTableModel() {
temp1.add(new Integer(1));
temp1.add("title");
temp1.add("author");
temp1.add(true);
temp2.add(new Integer(2));
temp2.add("title");
temp2.add("author");
temp2.add(false);
papers.add(temp1);
papers.add(temp2);
}
@Override
public int getColumnCount() {
// TODO Auto-generated method stub
return name.length;
}
@Override
public int getRowCount() {
// TODO Auto-generated method stub
return papers.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
return ((Vector)papers.elementAt(rowIndex)).elementAt(columnIndex);
}
@Override
public String getColumnName(int column) {
// TODO Auto-generated method stub
return name[column];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
}
这样boolean会以Check Box显示,数据类型一律靠右显示,String类型一律靠左显示。
凑,谁要是再找我写Swing我跟谁急,烦死了!!!