Neil Neil - 6 months ago 83
Java Question

JFace TableViewer - How to set the size to display one row only?

I have a TableViewer which I know will always have one row of data in it.
When I have data for that table, I can call

setInputData(...)
and pass the one object with
Arrays.asList(...)
to have the Table sized correctly displaying the one row of data.

When I do not have the object, I still want the Table to be sized to display only one row. However, if I use this:
setInputData(new ArrayList<Object>(0))
, the Table is auto-sized to show around 3 & a half blank rows. How can I get the Table to always be sized to display only one row?

I should mention that I'm using GridLayout for the Composite that the TableViewer is within as well as for the TableViewer.

I have tried setting the bounds for the SWT Table within the TableViewer to be the size of a single item, but that hasn't helped. I haven't found any similar questions on SO or through a general Google search, however in this question: TableViewer shrinks to a single row with a scroll bar when new input is set, the asker was able to have his Table sized to show one row. Unfortunately, I don't have enough rep. to comment asking him how he did that.

EDIT: Adding some more relevant code

final ScrolledComposite scrolledComposite = new ScrolledComposite(parentComposite, SWT.V_SCROLL);
scrolledComposite.setLayout(new GridLayout());
scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
scrolledComposite.setAlwaysShowScrollBars(true);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);

TableViewer tableViewer = new TableViewer(scrolledComposite, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);
// I'm setting the LabelProvider, ContentProvider here.
GridData gridData = new GridData();
gridData.heightHint = tableViewer.getTable().getItemHeight();
tableViewer.getTable().setLayoutData(gridData);

scrolledComposite.setContent(tableViewer.getControl());
scrolledComposite.setMinSize(tableViewer.getTable().getGridLineWidth(), tableViewer.getTable().getItemHeight());


And then, in a separate method:

tableViewer.setInputData(objectList); // This may be empty or have exactly one object

Answer

To anyone arriving at this link looking for a solution, building off of RĂ¼diger Herrmann's answer, what finally worked for me was to create the TableViewer inside a Composite which is then placed inside the ScrolledComposite. (This was found through another StackOverflow link which stated that a Control needs to be placed inside a Composite within the ScrolledComposite for it to show up correctly.) Then the Composite needs to be set the the ScrolledComposite like: ScrolledComposite.setContent(Composite). After setting both, the ScrolledComposite & the Composite Layouts to FillLayout & setting the size of the ScrolledComposite to be tableViewer.getTable().computeSize(SWT.DEFAULT, tableViewer.getTable().getItemHeight()), I was able to get the correct height for the TableViewer.

Once that's done, after tableViewer.setInput(objectList); is called, I set the size to the TableViewer with: tableViewer.getTable().setSize(tableViewer.getTable().computeSize(tableViewer.getTable().getClientArea().width, tableViewer.getTable().getItemHeight()));