我的任务是创建一个包含两个TableViewers的Composite。顶部表格包含一行可编辑单元格。这些表格单元格将用于过滤底部表格中的数据。有许多事情不能正常工作,但我会将我的询问限制在一个特别的地方。 TableViewers的表格超出了包含它们的Composite的宽度和高度,并且我无法查看Composite的右边缘(或底部表格的底部延伸到底部的行)之外的表格列。 Composite的水平滚动条正确滚动,但仅限于Composite的宽度(不足为奇)。我确信它就像在构造期间调整GridData或SWT常量一样简单。可悲的是,我尝试了几种不同的组合而没有成功。这是我的相关代码的片段:
public class ControlledColumnFilterTableComposite<T> extends Composite {
private TableViewer filterViewer;
private TableViewer mainViewer;
public ControlledColumnFilterTableComposite(Composite parent,
IControlledColumnTableContentProvider<T> content) {
super(parent, SWT.H_SCROLL);
createComposite(parent, content);
}
private void createComposite(Composite parent,
IControlledColumnTableContentProvider<T> content) {
this.setLayout(new GridLayout(1, false));
GridData data = getLayoutData(parent);
this.setLayoutData(data);
addHorizontalBarListener();
this.filterViewer = createFilterViewer(parent, content);
this.mainViewer = createMainViewer(parent, content);
}
private TableViewer createFilterViewer(Composite parent,
IControlledColumnTableContentProvider<T> content) {
TableViewer viewer = new TableViewer(this, SWT.MULTI
| SWT.FULL_SELECTION | SWT.BORDER);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(content);
ControlledColumnTableMetadata<T> metadata = content.getMetadata();
for (int i = 0; i < metadata.getBean().getDeclaredFields().length; i++) {
getViewerColumn(viewer, metadata.getBean().getDeclaredFields()[i],
true);
}
return viewer;
}
private TableViewer createMainViewer(Composite parent,
IControlledColumnTableContentProvider<T> content) {
TableViewer viewer = new TableViewer(this, SWT.MULTI | SWT.V_SCROLL
| SWT.FULL_SELECTION | SWT.BORDER);
viewer.getTable().setHeaderVisible(false);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(content);
viewer.setInput(((IPagingContentProvider<T>) content)
.getModelProvider().getTableRows());
ControlledColumnTableMetadata<T> metadata = content.getMetadata();
for (int i = 0; i < metadata.getBean().getDeclaredFields().length; i++) {
getViewerColumn(viewer, metadata.getBean().getDeclaredFields()[i],
false);
}
viewer.getTable().setLayoutData(getLayoutData(parent));
/*
* I've tried getLayoutData(this) and I've also tried manipulating the
* grabExcessHorizontalSpace and grabExcessVerticalSpace on the returned
* GridData without getting the desired results
*/
return viewer;
}
private TableViewerColumn getViewerColumn(TableViewer viewer, Field field,
boolean listen) {
final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
setColumnProperties(viewer, column, field);
viewerColumn.setLabelProvider(getColumnLabelProvider(field));
// Only the filter TableViewer should have Listeners and EditingSupport
if (listen) {
// add sorting support
viewerColumn.getColumn().addListener(SWT.Selection,
new SortListener(field));
// add support for saving column width preferences
viewerColumn.getColumn()
.addControlListener(createControlListener());
// add editing support
viewerColumn.setEditingSupport(getEditingSupport(viewer, field));
}
return viewerColumn;
}
private void setColumnProperties(TableViewer viewer, TableColumn column,
Field field) {
ControlledColumnTableMetadata<T> metadata = ((IControlledColumnTableContentProvider<T>) viewer
.getContentProvider()).getMetadata();
column.setText(metadata.getColumnHeader(field));
column.setToolTipText(metadata.getColumnHeader(field));
if (metadata.isVisible(field)) {
column.setWidth(metadata.getColumnWidth(field));
column.setResizable(true);
column.setMoveable(true);
} else {
column.setWidth(0);
column.setResizable(false);
column.setMoveable(false);
}
}
private GridData getLayoutData(Composite parent) {
GridLayout layout = (GridLayout) parent.getLayout();
// Layout the viewer
GridData gridData = new GridData();
gridData.verticalAlignment = GridData.FILL;
gridData.horizontalAlignment = GridData.FILL;
gridData.horizontalSpan = layout.numColumns;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
return gridData;
}
...
}
非常感谢任何建议。提前致谢。
答案 0 :(得分:1)
不要这样做
GridData data = getLayoutData(parent); // inside getLayoutData: GridLayout layout = (GridLayout) parent.getLayout();
this.setLayoutData(data);
setLayout应该由复合使用,它安排子控件(this.setlayout)。与this.someControl.setLayoutData()相同。在您的情况下:父句柄放置ControlledColumnFilterTableComposite,ControlledColumnFilterTableComposite处理TableViewer的排列方式。这意味着您永远不应该调用:parent.getLayout()和this.setLayoutData(),因为您现在可能不会使用哪个Layout父级并使用无效的LayoutData会导致一些异常。
试试这个
this.setLayout(new GridLayout(1,false));
this.filterViewer = createFilterViewer();
this.filterViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,true));
this.mainViewer = createMainViewer();
this.mainViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,true));
GridLayout在HTML中作为表格工作 - 将控件放在单元格中。 SWT.FILL表示控件将水平和垂直填充sorounding单元格,true(第3和第4个参数)表示单元格将水平和垂直扩展到最大可用大小