JTable demo
简单讲就是在没有使用layout manager的时候用setSize,在使用了layout manager 的时候用setPreferredSize
并且setPreferredSize通常和setMinimumSize、setMaximumSize联系起来使用
setSize()是你手动来设置组件的大小
Dimension 类封装单个对象中组件的宽度和高度(精确到整数)。该类与组件的某个属性关联。由 Component 类和 LayoutManager 接口定义的一些方法将返回 Dimension 对象
setPreferredSize设置此组件的首选大小
一般会用setPreferredSize
http://www.cnblogs.com/langtianya/archive/2012/10/13/2722904.html
// in constructor
rowSM_treatments = table_histories.getSelectionModel();
rowSM_treatments.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
if (lsm.isSelectionEmpty()) {
System.out.println("No rows are selected.");
} else {
selectedRow_treatments = lsm.getMinSelectionIndex();
System.out.println("selected Row> " + selectedRow_treatments);
//do more
}}});
table.changeSelection(row, 0, false, false);
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; public class SelectionListener implements ListSelectionListener {
JTable table; SelectionListener(JTable table) {
this.table = table;
} public void valueChanged(ListSelectionEvent e) {
if (e.getSource() == table.getColumnModel().getSelectionModel() && table.getColumnSelectionAllowed()) {
int firstRow = e.getFirstIndex();
int lastRow = e.getLastIndex();
// 事件处理...
}
} }
int |
getFirstIndex() Returns the index of the first row whose selection may have changed. |
int |
getLastIndex() Returns the index of the last row whose selection may have changed. |
boolean |
getValueIsAdjusting() Returns whether or not this is one in a series of multiple events, where changes are still being made. |
String |
toString() Returns a String that displays and identifies this object's properties. |
package swing.table; import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Date; import javax.swing.AbstractAction;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; public class SelectionModeDemo { String[] headings = { "Name", "Customer ID", "Order #", "Status" }; Object[][] data = {
{ "A", new Integer(3), "0", new Date() },
{ "B", new Integer(6), "4", new Date() },
{ "C", new Integer(9), "9", new Date() },
{ "D", new Integer(7), "1", new Date() },
{ "E", new Integer(4), "1", new Date() },
{ "F", new Integer(8), "2", new Date() },
{ "G", new Integer(6), "1", new Date() }
}; JTable jtabOrders = new JTable(data, headings); SelectionModeDemo() {
final JFrame jfrm = new JFrame("JTable Demo");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(800, 600);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JScrollPane jscrlp = new JScrollPane(jtabOrders);
jfrm.add(jscrlp);
jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 200)); // 设置选择模式。以下列表描述了接受的选择模式:只能选择一行!
jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // 拦截Ctrl+A组合键,防止焦点丢失
// new event create.
KeyStroke ctrlA = KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK);
// overwrite super class's event.
jtabOrders.getInputMap().put(ctrlA, "DO_NOTHING");
jtabOrders.getActionMap().put("DO_NOTHING", new AbstractAction() {
private static final long serialVersionUID = 1L; @Override
public void actionPerformed(ActionEvent e) {
System.out.println("Do nothing");
}
}); /**
* 在JTable里被选择的行发生变化时处理某事件的方法。 例如: 1:选择第一行的状态下,选择第二行时
* 2:只选择一行的状态下,追加选择另外的行时
*/
jtabOrders.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override
public void valueChanged(ListSelectionEvent e) {
DefaultListSelectionModel model = (DefaultListSelectionModel) e.getSource(); if (!e.getValueIsAdjusting()) {
/*
* public boolean getValueIsAdjusting()
* 一次鼠标的点击会有两次事件响应(按下和释放)。
* 前者的事件属性中getValueIsAdjusting()=true,后者是false。
* 因此,可以通过判断getValueIsAdjusting()来区别鼠标按下和释放。
*/
JOptionPane.showMessageDialog(jfrm, "Msg:" +
model.getSelectionMode() + " "
+ jtabOrders.getValueAt(jtabOrders.getSelectedRow(), 0).toString()
);
} }
}); jfrm.setLocationRelativeTo(null);
jfrm.setVisible(true); jtabOrders.setColumnSelectionAllowed(false);
jtabOrders.setRowSelectionAllowed(true);
} public static void main(String args[]) {
new SelectionModeDemo();
}
}
http://melodyvictor.blog.163.com/blog/static/1180061572011417315978/
//设置是否可以选择此模型中的列。
jtabOrders.setColumnSelectionAllowed(false);
//设置是否可以选择此模型中的行。
jtabOrders.setRowSelectionAllowed(true);
//设置此表是否允许同时存在行选择和列选择。
jtabOrders.setCellSelectionEnabled(true);
static int |
MULTIPLE_INTERVAL_SELECTION selectionMode 属性的值:一次选择一个或多个连续的索引范围。 |
static int |
SINGLE_INTERVAL_SELECTION selectionMode 属性的值:一次选择一个连续的索引范围。 |
static int |
SINGLE_SELECTION selectionMode 属性的值:一次选择一个列表索引。 |
http://blog.csdn.net/youyigong/article/details/6830966
编写该JTable的TableModel的String getColumnName(int columnIndex)方法
//传进来的是列的索引值
//返回该列的列名/
/给JTable设置好TableModel后,这个方法由系统自动调用
//显示在JTable中
public String getColumnName(int columnIndex){
return "你想要设置的对应列的列名";
}
eg.:
public String getColumnName(int columnIndex){
if(columnIndex == 1)
return "索引值为 1 的列的名字";
if(columnIndex == 2)
return "索引值为 2 的列的名字";
...
}
看了一篇实现JTable的列宽与内容的自适应稍加修饰后如下:
public void FitTableColumns(JTable myTable){
JTableHeader header = myTable.getTableHeader();
int rowCount = myTable.getRowCount(); Enumeration columns = myTable.getColumnModel().getColumns();
while(columns.hasMoreElements()){
TableColumn column = (TableColumn)columns.nextElement();
int col = header.getColumnModel().getColumnIndex(column.getIdentifier());
int width = (int)myTable.getTableHeader().getDefaultRenderer()
.getTableCellRendererComponent(myTable, column.getIdentifier()
, false, false, -1, col).getPreferredSize().getWidth();
for(int row = 0; row<rowCount; row++){
int preferedWidth = (int)myTable.getCellRenderer(row, col).getTableCellRendererComponent(myTable,
myTable.getValueAt(row, col), false, false, row, col).getPreferredSize().getWidth();
width = Math.max(width, preferedWidth);
}
header.setResizingColumn(column); // 此行很重要
column.setWidth(width+myTable.getIntercellSpacing().width);
}
}
http://blog.csdn.net/qof3990/article/details/8578350
http://www.blogjava.net/zeyuphoenix/archive/2010/04/08/317755.html
package swing.table; import java.awt.*;
import java.awt.event.*; import javax.swing.*;
import javax.swing.table.TableColumnModel; public class TestTable extends JFrame {
private static final long serialVersionUID = 1L;
JTable tb;
JPanel p = new JPanel(); public TestTable() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocation(112, 0);
setSize(700, 420);
final Object[] columnNames = { "档案号", "姓名", "年龄", "性别", "婚姻状况", "职业", "联系电话" };
Object[][] rowData = { { "010110", "张三", "28", "男", "已婚", "教师", "13686562936" },
{ "010110", "李四", "28", "男", "已婚", "教师", "13686562936" } };
tb = new JTable(rowData, columnNames) {
private static final long serialVersionUID = 1L; // 添加部分1
public boolean isCellEditable(int row, int column) {
return false;
}
};
tb.setPreferredScrollableViewportSize(new Dimension(639, 232));
// tb.setEnabled(false);
tb.setRowHeight(20);
tb.setRowSelectionAllowed(true);
tb.setSelectionBackground(Color.lightGray);
tb.setSelectionForeground(Color.white);
tb.setGridColor(Color.black);
tb.setShowGrid(true);
tb.setShowHorizontalLines(true);
tb.setShowVerticalLines(true);
tb.setBackground(Color.white);
// 添加部分2
tb.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {// 双击鼠标 if (e.getClickCount() == 2) {
int colummCount = tb.getModel().getColumnCount();
// 列数
for (int i = 0; i < colummCount; i++){
System.out.print(tb.getModel().getColumnName(i)+":");
System.out.print(tb.getModel().getValueAt(tb.getSelectedRow(), i).toString() + " ");
}
System.out.println();
}
}
}
});
JScrollPane pane = new JScrollPane(tb);
pane.setBackground(Color.white);
p.add(pane);
add(p);
setVisible(true);
} public static void main(String[] args) {
new TestTable();
}
}
加载时选中多行:
ListSelectionModel listSelectionModel = new DefaultListSelectionModel();
listSelectionModel .setSelectionInterval(0, 2);
table.setSelectionModel(ListSelectionModel);
listSelectionModel .removeSelectionInterval(1, 1);
ListSelectionModel listSelectionModel = new DefaultListSelectionModel();
listSelectionModel .setSelectionInterval(0, 2);
table.setSelectionModel(ListSelectionModel);
listSelectionModel .removeSelectionInterval(1, 1);
JTable中列的排序:
package swing.table.sort; import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.util.regex.Pattern; import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter; public class TestSortedTable {
private static int flag = 0; public static void main(String args[]) {
JFrame frame = new JFrame("JTable的排序测试");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final String columnNames[] = { "ID", "姓名", "国籍", "年龄", "体重" };
final Object sortRight_1st_withInt[][] = {
{ 1, "嘉靖", "中国", 44, 90.5 },
{ 3, "姚明", "中国", 25, 120.5 },
{ 2, "赵子龙", "西蜀", 1234, 130.6 },
{ 10, "曹操", "北魏", 2112, 90.0 },
{ 20, "Bill Gates", "美国", 45, 0.5 },
{ 5, "Tomas", "英国", 33, 100.0 }
}; final Object sortWrong_1st_withString[][] = {
{ "1", "嘉靖", "中国", 44, "90.5" },
{ "3", "姚明", "中国", 25, "120.5" },
{ "2", "赵子龙", "西蜀", 1234, "130.6" },
{ "10", "曹操", "北魏", 2112, "90.0" },
{ "20", "Bill Gates", "美国", 45, "0.5" },
{ "5", "Tomas", "英国", 33, "100.0" }
}; final Object[][] getRightSort_1st_withString = recoverData2Number(sortWrong_1st_withString); final DefaultTableModel model = new CustomizedTableModel(null, null); final JTable table = new JTable(model);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// table.setAutoCreateRowSorter(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 只能选一行
table.getTableHeader().setReorderingAllowed(false);
table.setRowSorter(new TableRowSorter<TableModel>(model)); JScrollPane pane = new JScrollPane(table);
frame.add(pane, BorderLayout.CENTER); JButton changeSourceBtn = new JButton("Change Source");
changeSourceBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (flag % 3 == 0) {
model.setDataVector(sortRight_1st_withInt, columnNames);
} else if (flag % 3 == 1) {
model.setDataVector(sortWrong_1st_withString, columnNames);
} else if (flag % 3 == 2) {
model.setDataVector(getRightSort_1st_withString, columnNames);
}
flag++;
}
}); JButton clearBtn = new JButton("Clear");
clearBtn.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
try {
RowSorter<?> rowSort = table.getRowSorter();
if (rowSort != null) {
rowSort.setSortKeys(null);// 如果使用了排序器,先清除对表的排序
}
((DefaultTableModel) table.getModel()).getDataVector().clear();
((DefaultTableModel) table.getModel()).fireTableDataChanged();
table.updateUI();
} catch (Exception ex) {
System.out.println(ex);
} }
}); JPanel southPanel = new JPanel();
southPanel.setLayout(new FlowLayout());
southPanel.add(changeSourceBtn);
southPanel.add(clearBtn); frame.add(southPanel, BorderLayout.SOUTH); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 300);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
} private static Object[][] recoverData2Number(Object[][] sortWrong_1st_withString) {
Object[][] target = new Object[sortWrong_1st_withString.length][];
for (int i = 0; i < sortWrong_1st_withString.length; i++) {
Object[] sourceRecord = sortWrong_1st_withString[i];
Object[] targetRecord = new Object[sourceRecord.length];
for (int j = 0; j < sourceRecord.length; j++) {
Object item = sourceRecord[j];
if (isNumericInt(sourceRecord)) {
item = Integer.parseInt(item.toString());
} else if (isNumericDouble(item)) {
item = new BigDecimal(item.toString()).doubleValue();
}
targetRecord[j] = item;
} target[i] = targetRecord;
}
return target;
} private static boolean isNumericInt(Object valueAt) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(valueAt.toString().trim()).matches();
} private static boolean isNumericDouble(Object valueAt) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*\\.?[\\d]*$");
return pattern.matcher(valueAt.toString().trim()).matches();
} } class CustomizedTableModel extends DefaultTableModel {
private static final long serialVersionUID = 1L; public Class<?> getColumnClass(int column) {
if (getRowCount() == 0) {
return Object.class;
}
return getValueAt(0, column).getClass();
} public CustomizedTableModel(Object[][] data, Object[] columnNames) {
super(data, columnNames);
} }
排序有两个途径:
(1)为每列的值设置正确的类型,并且重写DefaultTableModel中的getColumnClass方法
因为Integer,Double实现了Comparator接口,即可正确排序
(2)table.setRowSorter(new TableRowSorter<TableModel>(model));
然后为每列指定特定的Comparator:
public class OrderNumberComparator implements Comparator{ public int compare(Object o1, Object o2) {
int i = (Integer) o1 - (Integer) o2;
return i;
} }
定义表的时候,选择按自定义算法排序的字段,如果不设置,默认按字符串的ASCII码排序
JTable dataGrid=new JTable (); DefaultTableModel model = (DefaultTableModel) this.dataGrid.getModel();
TableRowSorter<TableModel> sorter=new TableRowSorter<TableModel>(model);
//sorter.setSortable(0, false);
sorter.setComparator(0, new cimframe.util.OrderNumberComparator());
sorter.setComparator(3, new cimframe.util.OrderNumberComparator());
sorter.setComparator(4, new cimframe.util.OrderNumberComparator());
sorter.setComparator(5, new cimframe.util.OrderNumberComparator());
dataGrid.setRowSorter(sorter);
一个关于SWING的工程,当然会用到大量的表格最早清空表格是这样写的
// DefaultTableModel model = (DefaultTableModel) table.getModel();
// for (int i = model.getRowCount() - 1; i >= 0; i--) {
// model.removeRow(i);
// }
用这个方法是有问题的,因为是JTable >> TableModel >> TableData(Vector或String[])这样的映射关系,如果用上面的方法,如果数据增加或减少都不会通知TableModel ,就导致每次清数据就报数据越界异常ArrayIndexOutOfBoundsException。
如果直接清理数据是会通知上层的监听,改变模型
((DefaultTableModel) table.getModel()).getDataVector().clear(); //清除表格数据
((DefaultTableModel) table.getModel()).fireTableDataChanged();//通知模型更新
table.updateUI();//刷新表格
这样做了,程序好像是不出问题了,但是如果对表格做了排序操作,再看看,程序是不出错了,但是每加载一行,就看到表格会做一次排序,这个过程的开销很大,如果数据量大的话,甚至导致内存溢出。经过一天半的研究,跟踪,终于找到了问题所在,创建表的时候,引用了排序器,排序器的监听是一个独立于JTable >> TableModel >> TableData之外,又在后台影响着这三者之间的关系的一个人,在程序调试时,很难找到他在那里影响的,最终在JDK API里发现了一点端倪
javax.swing
类 RowSorter<M>
java.lang.Object
javax.swing.RowSorter<M>
类型参数:
M
- 底层模型的类型
setSortKeys
public abstract void setSortKeys(List<? extends RowSorter.SortKey> keys)
设置当前排序键。
参数:
keys
- 新的SortKeys
;null
是指定一个空列表的简写,表示视图应该是未排序的。
toggleSortOrder
public abstract void toggleSortOrder(int column)
- 颠倒指定列的排序顺序。调用此方法时,由子类提供具体行为。通常,如果指定列已经是主要排序列,则此方法将升序变为降序(或将降序变为升序);否则,使指定列成为主要排序列,并使用升序排序顺序。如果指定列不可排序,则此方法没有任何效果。
如果此方法导致更改排序顺序和排序操作,则它将发送适当的
RowSorterListener
通知。 -
- 参数:
column
- 要切换排序顺序的列,就底层模型而言- 抛出:
IndexOutOfBoundsException
- 如果列超出底层模型的范围
上面这两个方法很像,但又有区别,我先用toggleSortOrder(int column) 这个column必须有一个有效的列号,就是说,不能用-1,这个方法是不能取消对表的排序选中的。那么另一个方法setSortKeys(List<? extendsRowSorter.SortKey> keys),这个就比较难了,我也不知道应该传什么参数,再看参数说明:null
是指定一个空列表的简写,表示视图应该是未排序的。“应该”两字说的实在是诡异,我就把它当成死马医,看看到底行不行,嘿嘿,通过方法:rowSort.setSortKeys(null);把表格还原到不排序的状态,就达到我想要的结果了,大功终于告成!
http://blog.csdn.net/aptweasel/article/details/7028058
http://www.cnblogs.com/tianyaxue/p/3494291.html
http://jingyan.baidu.com/article/fedf07377f003035ac8977c3.html
Java JTable 点击表头,能不能进行多列排序
建议已现有Jtable开发新的Table类,加个数组用于记录排序列的先后次序,重写Jtable的表头单击事件
JTable demo的更多相关文章
- jquery 插件JTable使用
http://www.jtable.org/ 下载后增加: Add these lines to the HEAD section of your HTML document: <!-- Inc ...
- Swing之JTable的详细介绍(转)
表格(Table)的使用与介绍8-1:使用JTable组件:类层次结构图:java.lang.Object--java.awt.Component--java.awt.Container--javax ...
- JSplitPane demo
package example; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; imp ...
- JTable用法-实例
前几篇文章介绍了JTable的基本用法,本文实现一个简单的JTable,算是前文的一个总结,并造福供拷贝党们. Swing-JTable用法-入门 Swing-JTable的渲染器与编辑器使用demo ...
- Swing-JTable的渲染器与编辑器使用demo
JTable的内容.外观.事件响应在很大程度上是由渲染器与编辑器控制的.具体说来,渲染器负责单元格的外观比如前景色.背景色,以及单元格提示:编辑器负责单元格的内容和事件响应.编辑器默认为文本框形式,也 ...
- 高级组件——表格JTable
JTable(Object[][] rowData,Object[] columnNames) 表格数据 列名集合 setSe ...
- java图像开发学习——JTable之导入数据库
package demo; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.MouseAd ...
- JTable写入数据库内容
/*JTable中导入数据库数据. 创建2个Vector col和dat col存入字段名 dat存入数据内容. dbname=new JTable(dat,col); */package demo; ...
- 通过一个demo了解Redux
TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...
随机推荐
- 算法起步之动态规划LCS
原文:算法起步之动态规划LCS 前一篇文章我们了解了什么是动态规划问题,这里我们再来看动态规划另一个经典问题,最长公共子序列问题(LCS),什么是子序列,我们定义:一个给定序列将其中的0个或者多个元素 ...
- linux在下面APK反编译软件和过程的描述
需要的工具: 1.apktool apk打包工具 下载地址:http://android-apktool.googlecode.com/files/apktool1.5.2.tar.bz2 安装:直接 ...
- MVC应用程序与单选列表
原文:MVC应用程序与单选列表 前几天,Insus.NET有在MVC应用程序中,练习了<MVC应用程序,动态创建单选列表(RadioButtonList)>http://www.cnblo ...
- 从零開始学习制作H5应用——V5.0:懊悔机制,整理文件夹,压缩,模板化
经过前面四个版本号的迭代.我们已经制作了一个从视觉和听觉上都非常舒服的H5微场景应用,没有看过的请戳以下: V1.0--简单页面滑动切换 V2.0--多页切换.透明过渡及交互指示 V3.0--增加lo ...
- SSDTHook实例--编写稳定的Hook过滤函数
解说怎样写Hook过滤函数,比方NewZwOpenProcess.打开进程. 非常多游戏保护都会对这个函数进行Hook. 因为我们没有游戏保护的代码,无法得知游戏公司是怎样编写这个过滤函数. 我看到非 ...
- poj3268(最短路)
题目连接:http://poj.org/problem?id=3268 题意:给出n个点和m条单向边,现在所有牛要到牛x那里去参加聚会,并且所有牛参加聚会后还要回来,给你牛x,除了牛x之外的牛,他们都 ...
- hdu1081(最大子矩阵)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1081 分析:a[i][j]代表第i行,前j个数据的和:那么由a[i][j]可得sum[k][long] ...
- Application.mk中APP_ABI 的含义
我们在编写JNI代码时有一个可选的文件Application.mk ,这个文件你可以不创建,但是有时候是有必要写一个这样的文件的. Application.mk文件用于描述应用程序本身的一些属性信息, ...
- 【Java】运用JDBC实现一个注册、登录系统的编写
数据库的建立 首先,建立一个数据库,存储注册成功的账户信息. 其SQL的DDL语句如下: CREATE TABLE `jdbctest` ( `id` int(10) NOT NULL auto_in ...
- html学习 - 自己主动跳转与自己主动刷新
自己主动刷新 事实上自己主动刷新和跳转没啥差别,刷新就是跳转到本地址. 有几种办法,首先是直接在html的<head>标签里加入以下的代码. html代码 代码都放在<head> ...