Java 如何始终在 SWT 表中显示垂直滚动条?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19383916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:39:41  来源:igfitidea点击:

How to always show vertical scroll bar in SWT table?

javaswttableviewjface

提问by Claude

Is it possible to always show the vertical scroll bar in a SWT table even if the table is empty? By always showing a (possible disabled) vertical scroll bar one can avoid that the last column get partially hidden when the columns use ColumnWeightDatafor layouting.

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

I tried to initialize the table with SWT.V_SCROLLor to use table.getVerticalBar().setVisible(true)- both without success.

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

There is a method setAlwaysShowScrollBarsin ScrollableComposite. What I am looking for is a similar method in Table.

有一种方法setAlwaysShowScrollBarsScrollableComposite。我正在寻找的是Table.

UPDATE:I suppose that the scroll bars which are visible when the table contains enough data are not those scroll bars which Tableinherits from Scrollable. I have debugged ScrollBar.setVisible(boolean)and it seems not be called on table layout updates. Is this observation correct?

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

UPDATE 2:Here is a snippet for a table construction. It would be great to have the vertical scrollbar visible even if the table is empty and to have the column headers visible even if the table data are scrolled down. Note: The snippet has left out some details as the label provider and some other controls arranged at the same parent composite.

更新 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");
}

采纳答案by Baz

It's not possible to force the Tableto always show scroll bars, the OS decides when to show them.

无法强制Table始终显示滚动条,操作系统决定何时显示它们。

Alternatives

备择方案

Right, I came up with a solution very similar to my answer to this question:

是的,我想出了一个与我对这个问题的回答非常相似的解决方案:

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

当 SWT 列表处于禁用状态时,是否可以使垂直/水平滚动条可见?



The idea is to use a ScrolledComposite(as the other answer already suggested) to take care of the scrolling. The Tableitself won't scroll. However, this won't make any difference, because the user won't be able to tell the difference.

这个想法是使用 a ScrolledComposite(正如已经建议的另一个答案)来处理滚动。该Table本身不会滚动。但是,这不会有任何区别,因为用户将无法分辨出区别。

ScrolledCompositehas a method called setAlwaysShowScrollBars(boolean)with which you can force it to always show the scroll bars, even if they aren't required.

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

Here is some sample code, that will illustrate what I just talked about:

下面是一些示例代码,它们将说明我刚刚谈到的内容:

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();
}

Looks like this:

看起来像这样:

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

As you can see, the scroll bar is always visible.

如您所见,滚动条始终可见。



UPDATE

更新

As pointed out in the comment, this approach will not keep the Tableheaders visible when you scroll down. If you could post a small working code example that illustrates your problem, we might come up with an alternative (unrelated to forcing the scroll bars).

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

UPDATE2

更新2

Here is some code that should do what you want, the trick is to trigger a resize event on the parent of the TableViewer, the horizontal scrollbar that is shown isn't really necessary and it disappears after you resize the window:

这是一些应该做你想做的代码,诀窍是在 的父级上触发调整大小事件TableViewer,显示的水平滚动条并不是真正必要的,并且在调整窗口大小后它会消失:

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;
    }
}

回答by ManuelRuiz-Maya

I don't think you can do this but you can try call ScrolledComposite.setAlwaysShowScrollbars() to true, but you will see both of the enabled scrollbars all the time.

我认为您不能这样做,但您可以尝试将 ScrolledComposite.setAlwaysShowScrollbars() 调用为 true,但您将始终看到两个启用的滚动条。

回答by Kildary

I have created a solution that I think is better than put your table inside a ScrolledComposite.

我创建了一个我认为比将您的表放在 ScrolledComposite 中更好的解决方案。

My solution: fill my table with empty items until my scroll bar is visible.

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

Example:

例子:

// 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 );

I hope this solution helps someone.

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

Thanks.

谢谢。