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

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

我尝试使用table.getVerticalBar().setVisible(true)初始化表或使用table.getVerticalBar().setVisible(true) – 两者都没有成功。

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

更新:我认为当表包含足够的数据时可见的滚动条不是Tableinheritance自Scrollable那些滚动条。 我调试了ScrollBar.setVisible(boolean) ,似乎没有在表格布局更新上调用它。 这个观察是否正确?

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

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

备择方案

是的,我提出了一个非常类似于我对这个问题的答案的解决方案:

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


我们的想法是使用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(); } 

看起来像这样:

在此处输入图像描述在此处输入图像描述

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


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

我创建了一个解决方案,我认为比将表放在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 ); 

我希望这个解决方案有助于某人

谢谢。

我不认为你可以这样做但你可以尝试将ScrolledComposite.setAlwaysShowScrollbars()调用为true,但是你会一直看到两个启用的滚动条。