尝试创建包含两个TableViewers的org.eclipse.swt.widgets.Composite时出现问题

时间:2011-01-31 18:10:37

标签: java swt

我的任务是创建一个包含两个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;
}
 ...
}

非常感谢任何建议。提前致谢。

1 个答案:

答案 0 :(得分:1)

  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会导致一些异常。

  2. 试试这个

    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个参数)表示单元格将水平和垂直扩展到最大可用大小

  3. 删除H_SCROLL,如果要在复合使用中滚动ScrolledComposite