2013-10-15 80 views
5

即使表格为空,是否可以始终在SWT表格中显示垂直滚动条?通过始终显示(可能已禁用)的垂直滚动条,可以避免当列使用ColumnWeightData进行布局时最后一列会部分隐藏。如何在SWT表格中始终显示垂直滚动条?

我试图使用SWT.V_SCROLL初始化表或使用table.getVerticalBar().setVisible(true) - 两者均未成功。

ScrollableComposite中有一种方法setAlwaysShowScrollBars。我在寻找的是Table中的类似方法。

更新:我想,滚动条当表包含足够的数据,可见不是那些滚动条,其Table继承Scrollable。我调试了ScrollBar.setVisible(boolean),它似乎没有被调用表格布局更新。这个观察是否正确?

UPDATE 2:这是一个表格构建的代码片段。即使表是空的,也可以看到垂直滚动条,并且即使表格数据向下滚动也可以看到列标题,这将是非常好的。注意:代码片段已经省略了一些细节,因为标签提供者和其他一些控件安排在同一个父组合上。

protected void createMasterPart(final IManagedForm managedForm, Composite parentComposite) 
{ 
    FormToolkit toolkit = managedForm.getToolkit(); 

    Composite contentComposite = toolkit.createComposite(parentComposite, SWT.NONE); 
    contentComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); 
    toolkit.paintBordersFor(contentComposite); 

    contentComposite.setLayout(new GridLayout(2, false)); 
    GridData gd; 

    Composite tableComposite = new Composite(contentComposite, SWT.NONE); 
    TableColumnLayout tableColumnLayout = new TableColumnLayout(); 
    tableComposite.setLayout(tableColumnLayout); 
    gd = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 3); 
    tableComposite.setLayoutData(gd); 

    speakerTableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION); 
    speakerTableViewer.setContentProvider(ArrayContentProvider.getInstance()); 
    Table speakerTable = speakerTableViewer.getTable(); 
    speakerTable.setHeaderVisible(true); 
    speakerTable.setLinesVisible(true); 
    toolkit.paintBordersFor(speakerTable); 

    TableViewerColumn tableViewerAudiosampleColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE); 
    TableColumn audiosampleColumn = tableViewerAudiosampleColumn.getColumn(); 
    tableColumnLayout.setColumnData(audiosampleColumn, new ColumnWeightData(60, true)); 
    audiosampleColumn.setText("Sample"); 

    TableViewerColumn tableViewerSpeakerColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE); 
    TableColumn speakerColumn = tableViewerSpeakerColumn.getColumn(); 
    tableColumnLayout.setColumnData(speakerColumn, new ColumnWeightData(60, true)); 
    speakerColumn.setText("Speaker"); 

    TableViewerColumn tableViewerRemarkColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE); 
    TableColumn remarkColumn = tableViewerRemarkColumn.getColumn(); 
    tableColumnLayout.setColumnData(remarkColumn, new ColumnWeightData(120, true)); 
    remarkColumn.setText("Remark"); 
} 
+0

将您的桌子包裹在面板内。 – Makky

+0

@Makky你是什么意思的面板? – Claude

+0

为什么你会显示一个空数据表的滚动条? – Makky

回答

6

不可能强制Table总是显示滚动条,操作系统决定何时显示它们。

替代

好吧,我想出了非常相似,我的回答这个问题的解决方案:

Is it possible to get the vertical/horizontal scroll bar visible when the SWT List is in disabled state?


的想法是使用ScrolledComposite (作为其他答案已经建议)来照顾滚动。 Table本身不会滚动。 但是,这不会有什么区别,因为用户将无法区分。

ScrolledComposite有一个名为setAlwaysShowScrollBars(boolean)的方法,可以强制它始终显示滚动条,即使它们不是必需的。

下面是一些示例代码,这将说明我刚才谈到:

public static void main(String[] args) 
{ 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new GridLayout()); 

    final ScrolledComposite composite = new ScrolledComposite(shell, SWT.V_SCROLL); 
    composite.setLayout(new GridLayout()); 
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 

    final Table table = new Table(composite, SWT.NO_SCROLL | SWT.FULL_SELECTION); 
    table.setHeaderVisible(true); 

    composite.setContent(table); 
    composite.setExpandHorizontal(true); 
    composite.setExpandVertical(true); 
    composite.setAlwaysShowScrollBars(true); 
    composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

    Button fillTable = new Button(shell, SWT.PUSH); 
    fillTable.setText("Fill table"); 
    fillTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false)); 

    fillTable.addListener(SWT.Selection, new Listener() 
    { 
     @Override 
     public void handleEvent(Event arg0) 
     { 
      if (table.getColumnCount() < 1) 
      { 
       for (int col = 0; col < 4; col++) 
       { 
        TableColumn column = new TableColumn(table, SWT.NONE); 
        column.setText("Column " + col); 
       } 
      } 

      for (int row = 0; row < 20; row++) 
      { 
       TableItem item = new TableItem(table, SWT.NONE); 

       for (int col = 0; col < table.getColumnCount(); col++) 
       { 
        item.setText(col, "Item " + row + " " + col); 
       } 
      } 

      for (int col = 0; col < table.getColumnCount(); col++) 
      { 
       table.getColumn(col).pack(); 
      } 

      composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 
     } 
    }); 

    Button clearTable = new Button(shell, SWT.PUSH); 
    clearTable.setText("Clear table"); 
    clearTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false)); 

    clearTable.addListener(SWT.Selection, new Listener() 
    { 
     @Override 
     public void handleEvent(Event arg0) 
     { 
      table.removeAll(); 

      composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 
     } 
    }); 

    shell.pack(); 
    shell.setSize(400, 300); 
    shell.open(); 
    while (!shell.isDisposed()) 
    { 
     if (!display.readAndDispatch()) 
      display.sleep(); 
    } 
    display.dispose(); 
} 

是这样的:

enter image description here enter image description here

正如你可以看到,滚动条始终可见。


UPDATE

正如评论指出的那样,这种方法不会保持Table标题可见,当你向下滚动。如果您可以发布一个能够说明您的问题的小型工作代码示例,那么我们可以提出一个替代方案(与强制滚动条无关)。

UPDATE2

下面是一些代码,应该做你想要什么,关键是要在TableViewer的父触发resize事件,所显示的水平滚动条是不是真的有必要,它消失调整窗口的大小后:

public static void main(String[] args) 
{ 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setText("StackOverflow"); 
    shell.setLayout(new GridLayout()); 

    createMasterPart(shell); 

    shell.pack(); 
    shell.setSize(400, 300); 
    shell.open(); 

    shell.layout(true, true); 

    while (!shell.isDisposed()) 
    { 
     if (!display.readAndDispatch()) 
      display.sleep(); 
    } 
    display.dispose(); 
} 

private static void createMasterPart(Composite parentComposite) 
{ 
    Composite composite = new Composite(parentComposite, SWT.NONE); 
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
    composite.setLayout(new GridLayout(1, false)); 

    Composite tableComposite = new Composite(composite, SWT.NONE); 
    TableColumnLayout tableColumnLayout = new TableColumnLayout(); 
    tableComposite.setLayout(tableColumnLayout); 
    tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 

    TableViewer tableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION); 
    tableViewer.setContentProvider(ArrayContentProvider.getInstance()); 
    Table table = tableViewer.getTable(); 
    table.setHeaderVisible(true); 
    table.setLinesVisible(true); 

    TableViewerColumn firstTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); 
    TableColumn firstTableColumn = firstTableViewerColumn.getColumn(); 
    firstTableColumn.setText("Sample"); 
    firstTableViewerColumn.setLabelProvider(new ColumnLabelProvider() 
    { 
     @Override 
     public String getText(Object element) 
     { 
      Dummy p = (Dummy) element; 
      return p.first; 
     } 
    }); 

    TableViewerColumn secondTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); 
    TableColumn secondTableColumn = secondTableViewerColumn.getColumn(); 
    secondTableColumn.setText("Speaker"); 
    secondTableViewerColumn.setLabelProvider(new ColumnLabelProvider() 
    { 
     @Override 
     public String getText(Object element) 
     { 
      Dummy p = (Dummy) element; 
      return p.second; 
     } 
    }); 

    TableViewerColumn thirdTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); 
    TableColumn thirdTableColumn = thirdTableViewerColumn.getColumn(); 
    thirdTableColumn.setText("Remark"); 
    thirdTableViewerColumn.setLabelProvider(new ColumnLabelProvider() 
    { 
     @Override 
     public String getText(Object element) 
     { 
      Dummy p = (Dummy) element; 
      return p.third; 
     } 
    }); 

    List<Dummy> elements = new ArrayList<>(); 

    for(int i = 0; i < 20; i++) 
    { 
     elements.add(new Dummy("firstfirstfirst " + i, "secondsecondsecond " + i, "thirdthirdthirdthirdthirdthird " + i)); 
    } 

    tableViewer.setInput(elements); 

    tableColumnLayout.setColumnData(firstTableColumn, new ColumnWeightData(1, true)); 
    tableColumnLayout.setColumnData(secondTableColumn, new ColumnWeightData(1, true)); 
    tableColumnLayout.setColumnData(thirdTableColumn, new ColumnWeightData(2, true)); 
} 

private static class Dummy 
{ 
    public String first; 
    public String second; 
    public String third; 

    public Dummy(String first, String second, String third) 
    { 
     this.first = first; 
     this.second = second; 
     this.third = third; 
    } 
} 
+0

列标题在向下滚动后仍然可见吗? – Basilevs

+0

@Basilevs他们从来没有在SWT表中。 – Baz

+0

通常,表格标题始终显示在每个滚动位置。 – Basilevs

-1

我不认为你可以做到这一点,但你可以尝试调用ScrolledComposite.setAlwaysShowScrollbars()为真,但你都将启用滚动条看到所有的时间。

+0

该表不是“ScrollableComposite”,不在“ScrollableComposite”中。什么是“ScrolledComposite”? – Claude

0

我创建了一个解决方案,我认为这是比把你的表里面ScrolledComposite。

我的解决方案:填充我的表与空项目,直到我的滚动条是可见的。

例子:

// Flag that knows if the empty item was added or not 
boolean addedEmptyItem = false; 

// Get the table client area 
Rectangle rect = table.getClientArea(); 
// Get the item height 
int itemHeight = table.getItemHeight(); 
// Get the header height 
int headerHeight = table.getHeaderHeight(); 
// Calculate how many items can be visible without scrolling 
int visibleCount = (rect.height - headerHeight + itemHeight - 1)/itemHeight; 

while (visibleCount > table.getItemCount()) { 
    // Add an empty item 
    new TableItem(table, SWT.NONE); 

    // Set the flag 
    addedEmptyItem = true; 
} 

// Vertical bar é disabled if an empty item was added 
table.getVerticalBar().setEnabled(!addedEmptyItem); 

我希望这个解决方案可以帮助别人。

谢谢。

+0

感谢您的示例!但是,恐怕有很多事情需要做,以便在高效环境中工作:禁用空项目的选择;在调整表格大小时适应;如果真的物品被添加,则适应;与桌子模型一起工作。不管怎么说,还是要谢谢你! – Claude