动态列表的NatTable过滤行表头层
NatTable filtering row header layer for dynamic list
当我为 Nattable 使用动态列表时,通过过滤器头层进行过滤对我不起作用。
我希望能够过滤所有列。我在过滤器行配置 class 中为每一列都有各自的代码,如果输入是静态列表,它就可以工作。
附上我的代码片段:
public 控制 createPeopleTable(复合父级){
// create a new ConfigRegistry which will be needed for GlazedLists
configRegistry = new ConfigRegistry();
peopleTableColumns = PeopleTableColumnDefinition.getPeopleTableColumns();
final Map<String, String> propertyToLabelMap = new HashMap<>();
final String[] propertyNames = new String[peopleTableColumns.size()];
for (int i = 0; i < peopleTableColumns.size(); ++i) {
final PeopleTableColumnDefinition col = peopleTableColumns.get(i);
propertyNames[i] = col.getProperty();
propertyToLabelMap.put(propertyNames[i], col.getDisplayName());
}
columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);
peopleList = new ArrayList<>();
eventList = GlazedLists.eventList(peopleList);
dynamicValues = GlazedLists.threadSafeList(eventList);
bodyLayerStack = new BodyLayerStack(dynamicValues, columnPropertyAccessor);
.....
IFilterStrategy<People> filterStrategy = new DefaultGlazedListsFilterStrategy<>(
bodyLayerStack.getFilterList(), columnPropertyAccessor, configRegistry);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<People> filterRowHeaderLayer = new FilterRowHeaderComposite<>(filterStrategy,
sortHeaderLayer, bodyLayerStack.getBodyDataProvider(), configRegistry);
// build the row header layer
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider());
DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayerStack,
bodyLayerStack.getSelectionLayer());
// build the corner layer
IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider,
rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, filterRowHeaderLayer);
// build the grid layer
GridLayer gridLayer = new GridLayer(bodyLayerStack, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);
// turn the auto configuration off as we want to add our header menu
// configuration
natTable = new NatTable(parent, gridLayer, false);
.....
natTable.addConfiguration(new FilterRowConfiguration());
natTable.configure();
...
return natTable;
}
class FilterRowConfiguration extends AbstractRegistryConfiguration {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
// register the FilterRowTextCellEditor in the first column which
// immediately commits on key press
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new FilterRowTextCellEditor(),
DisplayMode.NORMAL, FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ PeopleTableColumnDefinition.Name.columnIndex());
.....
}
class BodyLayerStack extends AbstractLayerTransform {
private FilterList<People> filterList;
private final SelectionLayer selectionLayer;
private SortedList<People> sortedList;
private ViewportLayer viewportLayer;
public BodyLayerStack(EventList<People> values,
IColumnPropertyAccessor<People> columnPropertyAccessor) {
// use the SortedList constructor with 'null' for the Comparator
// because the Comparator
// will be set by configuration
sortedList = new SortedList<>(values, null);
// wrap the SortedList with the FilterList
filterList = new FilterList<>(sortedList);
peopleListDataProvider = new PeopleListDataProvider<>(filterList, columnPropertyAccessor);
bodyDataLayer = new DataLayer(peopleListDataProvider);
final ColumnOverrideLabelAccumulator columnLabelAccumulator = new ColumnOverrideLabelAccumulator(
bodyDataLayer);
for (int i = 0; i < peopleTableColumns.size(); i++) {
PeopleTableColumnDefinition peopleTableColumnDefinition = peopleTableColumns.get(i);
columnLabelAccumulator.registerColumnOverrides(i, peopleTableColumnDefinition.getTableLabel());
}
bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<People> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer,
filterList);
selectionLayer = new SelectionLayer(glazedListsEventLayer);
viewportLayer = new ViewportLayer(selectionLayer);
FreezeLayer freezeLayer = new FreezeLayer(selectionLayer);
compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
setUnderlyingLayer(compositeFreezeLayer);
}
public SortedList<People> getSortedList() {
return sortedList;
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
public FilterList<People> getFilterList() {
return this.filterList;
}
public PeopleListDataProvider<People> getBodyDataProvider() {
return peopleListDataProvider;
}
}
public void setListOfPeople(List<People> listOfPeople) {
this.eventList.getReadWriteLock().writeLock().lock();
this.dynamicValues.getReadWriteLock().writeLock().lock();
try {
peopleList.clear();
eventList.clear();
dynamicValues.clear();
peopleList.addAll(listOfPeople);
eventList.addAll(listOfPeople);
dynamicValues.addAll(listOfPeople);
peopleListDataProvider.setPeopleList(peopleList);
} finally {
eventList.getReadWriteLock().writeLock().unlock();
dynamicValues.getReadWriteLock().writeLock().unlock();
}
}
看来你还没有理解GlazedLists和Java对象引用的原理。
首先,您不必对所有列表调用 clear() 和 addAll()。 GlazedLists 是基本列表上的视图,因此调用 EventList 或更高级别的列表(如 FilterList)应该就足够了。
第二个错误是您在 IDataProvider 上设置了另一个列表。该列表不是 FilterList。所以实际上你禁用了过滤器,因为 FilterList 正在执行过滤器魔术。并且不需要设置列表,因为您执行了列表修改。那么为什么要改变它呢?
当我为 Nattable 使用动态列表时,通过过滤器头层进行过滤对我不起作用。 我希望能够过滤所有列。我在过滤器行配置 class 中为每一列都有各自的代码,如果输入是静态列表,它就可以工作。
附上我的代码片段:
public 控制 createPeopleTable(复合父级){
// create a new ConfigRegistry which will be needed for GlazedLists
configRegistry = new ConfigRegistry();
peopleTableColumns = PeopleTableColumnDefinition.getPeopleTableColumns();
final Map<String, String> propertyToLabelMap = new HashMap<>();
final String[] propertyNames = new String[peopleTableColumns.size()];
for (int i = 0; i < peopleTableColumns.size(); ++i) {
final PeopleTableColumnDefinition col = peopleTableColumns.get(i);
propertyNames[i] = col.getProperty();
propertyToLabelMap.put(propertyNames[i], col.getDisplayName());
}
columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<>(propertyNames);
peopleList = new ArrayList<>();
eventList = GlazedLists.eventList(peopleList);
dynamicValues = GlazedLists.threadSafeList(eventList);
bodyLayerStack = new BodyLayerStack(dynamicValues, columnPropertyAccessor);
.....
IFilterStrategy<People> filterStrategy = new DefaultGlazedListsFilterStrategy<>(
bodyLayerStack.getFilterList(), columnPropertyAccessor, configRegistry);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<People> filterRowHeaderLayer = new FilterRowHeaderComposite<>(filterStrategy,
sortHeaderLayer, bodyLayerStack.getBodyDataProvider(), configRegistry);
// build the row header layer
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider());
DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayerStack,
bodyLayerStack.getSelectionLayer());
// build the corner layer
IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider,
rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, filterRowHeaderLayer);
// build the grid layer
GridLayer gridLayer = new GridLayer(bodyLayerStack, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);
// turn the auto configuration off as we want to add our header menu
// configuration
natTable = new NatTable(parent, gridLayer, false);
.....
natTable.addConfiguration(new FilterRowConfiguration());
natTable.configure();
...
return natTable;
}
class FilterRowConfiguration extends AbstractRegistryConfiguration {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
// register the FilterRowTextCellEditor in the first column which
// immediately commits on key press
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new FilterRowTextCellEditor(),
DisplayMode.NORMAL, FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX
+ PeopleTableColumnDefinition.Name.columnIndex());
.....
}
class BodyLayerStack extends AbstractLayerTransform {
private FilterList<People> filterList;
private final SelectionLayer selectionLayer;
private SortedList<People> sortedList;
private ViewportLayer viewportLayer;
public BodyLayerStack(EventList<People> values,
IColumnPropertyAccessor<People> columnPropertyAccessor) {
// use the SortedList constructor with 'null' for the Comparator
// because the Comparator
// will be set by configuration
sortedList = new SortedList<>(values, null);
// wrap the SortedList with the FilterList
filterList = new FilterList<>(sortedList);
peopleListDataProvider = new PeopleListDataProvider<>(filterList, columnPropertyAccessor);
bodyDataLayer = new DataLayer(peopleListDataProvider);
final ColumnOverrideLabelAccumulator columnLabelAccumulator = new ColumnOverrideLabelAccumulator(
bodyDataLayer);
for (int i = 0; i < peopleTableColumns.size(); i++) {
PeopleTableColumnDefinition peopleTableColumnDefinition = peopleTableColumns.get(i);
columnLabelAccumulator.registerColumnOverrides(i, peopleTableColumnDefinition.getTableLabel());
}
bodyDataLayer.setConfigLabelAccumulator(columnLabelAccumulator);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<People> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer,
filterList);
selectionLayer = new SelectionLayer(glazedListsEventLayer);
viewportLayer = new ViewportLayer(selectionLayer);
FreezeLayer freezeLayer = new FreezeLayer(selectionLayer);
compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
setUnderlyingLayer(compositeFreezeLayer);
}
public SortedList<People> getSortedList() {
return sortedList;
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
public FilterList<People> getFilterList() {
return this.filterList;
}
public PeopleListDataProvider<People> getBodyDataProvider() {
return peopleListDataProvider;
}
}
public void setListOfPeople(List<People> listOfPeople) {
this.eventList.getReadWriteLock().writeLock().lock();
this.dynamicValues.getReadWriteLock().writeLock().lock();
try {
peopleList.clear();
eventList.clear();
dynamicValues.clear();
peopleList.addAll(listOfPeople);
eventList.addAll(listOfPeople);
dynamicValues.addAll(listOfPeople);
peopleListDataProvider.setPeopleList(peopleList);
} finally {
eventList.getReadWriteLock().writeLock().unlock();
dynamicValues.getReadWriteLock().writeLock().unlock();
}
}
看来你还没有理解GlazedLists和Java对象引用的原理。
首先,您不必对所有列表调用 clear() 和 addAll()。 GlazedLists 是基本列表上的视图,因此调用 EventList 或更高级别的列表(如 FilterList)应该就足够了。 第二个错误是您在 IDataProvider 上设置了另一个列表。该列表不是 FilterList。所以实际上你禁用了过滤器,因为 FilterList 正在执行过滤器魔术。并且不需要设置列表,因为您执行了列表修改。那么为什么要改变它呢?