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 );
}
}
- 运行如下图:
- 控制台输出:
表格共有 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 );
}
}
- 运行如下图:
此次事件由 插入 触发
此次插入的是第 4 行,第 0 列
此次事件由 修改 触发
此次修改的是第 1 行,第 1 列
此次事件由 修改 触发
此次修改的是第 1 行,第 2 列
此次事件由 删除 触发
此次删除的是第 3 行,第 0 列
此次事件由 插入 触发
此次插入的是第 4 行,第 0 列