表格组件提供了以 行、列 的形式显示数据的视图。 在程序开发中是一个非常重要的组件。 尤其在需要将一堆数据有条理地展现给用户时,表格设计更能显示出它的重要性
在Swing中可以通过JTable组件非常轻松地构造出所需要的表格,并且也提供了一些方法来管理这些表格的内容。
JTable类的常用方法如下所示:
范例:建立表格
package org.forfan06.jtabledemo;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class JTableDemo01{
public static void main(String args[]){
JFrame jframe = new JFrame("Welcome page");
String[] titles = {"姓名", "年龄", "性别", "数学成绩", "英语成绩", "总分", "是否及格"}; //定义数组表示表格的标题
Object[][] userInfo = {{"forfan06", 29, "Male", 72, 59, 131, false}, {"Linda", 27, "Female", 89, 93, 182, true}}; //定义二维对象数组
JTable table = new JTable(userInfo, titles); //实例化JTable组件对象
JScrollPane scr = new JScrollPane(table); //加入滚动条
jframe.add(scr);
jframe.setSize(370, 90);
jframe.setVisible(true);
jframe.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1);
}
});
}
}
上面程序,使用一个二维数组表示表格中的数据,表格中的数据按照标题栏设置的顺序进行排列,之后将表格加入到一个滚动框中,再将滚动框加入到面板中。
===============================================================================================================
JTable使用时要加入到JScrollPane中。
在使用JTable时,如果不把JTable加入到JScrollPane中,则表格的标题将无法显示!!!!!!!!!!
===============================================================================================================
使用JTable构建的表格相对比较单一,如果想制作一些操作界面更加友好的表格,例如,在表格上加入一些单选按钮或下拉列表框,则需要借助于TableModel接口了。
在TableModel接口中定义了许多与表格操作相关的方法,如下所示:
但是,在实际的开发中很少直接实现以上的接口,而都是使用其接口的子类AbstractTableModel和DefaultTableModel。 但是不管使用哪个子类实现,首先都必须了解TableColumnModel接口。
TableColumnModel接口定义了许多与表格的行、列有关的方法。例如,增加行(列)、删除行(列),设置和取得表格元素的信息等操作。。。通常用户不会直接实现TableColumModel接口,而是直接通过JTable中的getColumnModel()方法取得TableColumnModel的实例!!!!!
TableColumnModel接口中定义的方法如下所示:
在TableColumnModel接口的操作中,增加或者删除都是以TableColumn类的形式出现的。 TableColumn类表示每一列的数据!!!!!!!
下面就先使用AbstractTableModel类建立一个表格。建立一个DefaultTable类直接集成AbstractTableModel类,然后覆写相应的抽象方法即可。
范例:使用AbstractTableModel构建表格
package org.forfan06.jtabledemo;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
class DefaultTable extends AbstractTableModel{
private String[] titles = {"姓名", "年龄", "性别", "数学成绩", "英语成绩", "总分", "是否及格"}; //定义数组表示表格的标题
private Object[][] userInfo = {{"forfan06", 29, "Male", 72, 59, 131, false}, {"Linda", 27, "Female", 89, 93, 182, true}}; //定义二维对象数组
public int getColumnCount(){
return this.titles.length;
}
public int getRowCount(){
return this.userInfo.length;
}
public Object getValueAt(int row, int column){
return this.userInfo[row][column];
}
//得到列的名字,如果不覆些此方法,则以后无法显示列的名称
public String getColumnName(int column){
return this.titles[column];
}
/*
*返回列的类型,如果不覆写此方法,则无法按格式显示数据,格式如下:
*1、 boolean类型,以CheckBox方式显示
*2、 数值类型: 以JLabel显示,文字向右排列
*/
public Class> getColumnClass(int column){
return this.getValueAt(0, column).getClass(); //取得指定列的类型
}
//如果不覆写此方法,则表格无法编辑
public boolean isCellEditable(int row, int column){
return true; //所有单元格均可编辑
}
public void setValueAt(Object newValue, int row, int column){
this.userInfo[row][column] = newValue;
}
}
class TableColumnModelDemo{
private JFrame jframe = new JFrame("Welcome page");
private JTable table = null; //声明JTable表格对象
private DefaultTable defaultTable = new DefaultTable();
private JComboBox sexList = new JComboBox(); //定义下拉列表框
public TableColumnModelDemo(){
this.table = new JTable(this.defaultTable); //实例化JTable对象
this.sexList.addItem("Male");
this.sexList.addItem("Femal");
//下面这条语句涉及到的类和接口
/*
*Class JTable
***public TableColumnModel getColumnModel();
*
*Interface TableColumnModel
*
*Class DefaultTableColumnModel implements TableColumnModel...
***public TableColumn getColumn(int columnIndex);
*
*Class TableColumn
***public void setCellEditor(TableCellEditor cellEditor);
*
*Interface TableCellEditor
***public interface TableCellEditor extends CelLEditor
*
*Class DefaultCellEditor extends AbstractCellEditor implements TableCellEditor, TreeCellEditor... Contstructors as below:
***public DefaultCellEditor(JComboBox comboBox);
***public DefaultCellEditor(JCheckBox checkBox);
***public DefaultCellEditor(JTextField textField);
*/
this.table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(this.sexList)); //将下拉列表选项加入到表格
JScrollPane scr = new JScrollPane(this.table);
JPanel toolBar = new JPanel();
this.jframe.add(toolBar, BorderLayout.NORTH);
this.jframe.add(scr, BorderLayout.CENTER);
this.jframe.setSize(370, 160);
this.jframe.setVisible(true);
this.jframe.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1);
}
});
}
}
public class JTableDemo02{
public static void main(String args[]){
new TableColumnModelDemo();
}
}
程序运行后,可以发现: 表格中的数据都是按照指定格式进行显示的;而且因为在DefaultTable类中覆写了isCellEditable()方法,所以表格的每一项都是可编辑的;对于性别的选项使用了一个下拉列表框的形式进行了显示;在“是否及格”列上,使用了一个CheckBox来代替了原有的true和false。
=================================================================================================
以下内容来之 http://www.cnblogs.com/renyuan/archive/2012/10/15/2724541.html
http://www.cnblogs.com/langtianya/archive/2012/09/04/2671173.html
http://mxdxm.iteye.com/blog/653023
http://blog.csdn.net/tsaid/article/details/7962798
Question:表格如何绘制它的单元格呢???? (编辑器和渲染器Editors、 Renderers的概念)
Answer: Swing的表格考虑性能的原因,其表格中每个单元格并不是一个组件。取而代之的是,一个single cell renderer(单一单元格绘制器)一般用来绘制所有包含同类型数据的单元格。你可以想象这个renderer是一个可配置的墨水打印,表格使用它将格式化的数据合适地印在每个单元格上。当用于开始标记一个单元格的数据时,cell editor接管这个单元格,控制单元格的编辑行为。
例如,TableDemo的 # of Years列中的每个单元格包含数字数据 --- 具体是一个Integer对象。默认情况下,对于数字列,渲染器使用单个JLabel实例在列上的单元格绘制恰当的居右的数字。如果用户开始编辑一个单元格,则默认的单元格编辑器使用一个居右的JTextField来控制单元格的编辑动作。
如果选择render处理某一列的单元格,表格首先会确定,对于该列,你是否已经指定了一个renderer。如果你未指定,那么table会调用table model的getColumnClass()方法,获得该列的单元格的数据的类型。接着,table会将该列的数据类型与一个数据类型列表对比, 该列表注册了多种cell renderers。 该表由table初始化,你可以向该表增加renderer。
通常,table会把下列类型放到列表中:
单元格编辑器使用类似的法则。
注意,如果让table自己创建它的model,它会把Object作为Object各列的类型。为了指定更明确列类型。 table model一定要定义适当的getColumnClass()方法。
记住,尽管render决定有多少单元格和列头被指定了它的 tool tip text(鼠标指在上面显示的提示文本), 但是render本身不处理事件。 如果你需要获得table内发生的事件,你使用的技术就是在下面分类的事件中做变化:
Situation How to Get Events
To detect events from a cell that is being edited... Use the cell editor(or register a listener on the cell editor)
To detect row/column/cell selections and deselections... Use a selection listener as described in Detecting User Selections.
To detect mouse event on a column header... Register the appropriate of mouse listener on the table's JTableHeader object.
To detect other events... Register the appropriate listener on the JTable object.
=================================================================================================
使用AbstractTableModel类可以方便地构建表格,而使用其子类DefaultTableModel则可以对表格进行动态的操作。 例如:增加行(列)、删除行(列)等。
在DefaultTableModel类中提供了以下的常用操作方法:
范例:动态操作表格
package org.forfan06.jtabledemo;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
class ChangeTable implements ActionListener{ //实现事件监听
private JFrame jframe = new JFrame("Dynamic edit Table");
private JTable table = null; //声明JTable对象
private DefaultTableModel tableModel = null; //声明DefaultTableModel对象
private String[] titles = {"姓名", "年龄", "性别", "数学成绩", "英语成绩", "总分", "是否及格"}; //定义数组表示表格的标题
private Object[][] userInfo = {{"forfan06", 29, "Male", 72, 59, 131, false}, {"Linda", 27, "Female", 89, 93, 182, true}}; //定义二维对象数组
private JButton addRowBtn = new JButton("增加行");
private JButton removeRowBtn = new JButton("删除行");
private JButton addColBtn = new JButton("增加列");
private JButton removeColBtn = new JButton("删除列");
public ChangeTable(){ //通过构造方法完成显示的功能
//实例化DefaultTableModel对象,显示内容
this.tableModel = new DefaultTableModel(this.userInfo, this.titles); //DefaultTableModel Constructor: DefaultTableMode(Object[][] data, Object[] columnName)
this.table = new JTable(this.tableModel); //根据TableModel显示内容
JScrollPane scr = new JScrollPane(this.table); //加入滚动条
JPanel toolBar = new JPanel();
toolBar.add(this.addRowBtn);
toolBar.add(this.removeRowBtn);
toolBar.add(addColBtn);
toolBar.add(this.removeColBtn);
this.jframe.add(toolBar, BorderLayout.NORTH);
this.jframe.add(scr, BorderLayout.CENTER);
this.jframe.setSize(370, 160);
this.jframe.setVisible(true);
this.addRowBtn.addActionListener(this);
this.removeRowBtn.addActionListener(this);
this.addColBtn.addActionListener(this);
this.removeColBtn.addActionListener(this);
this.jframe.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(1);
}
});
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == this.addColBtn){
this.tableModel.addColumn("新增列");
}
if(e.getSource() == this.addRowBtn){
this.tableModel.addRow(new Object[] {});
}
if(e.getSource() == this.removeColBtn){
int colCount = this.tableModel.getColumnCount(); //得到最后一列
if(colCount >= 0){ //判断是否还有列
//取得TableModel实例,以方便删除列
TableColumnModel columnMode = this.table.getColumnModel();
//取得删除列的对象,根据列的编号取得TableColumn对象
TableColumn tableColumn = columnMode.getColumn(colCount);
columnMode.removeColumn(tableColumn);
//修改表格的列数,如果不修改则在下次删除列时将出现数组越界异常
this.tableModel.setColumnCount(colCount);
}
}
if(e.getSource() == this.removeRowBtn){
int rowCount = this.tableModel.getRowCount() - 1; //得到最后一行
if(rowCount >= 0){ //判断是否还有行
this.tableModel.removeRow(rowCount);
this.tableModel.setRowCount(rowCount);
}
}
}
}
public class JTableDemo03{
public static void main(String args[]){
new ChangeTable();
}
}
在上面程序中,使用DefaultTableModel可以方便地实现增加行(列)、删除行(列)的各种操作。在删除行前先取得最后一行的编号,之后通过removeRow()方法根据行号删除掉指定行,但是在行删除之后一定要使用setRowCount()方法重新设置行数,这样在下面操作时就不会出现数据越界的异常信息。