Swing 高级组件


六、JTable 表格组件

  • swing 程序中表格组件,由 JTable 类实现。

1、基本概念

  • JTable 类表示表格组件,使用该类的构造方法可以创建相应的表格,该类有多种构造方法,常用构造方法如下:
    1)JTable():构造默认的表格,使用默认的数据类型、默认的列模型和默认的选择模型进行初始化。
    2)JTable(Object[][] rowData,Object[] columnNames):构造一个 JTable 类显示二维数组 rowData 中的值,其列名称为 columnNames。
    3)JTable(TableModel dm):构造一个 JTable,使用数据模型 dm、默认的列模型和默认的选择模型对其初始化。

2、表格的常用操作方法

  • JTable 提供了许多操作表格的方法,其中常用方法如下表:

方法

说明

setRowHeight(int rowHeight)

设置表格的行高,默认 16 像素

setRowSelectionAllowed(boolean sa)

设置是否允许选中表格行,默认允许选中;false 表示不允许

setSelectionMode(int sm)

设置表格的选择模式

setSelectionBackground(Color bc)

设置表格选中行的背景色

setSelectionForeground(Color fc)

设置表格选中行的前景色(通常为文字的颜色)

setAutoResizeMode(int mode)

设置表格的自动调整模式

getRowCount()

获得表格拥有的行数,返回值 int 型

getColumnCount()

获得表格的列数,返回 int 值

getColumnName(int column)

获得位于指定索引位置的列的名称,返回值为 String 型

setRowSelectionInterval(int from, int to)

选中行索引从 from 到 to 的所有行(包括 from 和 to 所在的行)

addRowSelectionInterval(int from, int to)

将索引从 from 到 to 的所有行追加为表格的选中行

isRowSelected(int row)

查看行索引为 row 的行是否被选中

selectAll()

选中表格中的所有行

clearSelection()

取消所有选中行的选中状态

getSelectedRowCount()

获得表格中选中行的数量,返回 int 值,若没有选中行则返回 -1

getSelectedRow()

获得被选中行中最小的索引值,如果没有选中行则返回 -1

getSelectedRows()

获得所有被选中行的索引值,返回 int 型数组

  • 简单示例:
package 高级Swing组件;

// !/usr/bin/env jdk1.8
// encoding:utf-8
//@software:IntelliJ IDEA
//@pack:高级Swing组件
//@user:彭友聪
//@date:2019/08/09
//@time:上午 8:09
//@project:IDEA_JAVA
//@file:JTableTest.java
//Author:御承扬
//email:2923616405@qq.com


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JTableTest extends JFrame {
    private JTable table;

    private JTableTest() {
        super();
        setTitle( "操作表格示例" );
        setBounds( 100, 100, 500, 375 );
        setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
        final JScrollPane scrollPane = new JScrollPane();
        getContentPane().add( scrollPane, BorderLayout.CENTER );
        String[] columnNames = {"A", "B", "C", "D", "E", "F", "G"};     // 定义表格列
        String[][] tableValues = new String[20][columnNames.length];    // 定义数组,用于存储表格单元数据
        int len = columnNames.length;
        // 初始化表格数据
        for (int row = 0; row < 20; row++) {
            for (int column = 0; column < len; column++) {
                tableValues[row][column] = columnNames[column] + row;
            }
        }
        table = new JTable( tableValues, columnNames );
        table.setRowSelectionInterval( 1, 3 );   // 设置选中行
        table.addRowSelectionInterval( 5, 5 );   // 添加选中行
        table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
        scrollPane.setViewportView( table );
        JPanel buttonPanel = new JPanel();
        getContentPane().add( buttonPanel, BorderLayout.SOUTH );
        JButton selectedAllButton = new JButton( "全部选择" );
        selectedAllButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                table.selectAll();  // 选中所有行
            }
        } );
        buttonPanel.add( selectedAllButton );
        JButton clearSelectionButton = new JButton( "取消选择" );
        clearSelectionButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                table.clearSelection(); // 取消选中行
            }
        } );
        buttonPanel.add( clearSelectionButton );
        // 输出表格的行数、列数
        System.out.println( "表格共有 " + table.getRowCount() + " 行 " + table.getColumnCount() );
        System.out.println( "第 3 行的选择状态为:" + table.isRowSelected( 2 ) );
        System.out.println( "被选中的第一行的索引是:" + table.getSelectedRow() );
        System.out.println( "第 2 列的名称是:" + table.getColumnName( 1 ) );
        System.out.println( "第 2 行 2 列的值为:" + table.getValueAt( 1, 1 ) );
    }

    public static void main(String[] args) {
        JTableTest frame = new JTableTest();
        frame.setVisible( true );
    }
}
  • 运行如下图:

Java swing表格界面 java swing表格组件_数据

  • 控制台输出:
表格共有 20 行 7
第 3 行的选择状态为:true
被选中的第一行的索引是:1
第 2 列的名称是:B
第 2 行 2 列的值为:B1

3、使用表格模型创建表格

  • JTable 类提供了一个使用 TableModel 创建表格的构造方法,其中 TableModel 是一个接口。
  • TableModel 接口定义了一个表格模型,AbstractTableModel 抽象类实现了 TableModel 接口的大部分方法,只有以下三个方法没有实现:
    1)public int getRowCount()
    2)public int getColumnCount()
    3)public Object getValueAt(int rowIndex, int columnIndex)
  • 通过继承 AbstractTableModel 类并实现以上三个抽象方法,可以创建自定义表格模型。
  • Swing 提供的表格模型类 DefaultTableModel 继承 AbstarctTableModel 类并实现了以上三个抽象方法,该类的常用构造方法如下:

构造方法

说明

DefaultTableModel()

创建一个 0 行 0 列的表格模型

DefaultTableModel(int rowCount, int columnCount)

创建指定行数列数的表格模型

DefaultTableModel(Object[][] data, Object[] columnNames)

按照数组中指定的数据和列名创建一个表格模型

DefaultTableModel(Vector data, Vector columnNames)

按照数组中指定的数据和列名创建一个表格模型

  • 表格模型创建后,使用 JTable 类的 JTable(TableModel dm) 构造方法创建表格,如下示例:
DefaultTableModel tableModel = new DefaultTableModel();
JTable table = new JTable();

4、维护表格模型

  • 维护表格模型是指对表格的数据进行增删改查等操作,以及表格模型事件。

4.1、向表格中添加、修改、删除行数据

  • 向表格中添加新数据时有两种情况:尾部添加和指定位置添加(通常不在尾部)。
  • 添加到尾部,可用方法 addRow() 完成,该方法有以下两个重载方法:
    1)addRow(Object[] rowData):将由数组封装的数据添加到表格尾部。
    2)addRow(Vector rowData):将由 Vector 封装的数据添加到表格尾部。
  • 添加到指定位置,可用 inserRow() 来完成,同样也有下面两种重载方法:
    1)insertRow(int row, Object[] rowData):将由数组封装的数据添加到指定索引位置。
    2) insertRow(int row, Vector rowData):将由 Vector 封装的数据添加到指定索引位置。
  • 修改表格数据可用 setValueAt(Object Value, int row, int column) 方法;而删除某一行数据可以用 removeRow(int row) 方法。

4.2、表格模型事件

  • 对表格进行操作时,将会产生表格模型事件;TableModelEvent 类负责捕获表格模型事件,可以通过为表格组件添加 TableModelListener 接口的监听器类处理相应表格模型事件。
  • TableModelListener 接口只有一个抽象方法,TableModelListener 接口定义如下:
public interface TableModelListener extends java.util.EventListener {
	public void tableChanged(TableModelEvent e);
}
  • TableEvent 类常用方法如下表:

方法

功能简介

getType()

获得此次事件的类型

getFirstRow()

获得触发此次事件的表格行的最小索引值

getLastRow()

获得触发此次事件的表格行的最大索引值

getColumn()

如果事件类型为 UPDATE,获得触发此次事件的表格列的索引值,否则返回-1

  • getType() 返回 int 型值,通过 TableModelEvent 类的静态常量可判断此事件的类型:
    INSERT:插入行触发的事件。
    UPDATE:修改行触发的事件。
    DELETE:删除行触发的事件。

4.3、示例

  • 示例代码如下:
package 高级Swing组件;

// !/usr/bin/env jdk1.8
// encoding:utf-8
//@software:IntelliJ IDEA
//@pack:高级Swing组件
//@user:彭友聪
//@date:2019/08/09
//@time:上午 10:11
//@project:IDEA_JAVA
//@file:TableModelTest.java
//Author:御承扬
//email:2923616405@qq.com


import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TableModelTest extends JFrame {
    private DefaultTableModel tableModel;   // 定义表格模型对象
    private JTable table;   // 表格对象
    private JTextField aTextField, bTextField;  // 面板下面的两个输入框
    private JButton addButton, delButton, updButton;    // 增删改三个按钮

    private TableModelTest() {
        super();
        setTitle( "维护表格模型示例" );
        setBounds( 100, 100, 500, 375 );
        setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
        String[] columnNames = {"A", "B"};
        String[][] tableValues = {{"A1", "B1"}, {"A2", "B2"}, {"A3", "B3"}};

        tableModel = new DefaultTableModel( tableValues, columnNames );
        table = new JTable( tableModel );
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane, BorderLayout.CENTER );
        buttonInit();   // 按钮初始化
        addListener();  // 给组件添加监听事件
    }

    private void buttonInit() {
        final JPanel panel = new JPanel();
        getContentPane().add( panel, BorderLayout.SOUTH );
        panel.add( new JLabel( "A: " ) );
        aTextField = new JTextField( "A4", 10 );
        panel.add( aTextField );
        panel.add( new JLabel( "B: " ) );
        bTextField = new JTextField( "B4", 10 );
        panel.add( bTextField );
        addButton = new JButton( "添加" );
        updButton = new JButton( "修改" );
        delButton = new JButton( "删除" );
        panel.add( addButton );
        panel.add( updButton );
        panel.add( delButton );
    }

    private void addListener() {
        // 为表格模型添加事件监听器
        tableModel.addTableModelListener( new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                int type = e.getType(); // 获取事件类型
                int row = e.getFirstRow() + 1;
                int column = e.getColumn() + 1;
                if (type == TableModelEvent.INSERT) {
                    System.out.println( "此次事件由 插入 触发" );
                    System.out.println( "此次插入的是第 " + row + " 行,第 " + column + " 列" );
                } else if (type == TableModelEvent.UPDATE) {
                    System.out.println( "此次事件由 修改 触发" );
                    System.out.println( "此次修改的是第 " + row + " 行,第 " + column + " 列" );
                } else if (type == TableModelEvent.DELETE) {
                    System.out.println( "此次事件由 删除 触发" );
                    System.out.println( "此次删除的是第 " + row + " 行,第 " + column + " 列" );
                } else {
                    System.out.println( "此次事件由 其他原因 触发" );
                }
            }
        } );
        // 添加按钮事件
        addButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String[] rowValues = {aTextField.getText(), bTextField.getText() };
                // 创建表格行数据
                tableModel.addRow( rowValues );
                int rowCount = table.getRowCount() + 1;
                aTextField.setText( "A " + rowCount );
                bTextField.setText( "B " + rowCount );
            }
        } );
        updButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow != -1) {
                    tableModel.setValueAt( aTextField.getText(), selectedRow, 0 );
                    tableModel.setValueAt( bTextField.getText(), selectedRow, 1 );
                }
            }
        } );
        delButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int selectedRow = table.getSelectedRow();
                if (selectedRow != -1) {
                    tableModel.removeRow( selectedRow );
                }
            }
        } );
    }

    public static void main(String[] args) {
        TableModelTest frame = new TableModelTest();
        frame.setVisible( true );
    }
}
  • 运行如下图:

Java swing表格界面 java swing表格组件_java_02

Java swing表格界面 java swing表格组件_System_03

此次事件由 插入 触发
此次插入的是第 4 行,第 0 列
此次事件由 修改 触发
此次修改的是第 1 行,第 1 列
此次事件由 修改 触发
此次修改的是第 1 行,第 2 列
此次事件由 删除 触发
此次删除的是第 3 行,第 0 列
此次事件由 插入 触发
此次插入的是第 4 行,第 0 列