关于JTable的使用

JTable是个JavaSwing中的表格控件,可以用来显示数据和编辑数据。这里讲一下我的使用心得。

JavaSwing讲究MVC理念,而这个JTable也可以说是个迷你的MVC模型。JTable只是个显示数据的表格,而它的数据其实是在TableModel上的。每一个Jtable都会有自己的TableModel。可以这样想,你实现好了tableModel的方法,就可以自动生成表格。

有两种方法设置JTable的model:

//这个TableDataModel是实现了TableModel的类
TableDataModel tableModel = new TableDataModel();

JTable jTable = new JTable(tableModel);//1
jTable.setModel(tableMoedl);

当然,我们一般不会自己去实现这个接口,Java提供了两个实现了这个接口的类:

AbstractTableModelDefaultTableModel 也就是说我们在在写自己的TableModel的时候只要extends他们就行了。

这里我们主要看看AbstractTableModel

这个类基本实现了TableModel接口的方法,但有几个我们还是一定要重写的:

public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);

这三个方法,大概就是用来生成表格的,前两个确定表格的行与列数。第三个是确定每个单元格格的值。

然后还有几个有用的方法:

isCellEditable(int rowIndex, int columnIndex)---------这个方法是让某个单元格可以编辑

public String getColumnName(int column)---------告诉表格列表名

setValueAt(Object aValue, int rowIndex, int columnIndex)------------如果你的表格是可以编辑的,那么一定要实现这个方法。它是什么效果呢?它可以在数据发生改变的时候重新设置该单元格的值。如果你不重写这个方法,当你改一个单元格的值,然后回车,它又会变回去。而且你改完后,获取到的值也是原来的。     因为这个JTable的数据都是放在TableModel中的,所以,要真正地改表格的值,就要改model的数据。        重写了这个方法后,编辑完后单元格后,就不会再变回去了。

现在来看一个例子的代码

package com.wangshen.www.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

import com.wangshen.www.dao.CheckDao;

/**
 * 这个类是表格的数据模型,用来实现表格的数据展示和数据管理
 * @author 85060
 *
 */

//一开始我特么rowData是个二维的vector,然年不知道为什么怎么重写那个setValueAt方法都做不到直接在表格上编辑,然后就换成了rowData里面装的每一行是字符串数组的形式
public class TableDataModel extends AbstractTableModel {
    Vector<String> columnData = new Vector<String>();//保存列名称
    Vector rowData = null;
    
    public TableDataModel() {
        CheckDao checkDao = new CheckDao();
        
        columnData.add("id");
        columnData.add("书本名称");
        columnData.add("书本价格");
        columnData.add("收入时间");
        columnData.add("是否借出(1代表已借出)");
        rowData = checkDao.getRowData();
    }
    
    
    @Override//必须要重写实现的
    public int getColumnCount() {
    // TODO Auto-generated method stub
        return columnData.size();
    }
    
    @Override//必须要重写实现的
    public int getRowCount() {
    // TODO Auto-generated method stub    
        return rowData.size();
    }
    
    @Override//必须要重写实现的
    public Object getValueAt(int row, int column) {
    // TODO Auto-generated method stub
        /*
        Vector temp=((Vector)rowData.get(row));
        return temp.get(column);
        */
        String LineTemp[] = (String[])rowData.get(row);
        return LineTemp[column];
    }
    
    @Override
    public String getColumnName(int column) {
    // TODO Auto-generated method stub
        return (String)this.columnData.get(column);
    }
    
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        // TODO Auto-generated method stub
         if(columnIndex>0){  
             return true;  
         }  
         else{  
             return false;  
         }  
    }
    
     @Override
     public void setValueAt(Object aValue, int rowIndex, int columnIndex)
     {

        /*
         Vector temp = (Vector)rowData.get(rowIndex);
        switch(rowIndex) {
            case 1:
                //temp.setElementAt((String)aValue, 1);
                temp.set(1,(String)aValue);
                break;
            case 2:
                temp.setElementAt((float)aValue, 2);
                break;
            case 3:
                temp.setElementAt((String)aValue, 3);
                break;
            case 4:
                temp.setElementAt((Integer)aValue, 4);
                break;
        }
        */
        // 当单元格的数据发生改变的时候掉用该函数重设单元格的数据
        // 我们想一下,数据是放在TableData 中的,说白了修改数据就是修改的
        // TableData中的数据,所以我们仅仅在此处将TableData的对应数据修改即可
        ((String[])this.rowData.get(rowIndex))[columnIndex]=(String)aValue;
        super.setValueAt(aValue, rowIndex, columnIndex);
        //
        // 其实这里super的方法是调用了fireTableCellUpdated()只对应更新了
        // 对应单元格的数据
        // fireTableCellUpdated(rowIndex, columnIndex);
    }

}

(补一下,这个Vector其实就是个列表一样的东西,实现了List,和ArrayList差不多,但是个动态数组)
然后来看看Dao层中row数据的获取

package com.wangshen.www.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import com.wangshen.www.util.DbUtil;

/**
 * 这个类是获取整个图书表的一个resultset
 * @author 85060
 *
 */
public class CheckDao {
    DbUtil dbUtil = new DbUtil();
    
    public Vector getRowData() {//返回一个Vector,就是一个表格的row信息
        Connection con = dbUtil.getCon();//获取数据库连接
        String sql = "SELECT * FROM t_books";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Vector rowData = new Vector();//用来保存数据库中的行结果
        
        try {
            
            
            
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while(rs.next()) {
                //Vector hang=new Vector();
                String[] temp = new String[50];
                int i = 0;
                /*
                hang.add(rs.getInt("id"));
                hang.add(rs.getString("bookName"));
                hang.add(rs.getFloat("price"));
                hang.add(rs.getString("time"));
                hang.add(rs.getInt("status"));
                rowData.add(hang);
                */
                temp[i++] = rs.getInt("id")+"";
                temp[i++] = rs.getString("bookName")+"";
                temp[i++] = rs.getFloat("price")+"";
                temp[i++] = rs.getString("time")+"";
                temp[i++] = rs.getInt("status")+"";
                rowData.add(temp);
            }
            
            
            
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("查找数据库行信息的数据库操作出错");
        } finally {
            dbUtil.close(pstmt, con);
        }
        return rowData;
    }
}

每个Vector变量(row的数据)里面是n个一维的字符串数组,代表着表格中的n行数据。



再来看JTable的建立
JPanel panelTable = new JPanel();//用来装表格的panel

TableModel tableModel = new TableDataModel();//table模型,这就话同时初始化表格

JTable tableBooks = new JTable();//不要这里加model好,以后同步不方便……

//官方api建议我们这样做,就是用个有滚轮的Panel来装这个表格,就当做表格的一部分吧
JScrollPane scrollPane = new JScrollPane(tableBooks);

scrollPane.setViewportView(tableBooks);//其实好像和那个构造方法的效果一样……但有
些例子加了就加吧……

panelTable.add(scrollPane);

tableBooks.setFillsViewportHeight(true);//表格充满容器,不加这一句表格不会充满容器panelTable。(似乎scrollPane是跟着table一起充满panelTable)

然后关于其他操作,只要抓住表格显示的数据是TableModel里的数据这点就行了。


补充: 之前实现刷新,是重新搞个新的TableModel的实现对象,然后再
table.setModel
来实现表格的更新。 后面知道,你如果用的是Vector或者List,只要你重写好了TableModel里面需要重写的方法,你只需要在改变你的model里面的类变量,比如行数据rowData后,再调用
table.updateUi()
就可以实现表格的更新,效果还挺好!!

原文地址:https://www.cnblogs.com/wangshen31/p/7861307.html