问题描述
我创建了一个 Eclipse 应用程序,在其中使用单个列标题实现了 NatTable 的行选择。行选择工作正常。后来我向应用程序添加了一个带有列组标题的 NatTable。问题来了,单击单元格后,行选择不起作用。仅选择了单击的单元格。
我在 RowSelectionAction extends AbstractSelectionAction
类中定义了行选择。 RowSelectionAction
对象是在类 configureBodyMouseClickBindings()
的重写 extends DefaultSelectionBindings
方法中创建的。此方法在 NatTable.configure()
方法期间调用。但在使用列分组标题创建的 NatTable 中似乎没有调用 configureBodyMouseClickBindings()
方法。
以下是使用简单列标题创建 NatTable 的代码:
private NatTable createTable(Composite parent,List<TableLine> tLines,String[][] propertyNames,PropertyToLabels[] propToLabels,TableParams params,TextMatcherEditor<TableLine>editor) {
BodyLayerStack bodyLayerStack =
new BodyLayerStack(
tLines,new LineDataProviderColumnAccessor(propertyNames[0].length),params.getColumnIndicesForRowHeaders());
DataLayer bodyDataLayer = bodyLayerStack.getBodyDataLayer();
Integer[] rowHeights = params.getRowHeights();
if( rowHeights != null && rowHeights.length > 0 ) {
for( int i = 0; i < rowHeights.length; i++ ) {
if( rowHeights[i] != null )
bodyDataLayer.setRowHeightByPosition(i,rowHeights[i]);
}
}
Integer[] colWidths = params.getColumnWidths();
if( colWidths != null && colWidths.length > 0 ) {
for( int i = 0; i < colWidths.length; i++ )
if( colWidths[i] != null )
bodyDataLayer.setColumnWidthByPosition(i,colWidths[i]);
}
IDataProvider columnHeaderDataProvider =
new DefaultColumnHeaderDataProvider(propertyNames[0],propToLabels[0].getPropertyToLabels());
DataLayer columnHeaderDataLayer =
new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
ILayer columnHeaderLayer =
new ColumnHeaderLayer(
columnHeaderDataLayer,bodyLayerStack,(SelectionLayer)null);
Integer[] hrHeights = params.getHeaderRowHeights();
if( hrHeights != null && hrHeights.length > 0 )
columnHeaderDataLayer.setRowHeightByPosition(0,hrHeights[0]);
CompositeLayer composite = new CompositeLayer(1,2);
composite.setChildLayer(GridRegion.COLUMN_HEADER,columnHeaderLayer,0);
composite.setChildLayer(GridRegion.BODY,1);
NatTable natTable = new NatTable(parent,composite,false);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
natTable.addConfiguration(new ContextMenuConfiguration(natTable));
natTable.addConfiguration(new AbstractRegistryConfiguration() {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
Style cellStyle = new Style();
cellStyle.setAttributeValue(
CellStyleAttributes.BACKGROUND_COLOR,GUIHelper.COLOR_WIDGET_BACKGROUND);
configRegistry.registerConfigAttribute(
CellConfigAttributes.CELL_STYLE,cellStyle,DisplayMode.NORMAL,RowHeaderLabel);
}
});
natTable.configure();
editor.setFilterator(new TextFilterator<TableLine>() {
@Override
public void getFilterStrings(List<String> baseList,TableLine element) {
for( int i = 0; i < element.getLength(); i++ )
baseList.add("" + element.getObjectByColumn(i));
}
});
editor.setMode(TextMatcherEditor.REGULAR_EXPRESSION);
bodyLayerStack.getFilterList().setMatcherEditor(editor);
return natTable;}
BodyLayerStack.class 内容:
class BodyLayerStack extends AbstractLayerTransform {
private final FilterList<TableLine> filterList;
private final SelectionLayer selectionLayer;
private final DataLayer bodyDataLayer;
private final IRowDataProvider<TableLine> bodyDataProvider;
public DataLayer getBodyDataLayer() {
return bodyDataLayer;
}
public SelectionLayer getSelectionLayer() {
return selectionLayer;
}
public IRowDataProvider<TableLine> getBodyDataProvider() {
return bodyDataProvider;
}
public BodyLayerStack(List<TableLine> values,IColumnAccessor<TableLine> columnAccessor,Integer[] columnIndicesForRowHeaders) {
EventList<TableLine> eventList = GlazedLists.eventList(values);
TransformedList<TableLine,TableLine> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
this.filterList = new FilterList<>(rowObjectsGlazedList);
this.bodyDataProvider = new ListDataProvider<TableLine>(this.filterList,columnAccessor);
bodyDataLayer = new DataLayer(this.bodyDataProvider);
ColumnOverrideLabelAccumulator bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
if( columnIndicesForRowHeaders != null ) {
for ( int i = 0; i < columnIndicesForRowHeaders.length; i++ ) {
bodyLabelAccumulator.registerColumnOverrides(
columnIndicesForRowHeaders[i],RowHeaderLabel);
}
}
GlazedListsEventLayer<TableLine> glazedListsEventLayer =
new GlazedListsEventLayer<>(bodyDataLayer,this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer,false);
selectionLayer.setSelectionModel(new RowSelectionModel<TableLine>(selectionLayer,this.bodyDataProvider,new IRowIdAccessor<TableLine>()
{
@Override
public Serializable getRowId(TableLine line)
{
return line.getId();
}
}));
selectionLayer.addConfiguration(new DefaultSelectionLayerConfiguration()
{
@Override
protected void addSelectionUIBindings()
{
addConfiguration(new SelectionBindings());
}
@SuppressWarnings("rawtypes")
@Override
protected void addMoveSelectionConfig()
{
addConfiguration(new RowOnlySelectionConfiguration());
}
});
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
setUnderlyingLayer(viewportLayer);
}
public FilterList<TableLine> getFilterList() {
return this.filterList;
}
}
这是用于创建列组标题 NatTable 的代码:
private NatTable createTableWithColumnHeaderGroups(Composite parent,TextMatcherEditor<TableLine> editor) {
String[][] columnHeaders = params.getColumnHeaders();
if( columnHeaders == null || columnHeaders.length != 2 )
return null;
String[] propertyNames = new String[columnHeaders[1].length];
PropertyToLabels propToLabels = new PropertyToLabels();
for( int i = 0; i < propertyNames.length; i++ ) {
propertyNames[i] = String.valueOf(i+1) + "_" + columnHeaders[1][i];
propToLabels.add(propertyNames[i],columnHeaders[1][i]);
}
BodyLayerStack bodyLayerStack =
new BodyLayerStack(
tLines,new LineDataProviderColumnAccessor(propertyNames.length),params.getColumnIndicesForRowHeaders());
ColumnGroupModel columnGroupModel = new ColumnGroupModel();
IRowDataProvider<TableLine> bodyDataProvider =
new ListDataProvider<TableLine>(tLines,new LineDataProviderColumnAccessor(propertyNames.length));
ColumnGroupBodyLayerStack bodyLayer =
new ColumnGroupBodyLayerStack(bodyLayerStack.getBodyDataLayer(),columnGroupModel);
Integer[] rowHeights = params.getRowHeights();
if( rowHeights != null && rowHeights.length > 0 ) {
for( int i = 0; i < rowHeights.length; i++ ) {
if( rowHeights[i] != null )
bodyLayer.doCommand(new RowResizeCommand(bodyLayer,i,rowHeights[i]));
}
}
Integer[] colWidths = params.getColumnWidths();
if( colWidths != null && colWidths.length > 0 ) {
for( int i = 0; i < colWidths.length; i++ )
if( colWidths[i] != null )
bodyLayer.doCommand(new ColumnResizeCommand(bodyLayer,colWidths[i]));
}
// Column header
DefaultColumnHeaderDataProvider defaultColumnHeaderDataProvider =
new DefaultColumnHeaderDataProvider(propertyNames,propToLabels.getPropertyToLabels());
DefaultColumnHeaderDataLayer columnHeaderDataLayer =
new DefaultColumnHeaderDataLayer(defaultColumnHeaderDataProvider);
ColumnHeaderLayer columnHeaderLayer =
new ColumnHeaderLayer(columnHeaderDataLayer,bodyLayer,bodyLayer.getSelectionLayer());
ColumnGroupHeaderLayer columnGroupHeaderLayer =
new ColumnGroupHeaderLayer(
columnHeaderLayer,bodyLayer.getSelectionLayer(),columnGroupModel);
Integer[] hrHeights = params.getHeaderRowHeights();
if( hrHeights != null && hrHeights.length > 0 )
for( int i = 0; i < hrHeights.length; i++ )
if( hrHeights[i] != null )
columnGroupHeaderLayer.doCommand(new RowResizeCommand(columnGroupHeaderLayer,hrHeights[i]));
List<ColumnHeaderGroup> groups = params.getColumnHeaderGroups();
for( ColumnHeaderGroup group : groups ) {
List<Integer> indices = group.getIndices();
int[] indicesArray = new int[indices.size()];
for( int i = 0; i < indices.size(); i++ )
indicesArray[i] = indices.get(i);
columnGroupHeaderLayer.addColumnsIndexesToGroup(group.getName(),indicesArray);
}
// Row header
final DefaultRowHeaderDataProvider rowHeaderDataProvider =
new DefaultRowHeaderDataProvider(bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer =
new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
ILayer rowHeaderLayer =
new RowHeaderLayer(rowHeaderDataLayer,bodyLayer.getSelectionLayer());
// Corner
final DefaultCornerDataProvider cornerDataProvider =
new DefaultCornerDataProvider(defaultColumnHeaderDataProvider,rowHeaderDataProvider);
DataLayer cornerDataLayer =
new DataLayer(cornerDataProvider);
ILayer cornerLayer =
new CornerLayer(cornerDataLayer,rowHeaderLayer,columnGroupHeaderLayer);
// Grid
GridLayer gridLayer =
new GridLayer(bodyLayer,columnGroupHeaderLayer,cornerLayer);
NatTable natTable = new NatTable(parent,gridLayer,false);
editor.setFilterator(new TextFilterator<TableLine>() {
@Override
public void getFilterStrings(List<String> baseList,TableLine element) {
for( int i = 0; i < element.getLength(); i++ )
baseList.add("" + element.getObjectByColumn(i));
}
});
editor.setMode(TextMatcherEditor.REGULAR_EXPRESSION);
bodyLayerStack.getFilterList().setMatcherEditor(editor);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
natTable.addConfiguration(new ContextMenuConfiguration(natTable));
natTable.addConfiguration(new AbstractRegistryConfiguration() {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
Style cellStyle = new Style();
cellStyle.setAttributeValue(
CellStyleAttributes.BACKGROUND_COLOR,RowHeaderLabel);
}
});
natTable.configure();
return natTable; }
最终,问题可能出在具有两行列标题创建的 nat 表的 nat 表层实现中。
解决方法
问题出在您的代码中。在带有 ColumnGroupHeader
的版本中,您创建了两个 body 层堆栈。首先是您还显示的 BodyLayerStack
。但是那个不用于列组示例。在那里您使用名为 ColumnGroupBodyLayerStack
的第二个。由于未显示该类,我无法判断该类是否缺少行选择配置。但可能是这样,因为 NatTable 层实现中没有关于该功能的问题。
顺便说一句,我建议使用 NatTable 1.6 引入的性能列分组,而不是旧的基于 ColumnGroupModel
的实现。