<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="ProgId" content="Word.Document">
<meta name="Generator" content="Microsoft Word 12">
<meta name="Originator" content="Microsoft Word 12">
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml">
<link rel="Edit-Time-Data" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso">
<!--[if !mso]>
<style>
v":* {behavior:url(#default#VML);}
o":* {behavior:url(#default#VML);}
w":* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]--><link rel="themeData" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx">
<link rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">
<!--[if gte mso 9]><xml>
Normal
0
false
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-alt:"Times New Roman";}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{
mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Calibri","serif";
mso-bidi-font-family:"Times New Roman";}
.MsoChpDefault
{
mso-bidi-font-family:"Times New Roman";}
/* Page Definitions */
@page
{}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
layout-grid:15.6pt;}
div.Section1
{page:Section1;}
-->
</style>
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.5pt;
font-family:"Calibri","serif";}
</style>
<![endif]-->
JTable的单元格和表头写完之后,关于JTable就剩下排序和过滤了,对于过滤来说,简单的直接使用Sun的RowSorter就可以了,复杂的可以集成Lucence等排序工具,对于它来说,性能比实现更重要,有时间就开个专题写,没时间就不写了,这里主要写排序.
排序从界面表现看其实就是对JTableHeader的鼠标操作,引发TableModel的数值比较,最后表现到画面的过程,知道这个过程很重要,它可以帮助我们完全实现自己的排序过程.
对于Java的JTable排序来说,主要分为两个阶段:Java1.6以前和Java1.6版本:Java1.6之前想要实现JTable的话,必须自己实现TableSorter,然后对JTableHeader去注册,很麻烦,但是可以完全自己控制;Java1.6为了方便,Sun增加了排序和过滤的类:
javax.swing.table.
TableRowSorter<M extends TableModel> -à
javax.swing. DefaultRowSorter<M, I> -à
javax.swing. RowSorter<M>
我们可以直接使用了.
实现很容易,看Sun官方的例子:
RowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(table.getModel());
table.setRowSorter(rowSorter);
这是JTable就自动为你实现了过滤,它的好处是不污染任何的JTable数据和渲染,自然进行排序,结果如图:
<!--[if gte vml 1]>
<![endif]-->
但是对于默认的JTable来说, TableRowSorter的默认排序都是把数据当做Object来处理的,这时我们看表格的数据行:
<!--[if gte vml 1]>
<![endif]-->
对于年份来说,这个排序是不对的,这个时候我们必须要复写TableModel的getColumnClass方法,告诉TableRowSorter我们现在需要排序的数据类型, TableRowSorter就会根据类型给我们的列设置合适的比较器Comparator:
Collator.getInstance()
@Override
public Class<? extends Object> getColumnClass(int c) {
return
getValueAt(0, c).getClass();
}
这是对JTable的排序就完成了:
<!--[if gte vml 1]>
<![endif]-->
但有时候还有别的情况,比如我们单元格放置的是一个特殊组件, TableRowSorter根本没有合适的比较器给我们提供,或者是基本类型但是我们不希望使用默认的比较器Comparator,这个时候我们就需要自己实现一个Comparator,然后通过TableRowSorter的setComparator设置某一列一个新的比较器.比如我们希望我们的第二列按字符串的反序排序:
TableRowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(table.getModel());
rowSorter.setComparator(1, new Comparator<String>() {
@Override
publicint compare(String str1, String str2) {
return
-str1.compareTo(str2);
}
});
table.setRowSorter(rowSorter);
效果如图:
<!--[if gte vml 1]>
<![endif]-->
到此为止,Java1.6排序的基本使用就完成了,通过Sun的方法很简单就实现了.
Java1.6以前的JTable排序功能必须自己实现,Sun官方也提供了例子,当然在1.6里你也可以自己实现,但是自己实现必须考虑排序Model,排序状态,JTableHeader的状态和监听,还要自己写Header的Rnederer,所以不是不能用1.6的话,最好不要自己实现.先看看是如何实现的,因为是Sun官方给的例子,就大概写下,算是学习和回忆以前使用1.5自己写Sorter的日子了.
效果和1.6类似:
<!--[if gte vml 1]>
<![endif]-->
首先看TableSorter类,它继承AbstractTableModel,这样它也就相当于自己也是一种底层数据模型,可以记录数据和排序数据:
publicclass TableSorter extends
AbstractTableModel {
然后看它的属性:
private
JTableHeader tableHeader;
这个是需要排序的JTable的Header,这里需要对它进行鼠标监听和状态管理.
private
MouseListener mouseListener;
private
TableModelListener tableModelListener;
这两个是鼠标监听器和TableModel监听器,主要是当鼠标排序和JTabel数据变化时排序也随之变化.
private
Map<Class<?>, Comparator<?>> columnComparators
= new
HashMap<Class<?>, Comparator<?>>();
private
List<Directive> sortingColumns
= new
ArrayList<Directive>();
这连个主要是记录状态的,一个是记录列的排序比较器,一个是记录列的排序状态.
publicstaticfinal Comparator<Object> LEXICAL_COMPARATOR = new
Comparator<Object>() {
publicint compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
};
另外还提供了几种基本的排序比较器,这是String的比较器.
然后是是构造函数,
public
TableSorter(TableModel tableModel) {
传入我们需要排序的JTable的TableModel,并对JTable增加事件监听和TableModel数据变化监听:
this.tableHeader.addMouseListener(mouseListener);
this.tableHeader.setDefaultRenderer(new SortableHeaderRenderer(
this.tableHeader.getDefaultRenderer()));
this.tableModel.addTableModelListener(tableModelListener);
然后处理这些监听:
privateclass MouseHandler extends
MouseAdapter {
@Override
publicvoid mouseClicked(MouseEvent e) {
首先取得排序列和当前排序状态:
JTableHeader h = (JTableHeader)
e.getSource();
TableColumnModel columnModel =
h.getColumnModel();
int viewColumn
= h.columnAtPoint(e.getPoint());
int column =
columnModel.getColumn(viewColumn).getModelIndex();
int status = getSortingStatus(column);
然后判断后调用排序方法:
setSortingStatus(column, status);
TableModel数据变化监听也类似:
privateclass TableModelHandler implements
TableModelListener {
@Override
publicvoid tableChanged(TableModelEvent e) {
非排序状态直接插入:
if (!isSorting()) {
clearSortingState();
fireTableChanged(e);
return;
}
排序状态比较插入:
int column = e.getColumn();
if (e.getFirstRow() == e.getLastRow()
&& column != TableModelEvent.ALL_COLUMNS
&& getSortingStatus(column) == NOT_SORTED
&& modelToView != null) {
int viewIndex =
getModelToView()[e.getFirstRow()];
fireTableChanged(new TableModelEvent(TableSorter.this,
viewIndex, viewIndex, column,
e.getType()));
return;
}
然后是一个行的比较器:
// Helper
classes
privateclass Row implements Comparable<Object> {
它取得比较的行:
@Override
publicint compareTo(Object o) {
int row1 = modelIndex;
int row2 =
((Row) o).modelIndex;
再去的比较的值:
Object o1 = tableModel.getValueAt(row1,
column);
Object o2 = tableModel.getValueAt(row2,
column);
根据我们提供的构造器比较:
comparison =
getComparator(column).compare(o1, o2);
其它的还有一些设置比较器,设置JTableHeader的Renderer,绘制排序的图标的方法,基本都是以前JTable会学习到的,就不写了,很多但是不难.
然后是使用,先创建我们自己构造的TableSorter:
TableSorter sorter = new
TableSorter(new MyTableModel());
当做JTable的TableModel放入JTable中:
JTable table = new
JTable(sorter);
还要设置一下Header,目的是使用我们自己做成的HeaderRenderer,可以出现图标
sorter.setTableHeader(table.getTableHeader());
以后就和正常JTable一样了.
最后,我们看一个我们自己实现排序比较和Renderer的例子:
<!--[if gte vml 1]>
<![endif]-->
<!--[if gte vml 1]>
<![endif]-->
工程目录如下:
<!--[if gte vml 1]>
<![endif]-->
其中和类是实现了Icon接口的绘制JTableHeader排序时的图片的类,
publicclass MyBlankIcon implements Icon {
publicclass MySortIcon implements Icon {
主要过程就是实现paintIcon方法绘制图片,前面写过这种三角形形式的图片绘制方法了,这里省略.
void paintIcon(Component c, Graphics g, int x, int y);
然后就是比较重要的MyTableSorter类,它继承TableRowSorter,扩充了我们自己的排序实现:
publicclass MyTableSorter extends
TableRowSorter<TableModel> {
提供了三个方法,正序、逆序和无序:
/**
* Enumeration value indicating the items
are sorted in increasing
*/
protectedvoid setASCSort(int colIdx) {
ArrayList<SortKey> key = new ArrayList<SortKey>();
key.add(new
RowSorter.SortKey(colIdx, SortOrder.ASCENDING));
setSortKeys(key);
}
/**
* Enumeration value indicating the items
are sorted in decreasing * order.
*/
protectedvoid setDESCSort(int colIdx) {
ArrayList<SortKey> key = new ArrayList<SortKey>();
key.add(new RowSorter.SortKey(colIdx,
SortOrder.DESCENDING));
setSortKeys(key);
}
/**
* Enumeration value indicating the items
are unordered.
*/
protectedvoid setUNSort(int colIdx) {
ArrayList<SortKey> key = new ArrayList<SortKey>();
key.add(new
RowSorter.SortKey(colIdx, SortOrder.UNSORTED));
setSortKeys(key);
}
提供设置当前排序状态的方法:
protectedvoid setSorterStatus(int column, boolean CtrlDown) {
List<SortKey>
SortStatus = new ArrayList<SortKey>(getSortKeys());
SortKey sortKey = null;
int sortIndex =
-1;
for (sortIndex
= SortStatus.size() - 1; sortIndex >= 0; sortIndex--) {
if
(SortStatus.get(sortIndex).getColumn() == column) {
break;
}
}
if (sortIndex == -1) {
// Key doesn't exist
if (CtrlDown)
{
sortKey = new SortKey(column, SortOrder.DESCENDING);
} else {
sortKey = new SortKey(column, SortOrder.ASCENDING);
}
SortStatus.add(0, sortKey);
} elseif (sortIndex == 0) {
// It's the primary sorting key, toggle it
SortStatus.set(0,
toggle(SortStatus.get(0), CtrlDown));
} else {
// It's not the first, but was sorted on, remove old
// entry, insert as first with ascending.
SortStatus.remove(sortIndex);
if (CtrlDown)
{
sortKey = new SortKey(column, SortOrder.DESCENDING);
} else {
sortKey = new SortKey(column, SortOrder.ASCENDING);
}
SortStatus.add(0, sortKey);
}
if
(SortStatus.size() > getMaxSortKeys()) {
SortStatus = SortStatus.subList(0,
getMaxSortKeys());
}
setSortable(column, true);
setSortKeys(SortStatus);
setSortable(column, false);
}
提供取得下一个状态的方法:
protected SortKey
toggle(SortKey key, boolean CtrlDown) {
if
(key.getSortOrder() == SortOrder.ASCENDING) {
returnnew SortKey(key.getColumn(), SortOrder.DESCENDING);
} elseif (key.getSortOrder() == SortOrder.DESCENDING) {
returnnew SortKey(key.getColumn(), SortOrder.UNSORTED);
} else {
returnnew SortKey(key.getColumn(), SortOrder.ASCENDING);
}
}
然后就是Renderer方法了,它继承TableCellRenderer,设置排序状态和Header状态:
publicclass MyHeaderButtonRenderer extends JButton implements
TableCellRenderer, MouseListener {
它提供一个属性存储当前列的排序状态:
/** save
the header state. */
private
Hashtable<Integer, Integer> state = null;
在它的鼠标事件里,设置排序和排序状态:
/**
* Invoked when the mouse button has been
clicked (pressed and
* released) on a component.
*/
@Override
publicvoid mouseClicked(MouseEvent e) {
先取得鼠标事件的列,设置表现:
int col = header.columnAtPoint(e.getPoint());
int sortCol = header.getTable().convertColumnIndexToModel(col);
renderer.setPressedColumn(col);
renderer.setSelectedColumn(col);
header.repaint();
再设置排序和状态:
if (header.getTable().isEditing()) {
header.getTable().getCellEditor().stopCellEditing();
}
if (!(DOWN == renderer.getState(col))
&& !(UP == renderer.getState(col))) {
sorter.setUNSort(sortCol);
}
实现TableCellRenderer的方法设置列的Header的表现:
@Override
public Component
getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (header != null && renderer != null) {
boolean isPressed =
(column == pushedColumn);
button.getModel().setPressed(isPressed);
button.getModel().setArmed(isPressed);
}
使用也不是很麻烦:
先创建Sorter:
TableSorter tableSorter = new MyTableSorter(table);
设置某一列的比较器,和TableSorter一样:
tableSorter.setComparator(2, new MyComparator<String>());
table.setRowSorter(tableSorter);
然后是创建Renderer:
MyHeaderButtonRenderer renderer = new MyHeaderButtonRenderer();
然后设置JTable的Header的Renderer:
table.getColumnModel().getColumn(i).setHeaderRenderer(renderer);
这样就完成了.
分享到:
相关推荐
### jQuery 实现表格排序 #### 知识点一:jQuery表格排序插件介绍 在Web开发中,数据展示经常需要通过表格的形式呈现给用户,并且为了方便用户查找所需信息,通常会提供排序功能。传统的表格排序往往需要后端的...
本资源“jQuery Table表格排序显示代码.zip”聚焦于利用jQuery实现动态表格排序的功能,这对于数据展示和用户交互至关重要。下面将详细阐述相关知识点。 1. **jQuery基础**:首先,理解jQuery的基础是至关重要的。...
易语言高级表格排序示例,程序模仿易语言例程里面的高级列表框排序写成.
而JavaScript实现的表格排序功能则能够帮助用户更方便地管理和理解这些数据。这篇我们将深入探讨如何使用JavaScript实现表格排序,包括对数字、日期和汉字的排序。 首先,我们需要理解HTML表格的基本结构,通常由`...
本示例项目“android 表格 排序 源码”提供了实现Android表格排序功能的完整源码,用户可以点击表头对表格中的数据进行升序或降序排序。下面我们将详细讲解这个功能实现的关键知识点。 1. **使用GridView或...
jquery-tablesort则是一个独立于jQuery的表格排序库,它提供了类似的功能,但不依赖于jQuery。这意味着如果你的项目不使用jQuery或者希望减少依赖,这个库是个不错的选择。jquery-tablesort同样支持多种数据类型的...
总结起来,这个JavaScript表格排序示例展示了如何通过监听表头点击事件,使用纯JavaScript实现表格数据的动态排序。它依赖于HTML表格结构,通过JavaScript操作DOM节点进行数据比较和位置交换。在实际项目中,可以...
表格排序对于数据展示和分析尤其重要,特别是在数据量较大的情况下。 在描述中提到的“博文链接:https://liu346435400.iteye.com/blog/1130963”,这可能是一个博客文章,详细介绍了如何使用特定的jQuery表格排序...
`tablesort.js` 是一个用于表格排序的JavaScript库,而 `jquery-1.9.0.min.js` 是jQuery的轻量级版本,它是一个广泛使用的JavaScript库,提供了更简单、更高效的DOM操作、事件处理和动画功能。 首先,我们要理解...
"表格排序和表头浮动"就是一个这样的功能组合,它使得用户能更方便地浏览和理解大量数据。 表格排序是指用户可以通过点击表格列头来按该列的数据进行升序或降序排列。这个功能对于处理大量结构化数据非常有用,比如...
**Blue Table:JavaScript表格排序插件** 在网页开发中,数据展示经常需要用到表格,而对表格数据进行排序是用户交互中的常见需求。Blue Table是一款基于JavaScript的表格排序插件,它能够帮助开发者轻松实现表格...
源码是软件开发的基础,通过查看和理解源码,开发者可以学习到如何用JavaScript实现表格排序功能,包括数据处理、事件监听、DOM操作等技术。 “工具”标签则表明这是一个开发者使用的辅助工具,可以帮助他们在自己...
表格排序通常用于显示大量结构化数据,并允许用户根据需要对数据进行升序或降序排列。在中文环境下,排序需要考虑中文字符的Unicode编码顺序,确保排序的准确性。 ### 3. 实现思路 - 首先,我们需要一个包含表格...
《表格排序插件详解及其应用》 在网页开发中,数据展示往往离不开表格。而当表格数据量较大或者需要频繁进行动态排序时,一个高效、易用的表格排序插件就显得尤为重要。本文将深入探讨“表格排序插件”,特别是以...
Excel因其强大的数据处理和可视化能力而备受青睐,因此在网页或应用程序中模拟其某些特性,如表格排序,能极大地提升用户体验。在这个"仿excle表格排序效果"的项目中,我们将探讨如何实现点击表头进行按列排序的功能...
在JavaScript编程中,实现带箭头的表格排序是一种常见的需求,尤其在数据展示和交互式网页设计中。本文将深入探讨如何使用JavaScript实现这一功能,包括理解基础的HTML表格结构、CSS样式设置以及JavaScript事件处理...
要实现“漂亮的html表格排序实现”,我们需要借助JavaScript或者jQuery等库来增强HTML表格的功能,让数据可以按照用户的需求进行升序或降序排列。下面将详细介绍这个过程中的关键知识点。 1. HTML基础 首先,我们...
在描述中提到了一个博客链接,虽然具体内容没有给出,但可以推测博主分享了一篇关于如何使用jQuery创建表格排序功能的文章。在实际应用中,这样的插件可能包括以下关键知识点: 1. **jQuery基础**:了解jQuery的...
"Table表格排序显示jQuery代码"是一个实用的工具,它允许用户通过简单的点击表头来实现表格数据的多维度排序,包括分类排序、数字大小排序以及英文排序等。这个功能极大地提升了用户体验,使得大量数据的浏览和分析...
而“使用jQuery UI实现表格排序功能”是网页交互设计中的常见需求,尤其对于数据展示丰富的网页,如报表、数据分析页面等。jQuery UI 的 tablesorter 插件可以方便地实现这一功能,让表格数据可以根据用户的需求进行...