JTable用法
来源:互联网 发布:端口映射和端口转发 编辑:程序博客网 时间:2024/06/15 04:10
Swing-JTable用法-入门
注:本文为学习笔记,原文为How to Use Tables,本文所有素材与代码均源于原文,可能会有部分更改。
JTable是Swing中的表格控件,它的外观如下所示:
没错,excel或者access数据库的编辑区就是JTable这样的控件了。
创建JTable
JTable提供了2个构造器可以让你用数据和头部直接生成它:
JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames)
这两个构造器有一些特性你必须要注意:
1.JTable所有的单元格都是可编辑的;
2.它将所有数据都当做string来处理。本来,JTable可以将布尔型数据用一个checkBox来进行展示,就像表1那样,在这里就不行了。
3.它要求你把所有数据都放到数组或vector中。如果你的数据来自于数据库,那么专门再填充到数组实在是多此一举。
呐,如果你不能忍受以上限制,那么就使用table Model来管理你的数据吧!
创建TableModel
如果程序没有显式地指定tableModel,JTable会自动生成一个 DefaultTableModel实例,这样做的副作用在上面已经说过了。我们自己创建tableModel可以让数据得到更好的展示,这样做的方法是继承
AbstractTableModel。它已经提供了tableModel接口的大部分默认实现,在最低限度下,你只需要实现以下三个方法:
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
当然,如果你的应用程序有其他定制化的功能,你可以自己实现AbstractTableModel的其它方法,比如:
public Class getColumnClass(int c)//JTable uses this method to determine the default renderer editor for each cell
public boolean isCellEditable(int row, int col)//Don't need to implement this method unless your table's editable
public void setValueAt(Object value, int row, int col) //Don't need to implement this method unless your table's data can change.
TableDemo.java示意了如何自己创建并使用tableModel。
将表格添加到容器中
一般情况下我们都是将JTable放到JScrollPane中,从而使用它的滚动功能。JScrollPane会很贴心地把表头放在表格上方,并在向下滑动时始终保持它可见。如果你就是不要用JScrollPane,那么记得在容器中添加表头哦~就像下面这样
container.setLayout(new BorderLayout());container.add(table.getTableHeader(), BorderLayout.PAGE_START);container.add(table, BorderLayout.CENTER);
设置和更改列宽
设置列宽,直接上代码:
TableColumn column = null;for (int i = 0; i < 5; i++) { column = table.getColumnModel().getColumn(i); if (i == 2) { column.setPreferredWidth(100); //third column is bigger } else { column.setPreferredWidth(50); }}
当你手动调整列宽时,其它列的宽度也会自动调整,因为窗体尺寸没变。
用户选择
与JList一样,JTable也支持三种选择模式:
- 单独选择:SINGLE_SELECTION
- 单重连续选择:SINGLE_INTERVAL_SELECTION
- 多重连续选择:MULTIPLE_INTERVAL_SELECTION
具体来说,你还可以设置是否允许选择行、选择列或选择单元格。需要注意的是,行、列选择与单元格选择会相互影响的。
1.在MULTIPLE_INTERVAL_SELECTION模式下:
选择单元格被永远禁止;选择行、选择列相互排斥,要么选择若干行,要么选择若干列;
2.在SINGLE_INTERVAL_SELECTION模式下:
禁止选择单元格时,选择行、选择列相互排斥,要么选择连续行,要么选择连续列。
启用选择单元格时,三者必须同时被选中,此时单元格可被单独或连续选中。
3.在SINGLE_SELECTION模式下:
禁止选择单元格时,选择行、选择列相互排斥,要么选择一行,要么选择一列。
启用选择单元格时,三者必须同时被选中,每次只能选择一个单元格。
注意,在JTable中无法同时选择独立的多个单元格,因为其Selection模型非常简单,就是取行与列的交集。
对于已选择的行、列的提取,使用JTable.getSelectedRows和
JTable.getSelectedRows来提取它们的index。而lead selection的提取则有点违反直觉,代码如下:
String.format("Lead Selection: %d, %d. ", table.getSelectionModel().getLeadSelectionIndex(), table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
监听数据变更
为了监听数据的变更,你需要调用model的addTableModelListener方法来添加一个监听器,而这个监听器必须实现了TableModelListener接口。该接口只有一个
void tableChanged(TableModelEvent e)方法,你需要在里面进行响应。TableModelEvent将提供必要的信息,来指示发生变更的位置。它的方法有:
int getColumn()//Returns the column for the event.
int getFirstRow()//Returns the first row that changed.
int getLastRow()//Returns the last row that changed.
int getType()//Returns the type of event - one of: INSERT, UPDATE and DELETE.
得到位置后,你就可以调用model的getValueAt方法来获取最新值。
触发数据变更事件
为了触发数据变更事件,model必须知道如何创建数据变更事件。虽然这个过程很复杂,但是DefaultTableModel已经实现了。所以,你要么使用JTable默认的DefaultTableModel,要么自己继承DefaultTableModel。呐,如果你认为DefaultTableModel不合适而自己继承了 AbstractTableModel,那么你就得自己动动手啦!当数据被外部源改变时,你需要激活以下方法:
fireTableCellUpdated//Update of specified cell.
fireTableRowsUpdated//Update of specified rows
fireTableDataChanged//Update of entire table (data only).
fireTableRowsInserted//New rows inserted.
fireTableRowsDeleted//Existing rows Deleted
fireTableStructureChanged //Invalidate entire table, both data and structure.
渲染器与编辑器
渲染器决定了单元格内容的展现形式,而编辑器决定单元格内容被编辑的方式。比如,默认情况下,数字使用右对齐的JLabel来展示,布尔型变量使用单选控件来展示;而你在编辑某些列时,可能希望从下拉菜单中选择内容,这就是编辑器的作用了。出于性能上的考虑,JTable并没有为每一个单元格提供独立的渲染器,而是根据数据类型来渲染的。JTable首先会检查该列是否指定了渲染器,没有的话就检查该列的数据类型,并查看对应的渲染器。而基础类型以外的对象基本都是调用其toString方法,并通过JLable来渲染的。编辑器也是一样。
当然,我们可以对渲染器进行定制,来满足特定的需求。对指定的列或指定的数据类型应用定制渲染器都可以。如果是前者你需要调用JTable的setDefaultRenderer方法;如果是后者你需要调用指定列的setCellRenderer方法。如果你要为特定的单元格指定渲染器,那你需要调用继承JTable并重载getCellRenderer
方法。构造渲染器的最简单方法是继承DefaultTableCellRenderer类,然后实现它的setValue方法,你在里面使用setText或者setIcon来定制你渲染的内容。如果这还不够,那你可以继承一个已经存在的组件并实现 TableCellRenderer接口,比如让你的JLable继承这个接口,然后将它作为渲染器使用。
Table Render Demo Project是一个定制渲染器与编辑器的绝好例子,运行效果如下:
单元格提示(Tool tips for Cells)
单元格提示效果如上图,鼠标悬停时可显示出定制内容。在默认情况下,它是由单元格的渲染器决定的;然而,你也可以重载JTable的getToolTipText(MouseEvent)实现。下面分别介绍这两种方法。
(1)为单元格渲染器添加提示,首先需要建立一个渲染器,确认它是一个JComponent,然后用它调用setToolTipText即可。以下代码来自于TableRenderDemo.java
:
//Set up tool tips for the sport cells.DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();renderer.setToolTipText("Click for combo box");sportColumn.setCellRenderer(renderer);
以下代码来自于 ColorRenderer.java:
public class ColorRenderer extends JLabel implements TableCellRenderer { ... public Component getTableCellRendererComponent( JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { Color newColor = (Color)color; ... setToolTipText("RGB value: " + newColor.getRed() + ", " + newColor.getGreen() + ", " + newColor.getBlue()); return this; }}
(2)重载JTable的getToolTipText(MouseEvent)
在该方法中,找到指定列,然后返回指定的字符串。以下代码来自于TableToolTipsDemo.java:
JTable table = new JTable(new MyTableModel()) { //Implement table cell tool tips. public String getToolTipText(MouseEvent e) { String tip = null; java.awt.Point p = e.getPoint(); int rowIndex = rowAtPoint(p); int colIndex = columnAtPoint(p); int realColumnIndex = convertColumnIndexToModel(colIndex); if (realColumnIndex == 2) { //Sport column tip = "This person's favorite sport to " + "participate in is: " + getValueAt(rowIndex, colIndex); } else if (realColumnIndex == 4) { //Veggie column TableModel model = getModel(); String firstName = (String)model.getValueAt(rowIndex,0); String lastName = (String)model.getValueAt(rowIndex,1); Boolean veggie = (Boolean)model.getValueAt(rowIndex,4); if (Boolean.TRUE.equals(veggie)) { tip = firstName + " " + lastName + " is a vegetarian"; } else { tip = firstName + " " + lastName + " is not a vegetarian"; } } else { //another column //You can omit this part if you know you don't //have any renderers that supply their own tool //tips. tip = super.getToolTipText(e); } return tip; } ...}
运行效果如下图:
表头提示
通常表头中的不同列都具有不同的文字提示。你可以通过重载表头的getToolTipText方法来改变文字提示,也可以调用TableColumn.setHeaderRenderer来为表头提供一个定制的渲染器。
以下代码来自于TableSorterDemo.java,它为所有列头提供了相同的文字提示:
table.getTableHeader().setToolTipText( "Click to sort; Shift-Click to sort in reverse order");
以下代码来自于TableSorterDemo.java,它为后3列的列头提供不同的文字提示。
protected String[] columnToolTips = { null, // "First Name" assumed obvious null, // "Last Name" assumed obvious "The person's favorite sport to participate in", "The number of years the person has played the sport", "If checked, the person eats no meat"};...JTable table = new JTable(new MyTableModel()) { ... //Implement table header tool tips. protected JTableHeader createDefaultTableHeader() { return new JTableHeader(columnModel) { public String getToolTipText(MouseEvent e) { String tip = null; java.awt.Point p = e.getPoint(); int index = columnModel.getColumnIndexAtX(p.x); int realIndex = columnModel.getColumn(index).getModelIndex(); return columnToolTips[realIndex]; } }; }};
运行效果如下:
可以自己重写tablemodel也可以使用缺省的
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.setDataVector(row,columnNames);
JTable table = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(table); //放入滚动条中scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); //自动产生滚动条
scrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
((DefaultTableModel)table.getModel()).addRow(new Vector());//可以动态增加一个空白行
((DefaultTableModel)table.getModel()).removeRow(table.getSelectedRow());//删除选中行
下面记录一下加入复选框checkbox
先将第一列设置为boolean属性
然后添加下面代码
//设置第0列显示JCheckBox
TableColumnModel tcm = jTable1.getColumnModel();
tcm.getColumn(0).setCellEditor(new DefaultCellEditor(new JCheckBox()));
//添加标格监听事件
jTable1.addMouseListener(new MouseAdapter(){
});
sontable.getColumnModel().getColumn(0).setCellEditor(new CheckBoxCellEditor());
sontable.getColumnModel().getColumn(0).setCellRenderer(new CWCheckBoxRenderer());
class CheckBoxCellEditor extends AbstractCellEditor implements TableCellEditor {
//~ Static fields/initializers -------------------------------------------------------------------------------------
private static final long serialVersionUID = 1L;
//~ Instance fields ------------------------------------------------------------------------------------------------
protected JCheckBox checkBox;
//~ Constructors ---------------------------------------------------------------------------------------------------
public CheckBoxCellEditor() {
checkBox = new JCheckBox();
checkBox.setHorizontalAlignment(SwingConstants.CENTER);
// checkBox.setBackground( Color.white);
}
//~ Methods --------------------------------------------------------------------------------------------------------
@Override public Object getCellEditorValue() {
return Boolean.valueOf(checkBox.isSelected());
}
//~ ----------------------------------------------------------------------------------------------------------------
@Override public Component getTableCellEditorComponent(
JTable table,
Object value,
boolean isSelected,
int row,
int column) {
checkBox.setSelected(((Boolean) value).booleanValue());
return checkBox;
}
} // end class CheckBoxCellEditor
class CWCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
//~ Static fields/initializers -------------------------------------------------------------------------------------
private static final long serialVersionUID = 1L;
//~ Instance fields ------------------------------------------------------------------------------------------------
Border border = new EmptyBorder(1, 2, 1, 2);
//~ Constructors ---------------------------------------------------------------------------------------------------
public CWCheckBoxRenderer() {
super();
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
}
//~ Methods --------------------------------------------------------------------------------------------------------
@Override public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
if (value instanceof Boolean) {
setSelected(((Boolean) value).booleanValue());
// setEnabled(table.isCellEditable(row, column));
setForeground(table.getForeground());
setBackground(table.getBackground());
}
return this;
}
} // end class CWCheckBoxRenderer
- JTable用法
- JTable用法
- JTable用法
- JTable用法示例
- JTable的相关用法
- JTable的一些用法
- JTable常见用法细则
- 理解JTable的用法
- JTable常见用法细则
- JTable常见用法细则
- 关于JTable的用法
- java--JTable用法
- Jtable 的用法
- JTable常见用法细则
- JTable常见用法细则
- JTable常见用法细则
- JTable的简单用法
- JTable常见用法细则
- 第三周项目三 求集合并集
- Python2到Python3代码的转换工具2to3.py
- CSDN-markdown编辑器示意效果
- java程序练习:尝试创建一个父类,在父类中创建两个方法,在子类中覆盖第二个方法,为子类创建一个对象,将他向上转型到基类并调用这个方法。
- nginx配置location总结及rewrite规则写法
- JTable用法
- Navicat for mysql 下载、安装、连接MySQL操作
- HDU2222(AC自动机入门题)
- CentOS 7 yum 安装 Nginx
- Java练习
- JAVA 反射详解以及基础使用
- 左值和右值的区别(以a++和++a为例)
- HDU 6214 Smallest Minimum Cut (最小割)
- PAT乙级-1001A+B和C (15)