JTable控件

JTabel 是表格组件,可以把数据以二维表格的形式显示出来,并且支持用户对表格中的数据进行编辑。表格组件是最复杂的组件之一,它的表格模型功能非常强大、灵活而易于执行。

JTable 类实现表格,常用构造方法如下:

  • JTable():构造一个默认的 JTable,使用默认的数据模型、默认的列模型和默认的选择模型对其进行初始化。
  • JTable(int numRows,int numColumns):使用 DefaultTableModel 构造具有 numRows 行和 numColumns 列个空单元格的 JTable。
  • JTable(Object[][] rowData,Object[] columnNames):构造一个 JTable 来显示二 维数组 rowData 中的值,其列名称为 columnNames。

JTable 类的常用方法如下:

Swing 的表格功能强大,相关的接口、类较为丰富,本节只介绍 TableModel、TableCellRender、TableCellEditor 三个子类常用的方法。

  • TableModel :定义了若干的方法:包括了存取表格字段(cell)的内容、计算表格的列数等等的基本存取操作,让设计者可以简单地利用TableModel来实作他所想要的表格。
  • TableCellRender :表格单元格渲染器。
  • TableCellEditor :表格编辑器,使表格中的数据处于可编辑状态。

TableModel常用方法如下:

方法名及返回值类型 说明
getColumnCount() 返回列模型中的列数
getColumnN ame(int column) 返回出现在视图中 column 列位置处的列名称
getRowCount() 返回 JTable 中可以显示的行数(给定无限空间)
getRowSorter() 返回负责排序的对象
getSelectedColumn() 返回第一个选定列的索引,如果没有选定的列, 则返回 -1
getSelectedRow() 返回第一个选定行的索引,如果没有选定的行, 则返回 -1
getValueAt(int row,int column) 返回 row 和 column 位置的单元格值
isEditing() 如果正在编辑单元格,则返回 true
selectAll() 选择表中的所有行、列和单元格
setColumnSelectionInterval(int index0,int index1) 选择从 index0 到

index1之间(包含两端)的列
setRowSelectionInterval(int index0,int index1) | 选择从 index0 到 index1 之间(包含两端)的行
setTableHeader(JTableHeader tableHeader) | 将此 JTable 所使用的 tableHeader 设置为 newHeader
setUpdateSelectionOnSort(boolean update) | 指定排序后是否应该更新选择
setValueAt(Object a Value,int row,int column) | 设置表模型中 row 和 column 位置的单元格值

TableCellRender常用方法如下:

方法名及返回值类型 说明
getTableCellRendererComponent() 返回绘制在单元格上的控件

TableCellEditor常用方法如下:

方法名及返回值类型 说明
getTableCellEditorComponent 获取单元格的编辑器,可以自定义返回值
getCellEditorValue

编辑结束之后,Table会从这个接口获取编辑之后的值,然后通过TableModel.setValue接口设置给table

示例

继承 MyFrame 类,使用 JTable 类创建一个包含 6 列的学生成绩表,并向表格中填充几行学生信息,修改第2列单元格渲染风格,并且除表头外,表格内容支持编辑。具体实现代码如下:

package com.supermap.desktop.samplecode.swing.table;
import com.supermap.desktop.samplecode.MyFrame;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.util.ArrayList;

public class MyJTable extends MyFrame {
	private MyJTable() {
		JTable jTable = new JTable();
		ArrayList<Data> data = new ArrayList<>();
		data.add(new Data(0, "学生1", 20, 30, 40));
		data.add(new Data(1, "学生2", 90, 92, 94));
		data.add(new Data(2, "学生3", 80, 30, 20));
		data.add(new Data(3, "学生4", 90, 99, 30));
		jTable.setModel(new MyTableModel(data));
		// 这里我们只修改第2列的渲染器,让他返回我们自定义的效果
		jTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				JLabel tableCellRendererComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				tableCellRendererComponent.setText(((String) value));
				tableCellRendererComponent.setBackground(row % 2 == 0 ? Color.WHITE : Color.CYAN);//设置交替的背景色
				return tableCellRendererComponent;
			}
		});
		// 修改第0列的编辑器为自定义的编辑器,实现:
		// 0或其他 -> textField
		// 1 -> checkBox
		// 2 -> comboBox
		//
		jTable.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(new JComboBox()) {
			JTextField textField = new JTextField();
			JCheckBox checkBox = new JCheckBox();
			JComboBox<String> comboBox = new JComboBox<>(new String[]{"0", "1", "2"});
			JComponent currentComponent = null;
			public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
				int intValue = (int) value;
				switch (intValue) {
					case 1:
						currentComponent = checkBox;
						checkBox.setSelected(true);
						return checkBox;
					case 2:
						currentComponent = comboBox;
						comboBox.setSelectedItem("2");
						return comboBox;
					default:
						currentComponent = textField;
						textField.setText(String.valueOf(value));
						return textField;
				}
			}
			public Object getCellEditorValue() {
				if (currentComponent == checkBox) {
					return checkBox.isSelected() ? 1 : 0;
				} else if (currentComponent == comboBox) {
					return Integer.valueOf(((String) comboBox.getSelectedItem()));
				} else if (currentComponent == textField) {
					return Integer.valueOf(textField.getText());
				}
				return super.getCellEditorValue();
			}
		});
		this.add(new JScrollPane(jTable));
	}
	class MyTableModel extends DefaultTableModel {
		private String[] columnNames = new String[]{
				"id", "姓名", "语文", "数学", "英语", "总分"
		};
		private ArrayList<Data> data;
		public MyTableModel(ArrayList<Data> data) {
			this.data = data;
		}
		public Object getValueAt(int row, int column) {
			// 根据行列号获取值
			Data data = this.data.get(row);
			switch (column) {
				case 0:
					return data.id;
				case 1:
					return data.name;
				case 2:
					return data.scoreA;
				case 3:
					return data.scoreB;
				case 4:
					return data.scoreC;
				case 5:
					return data.getTotal();// 修改单科成绩后,自动刷新总分
			}
			return super.getValueAt(row, column);
		}
		public void setValueAt(Object aValue, int row, int column) {
			// 修改表格的值,cellEditor返回的值会进入这个方法设置
			Data data = this.data.get(row);
			switch (column) {
				case 0:
					data.id = (int) aValue;
					break;
				case 1:
					data.name = (String) aValue;
					break;
				case 2:
					data.scoreA = (int) aValue;
					break;
				case 3:
					data.scoreB = (int) aValue;
					break;
				case 4:
					data.scoreC = (int) aValue;
					break;
			}
		}
		public boolean isCellEditable(int row, int column) {
			// 判断列是否可编辑,设置最后一列不可编辑
			return column != columnNames.length - 1;
		}
		public String getColumnName(int column) {
			// 获得每一列的列头
			return columnNames[column];
		}
		public int getColumnCount() {
			// 获取表格共有多少列
			return columnNames.length;
		}
		public int getRowCount() {
			// 获取表格共有多少行
			return data != null ? data.size() : 0;
		}
		public Class<?> getColumnClass(int columnIndex) {
			if (columnIndex == 1) {
				return String.class;
			}
			return Integer.class;
		}
	}
	class Data {
		int id;
		String name;
		int scoreA;
		int scoreB;
		int scoreC;
		public Data(int id, String name, int scoreA, int scoreB, int scoreC) {
			this.id = id;
			this.name = name;
			this.scoreA = scoreA;
			this.scoreB = scoreB;
			this.scoreC = scoreC;
		}
		public int getTotal() {
			return scoreA + scoreB + scoreC;
		}
	}
	public static void main(String[] args) {
		MyJTable frame = new MyJTable();
		frame.setVisible(true);
	}
}

示例代码运行结果如下,表格中的内容都可编辑:

JTabelResult

相关内容

JFrame 控件

JPanel 控件

JLabel 控件

JTextField 控件

JTextArea 控件

JButton 控件

JRadioButton 控件

JCheckBox 控件

JComboBox 控件

JList 控件

JTree 控件

JToolBar 控件