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
How to always show vertical scroll bar in SWT table?
提问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 ColumnWeightData
for layouting.
即使表格为空,是否可以始终在 SWT 表格中显示垂直滚动条?通过始终显示(可能禁用)垂直滚动条,可以避免当列ColumnWeightData
用于布局时最后一列被部分隐藏。
I tried to initialize the table with SWT.V_SCROLL
or to use table.getVerticalBar().setVisible(true)
- both without success.
我试图用SWT.V_SCROLL
或使用来初始化表table.getVerticalBar().setVisible(true)
- 两者都没有成功。
There is a method setAlwaysShowScrollBars
in ScrollableComposite
. What I am looking for is a similar method in Table
.
有一种方法setAlwaysShowScrollBars
在ScrollableComposite
。我正在寻找的是Table
.
UPDATE:I suppose that the scroll bars which are visible when the table contains enough data are not those scroll bars which Table
inherits 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
Table
to 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:
是的,我想出了一个与我对这个问题的回答非常相似的解决方案:
当 SWT 列表处于禁用状态时,是否可以使垂直/水平滚动条可见?
The idea is to use a ScrolledComposite
(as the other answer already suggested) to take care of the scrolling. The Table
itself won't scroll. However, this won't make any difference, because the user won't be able to tell the difference.
这个想法是使用 a ScrolledComposite
(正如已经建议的另一个答案)来处理滚动。该Table
本身不会滚动。但是,这不会有任何区别,因为用户将无法分辨出区别。
ScrolledComposite
has 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:
看起来像这样:
As you can see, the scroll bar is always visible.
如您所见,滚动条始终可见。
UPDATE
更新
As pointed out in the comment, this approach will not keep the Table
headers 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.
谢谢。