SWT Section Table and Scrolling

I am trying to display a SWT table inside a section of a form, but I have problems resizing and scrolling columns.

I have added sample code that can be placed in the ViewPart of the Eclipse plug-in (3.7 is the version I use). If you run the code and resize the column to the right, the table will get a horizontal scrollbar (this is what I want).

Now, if I hide the section (click the arrow to the left of "Title Title"), a horizontal scroll bar (which I don't need) will appear in the view. By expanding the section again, scrolling the overview remains, and now the table no longer has it.

I am looking for a way (perhaps some terrible combination of nested composites) so that the table is wider than the view and would appreciate any suggestions.

public class ExampleView extends ViewPart { /** Note: other fields / methods removed to condense snippet */ private FormToolkit toolkit; private ScrolledForm scrolledForm; public void createPartControl(Composite parent) { parent.setLayout(new FillLayout()); toolkit = new FormToolkit(parent.getDisplay()); scrolledForm = toolkit.createScrolledForm(parent); scrolledForm.setExpandHorizontal(true); scrolledForm.setText("Form Title"); scrolledForm.getBody().setLayout(new FillLayout()); // here the modification for the solution scrolledForm.getBody().setLayout( new BoundedLayout(new FillLayout(), true)); final Section section = toolkit.createSection(scrolledForm.getBody(), Section.DESCRIPTION | Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED); section.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { scrolledForm.reflow(true); } }); section.setText("Section Title"); final Table table = toolkit.createTable(section, SWT.FULL_SELECTION); TableViewer viewer = new TableViewer(table); table.setLinesVisible(true); table.setHeaderVisible(true); table.setItemCount(10); TableColumn col = new TableColumn(table, SWT.NONE); col.setText("Column A"); col.setWidth(150); col.setResizable(true); col.setMoveable(true); TableColumn col2 = new TableColumn(table, SWT.NONE); col2.setText("Column B"); col2.setWidth(150); col2.setResizable(true); col2.setMoveable(true); section.setClient(table); } } 
+4
source share
2 answers

So here is a solution that I developed using a custom layout. It wraps another layout, but can bind computeSize to the width or height of the parent composite - basically only allowing scrolling in one direction (if there is an easier way to get ScrolledForm to do this, please let me know!).

There are some nasty reflective hacks that need to be applied when the computeSize and layout : protected methods

 import java.lang.reflect.Method; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Layout; public class BoundedLayout extends Layout { protected Layout delegateLayout; protected Method computeSizeMethod; protected Method layoutMethod; protected boolean widthBound; public BoundedLayout(Layout delegateLayout, boolean widthBound) { setDelegateLayout(delegateLayout); this.widthBound = widthBound; } public Layout getDelegateLayout() { return delegateLayout; } public void setDelegateLayout(Layout delegateLayout) { this.delegateLayout = delegateLayout; try { computeSizeMethod = delegateLayout.getClass().getDeclaredMethod( "computeSize", Composite.class, int.class, int.class, boolean.class); computeSizeMethod.setAccessible(true); layoutMethod = delegateLayout.getClass().getDeclaredMethod( "layout", Composite.class, boolean.class); layoutMethod.setAccessible(true); } catch (Exception e) { throw new RuntimeException(e); } } @Override protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { // get comp size to make sure we don't let any children exceed it Point compSize = composite.getSize(); try { Point layoutComputedSize = (Point) computeSizeMethod.invoke( delegateLayout, composite, wHint, hHint, flushCache); if (widthBound) { layoutComputedSize.x = Math.min(compSize.x, layoutComputedSize.x); } else { layoutComputedSize.y = Math.min(compSize.y, layoutComputedSize.y); } return layoutComputedSize; } catch (Exception e) { throw new RuntimeException(e); } } @Override protected void layout(Composite composite, boolean flushCache) { try { layoutMethod.invoke(delegateLayout, composite, flushCache); } catch (Exception e) { throw new RuntimeException(e); } } } 
+1
source

If you add the Section.COMPACT style to your section, then the section width will only be changed in the expanded state. In a compressed state, it will return to its normal size.

If you do not want the section to increase in width after expansion again, I think you will have to use a workaround in the ExpansionAdapter . Keep the width manually when folding and set it when expanding.

By the way, I would recommend using WindowBuilder to create graphical interfaces so that it is easier to configure and move.

0
source

Source: https://habr.com/ru/post/1403262/


All Articles