Java 如何使用RowHeader处理JTables中的RowSorter同步?
以下情况:我有一个带有RowHeader的J(X)表(作为guidline,我使用了一个Rob Camicks great)。一切如期进行 根据要求,我从服务器接收的数据已经包含一个tablerownumber,我必须在rowheader中显示它,并且数据应该是可过滤的。所以我扩展了这个示例,并添加了一个过滤器。过滤视图时,我在行号中看到了间隙(例如:1、3、6、…),这是理想的效果 为了能够根据我自己的tablerow对表进行筛选和排序,我添加了一个。我开始感到困惑。该示例对mainTable和rowHeaderTable使用相同的TableModel和SelectionModel:Java 如何使用RowHeader处理JTables中的RowSorter同步?,java,swing,jtable,tablerowsorter,rowheader,Java,Swing,Jtable,Tablerowsorter,Rowheader,以下情况:我有一个带有RowHeader的J(X)表(作为guidline,我使用了一个Rob Camicks great)。一切如期进行 根据要求,我从服务器接收的数据已经包含一个tablerownumber,我必须在rowheader中显示它,并且数据应该是可过滤的。所以我扩展了这个示例,并添加了一个过滤器。过滤视图时,我在行号中看到了间隙(例如:1、3、6、…),这是理想的效果 为了能够根据我自己的tablerow对表进行筛选和排序,我添加了一个。我开始感到困惑。该示例对mainTabl
setModel( main.getModel() );
setSelectionModel( main.getSelectionModel() );
这很好,因为我不必同步它们。但是关于TableRowSorter
,我突然不确定我是否也可以或者甚至必须使用相同的TableRowSorter
-实例,或者是否必须为每个表创建一个TableRowSorter
。首先,我在两个表中都添加了相同的内容,因为这看起来很实际,但在许多情况下,我得到了indexootfound异常。经过一番挖掘,我发现这是因为TableRowSorter
在每次TableModelEvent
时都会更新两次,因为每个表(RowHeader和MainTable)都会通知TableRowSorter
现在我不确定该走哪条路。我想到了以下解决方案:我应该添加第二个TableRowSorter(每个表一个)并同步它们,还是应该将TableModel包装在RowHeaderTable中,让它不触发任何事件?或者我应该创建我自己的RowHeaderTable,它根本不通知分拣机更改 这里有一个快速(注意:没有经过正式测试!不过使用示例很好)的包装行分拣器实现
- 接收模型更改通知时不执行任何操作
- 委派所有状态查询
- 侦听包装的行分类器并传播其事件
客户有责任使其与主表中使用的行分拣机保持同步
使用示例(根据SwingX测试基础架构和SwingX sortController/table):
public void interactiverowSorterRapperSharedXtable(){
final DefaultTableModel tableModel=新的DefaultTableModel(list.getElementCount(),2){
@凌驾
公共类getColumnClass(int columnIndex){
返回Integer.class;
}
};
对于(int i=0;i
说唱歌手:
/**
* Wrapping RowSorter for usage (f.i.) in a rowHeader.
*
* Delegates all state queries,
* does nothing on receiving notification of model changes,
* propagates rowSorterEvents from delegates.
*
* Beware: untested!
*
* @author Jeanette Winzenburg, Berlin
*/
public class RowSorterWrapper<M> extends RowSorter<M> {
private RowSorter<M> delegate;
private RowSorterListener rowSorterListener;
public RowSorterWrapper(RowSorter<M> delegate) {
this.delegate = delegate;
delegate.addRowSorterListener(getRowSorterListener());
}
/**
* Creates and returns a RowSorterListener which re-fires received
* events.
*
* @return
*/
protected RowSorterListener getRowSorterListener() {
if (rowSorterListener == null) {
RowSorterListener listener = new RowSorterListener() {
@Override
public void sorterChanged(RowSorterEvent e) {
if (RowSorterEvent.Type.SORT_ORDER_CHANGED == e.getType()) {
fireSortOrderChanged();
} else if (RowSorterEvent.Type.SORTED == e.getType()) {
fireRowSorterChanged(null); }
}
};
rowSorterListener = listener;
}
return rowSorterListener;
}
@Override
public M getModel() {
return delegate.getModel();
}
@Override
public void toggleSortOrder(int column) {
delegate.toggleSortOrder(column);
}
@Override
public int convertRowIndexToModel(int index) {
return delegate.convertRowIndexToModel(index);
}
@Override
public int convertRowIndexToView(int index) {
return delegate.convertRowIndexToView(index);
}
@Override
public void setSortKeys(List keys) {
delegate.setSortKeys(keys);
}
@Override
public List getSortKeys() {
return delegate.getSortKeys();
}
@Override
public int getViewRowCount() {
return delegate.getViewRowCount();
}
@Override
public int getModelRowCount() {
return delegate.getModelRowCount();
}
@Override
public void modelStructureChanged() {
// do nothing, all work done by delegate
}
@Override
public void allRowsChanged() {
// do nothing, all work done by delegate
}
@Override
public void rowsInserted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsDeleted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsUpdated(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsUpdated(int firstRow, int endRow, int column) {
// do nothing, all work done by delegate
}
}
/**
*包装行分拣机,以便在行标头中使用(f.i.)。
*
*委托所有状态查询,
*在收到模型更改通知时不执行任何操作,
*传播来自代理的行。
*
*注意:未经测试!
*
*@作者Jeanette Winzenburg,柏林
*/
公共类RowsorterRapper扩展RowSorter{
私人分拣员代表;
私人RowsterListener RowsterListener;
公共行分拣机操作员(行分拣机代表){
this.delegate=委托;
addRowSorterListener(getRowSorterListener());
}
/**
*创建并返回重新激发接收的RowSorterListener
*事件。
*
*@返回
*/
受保护的RowSorterListener getRowSorterListener(){
if(rowSorterListener==null){
RowSorterListener=新的RowSorterListener(){
@凌驾
公共无效分拣机已更改(第e行){
if(rowsortrevent.Type.SORT\u ORDER\u CHANGED==e.getType()){
fireSortOrderChanged();
}else if(rowsortrevent.Type.SORTED==e.getType()){
/**
* Wrapping RowSorter for usage (f.i.) in a rowHeader.
*
* Delegates all state queries,
* does nothing on receiving notification of model changes,
* propagates rowSorterEvents from delegates.
*
* Beware: untested!
*
* @author Jeanette Winzenburg, Berlin
*/
public class RowSorterWrapper<M> extends RowSorter<M> {
private RowSorter<M> delegate;
private RowSorterListener rowSorterListener;
public RowSorterWrapper(RowSorter<M> delegate) {
this.delegate = delegate;
delegate.addRowSorterListener(getRowSorterListener());
}
/**
* Creates and returns a RowSorterListener which re-fires received
* events.
*
* @return
*/
protected RowSorterListener getRowSorterListener() {
if (rowSorterListener == null) {
RowSorterListener listener = new RowSorterListener() {
@Override
public void sorterChanged(RowSorterEvent e) {
if (RowSorterEvent.Type.SORT_ORDER_CHANGED == e.getType()) {
fireSortOrderChanged();
} else if (RowSorterEvent.Type.SORTED == e.getType()) {
fireRowSorterChanged(null); }
}
};
rowSorterListener = listener;
}
return rowSorterListener;
}
@Override
public M getModel() {
return delegate.getModel();
}
@Override
public void toggleSortOrder(int column) {
delegate.toggleSortOrder(column);
}
@Override
public int convertRowIndexToModel(int index) {
return delegate.convertRowIndexToModel(index);
}
@Override
public int convertRowIndexToView(int index) {
return delegate.convertRowIndexToView(index);
}
@Override
public void setSortKeys(List keys) {
delegate.setSortKeys(keys);
}
@Override
public List getSortKeys() {
return delegate.getSortKeys();
}
@Override
public int getViewRowCount() {
return delegate.getViewRowCount();
}
@Override
public int getModelRowCount() {
return delegate.getModelRowCount();
}
@Override
public void modelStructureChanged() {
// do nothing, all work done by delegate
}
@Override
public void allRowsChanged() {
// do nothing, all work done by delegate
}
@Override
public void rowsInserted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsDeleted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsUpdated(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
@Override
public void rowsUpdated(int firstRow, int endRow, int column) {
// do nothing, all work done by delegate
}
}