Avoid Tree Resize after Section expand - swt

I've got a question I couldn't resolve myself for quite a while now.
I have a RCP ViewPage containing two sections. The sections are inside a SashForm so that the user is able to resize the expanded sections. In the bottom section there is a Tree which is empty after initialization. Through user interaction (i.e. removing a filter) the tree gets filled and has a lot of data in it. If the user now collapses the bottom view and expands it again the tree gets resized which causes ScrollBars in my form. What I want is scrollbars in the tree view.
Here is how the view is build:
- ScrolledForm
- Form Body
- Sash
- Section 1
- Composite
- Some View
- Section 2
- Composite
- Tree
I hope you understand what I'm trying to achieve.
UPDATE: Here is some source code to play with. It uses a Table instead of a tree but produces the same issue.
public class MyPersonPageEditor extends FormPage {
public static final String ID = "some.ID";
TableViewer tableViewer;
public MyPersonPageEditor(FormEditor editor) {
super(editor, ID, "Some Title");
}
#Override
protected void createFormContent(IManagedForm managedForm) {
FormToolkit toolkit = managedForm.getToolkit();
ScrolledForm form = managedForm.getForm();
Composite formBody = form.getBody();
formBody.setLayout(new GridLayout());
form.setText("Some Title");
toolkit.decorateFormHeading(form.getForm());
SashForm sfForm = new SashForm(formBody, SWT.VERTICAL);
sfForm.setLayout(new GridLayout());
sfForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Section topSection = new Section(sfForm, Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
topSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
topSection.setText("Section 1 Title");
Composite topSectionComposite = toolkit.createComposite(topSection);
topSectionComposite.setLayout(new GridLayout());
toolkit.createLabel(topSectionComposite, "Just some content. Doesn't need to be much");
Button btn = toolkit.createButton(topSectionComposite, "Create Table Content", SWT.PUSH);
btn.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
for (int i = 0 ; i < 10 ; i++) {
tableViewer.add("Element " + i);
}
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
topSection.setClient(topSectionComposite);
Section bottomSection = new Section(sfForm, Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
bottomSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomSection.setText("Section 2 Title");
Composite bottomSectionComposite = toolkit.createComposite(bottomSection);
bottomSectionComposite.setLayout(new GridLayout());
bottomSectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomSection.setClient(bottomSectionComposite);
Table table = toolkit.createTable(bottomSectionComposite, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION |
SWT.V_SCROLL | SWT.H_SCROLL | SWT.RESIZE);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table.setHeaderVisible(true);
tableViewer = new TableViewer(table);
tableViewer.add("New Element");
new TableColumn(table, SWT.LEFT).setText("Spalte 1");
TableLayout layoutDefault = new TableLayout();
layoutDefault.addColumnData(new ColumnWeightData(1));
table.setLayout(layoutDefault);
form.reflow(true);
}
}
If you click the button after start the table looks like the left picture. After you collapse and expand the second section it looks like the right one.

Here is the code that works: you just have to tweak the size of the Tree/Table and make sure it will not span across the vertical space:
public void createPartControl(Composite parent) {
FormToolkit toolkit = new FormToolkit(parent.getDisplay());
final ScrolledForm form = toolkit.createScrolledForm(parent);
Composite formBody = form.getBody();
formBody.setLayout(new GridLayout());
form.setText("Some Title");
toolkit.decorateFormHeading(form.getForm());
SashForm sfForm = new SashForm(formBody, SWT.VERTICAL);
sfForm.setLayout(new GridLayout());
sfForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
//top section
Section topSection = new Section(sfForm, Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
topSection.setLayout(new GridLayout());
topSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
topSection.setText("Section 1 Title");
Composite topSectionComposite = toolkit.createComposite(topSection);
topSectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
topSectionComposite.setLayout(new TableWrapLayout());
toolkit.createLabel(topSectionComposite, "Just some content. Doesn't need to be much");
Button btn = toolkit.createButton(topSectionComposite, "Create Table Content", SWT.PUSH);
btn.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
for (int i = 0 ; i < 10 ; i++) {
tableViewer.add("Element " + i);
}
form.reflow(true);
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
topSection.setClient(topSectionComposite);
//bottom section
Section bottomSection = new Section(sfForm, Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);
bottomSection.setLayout(new GridLayout());
bottomSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomSection.setText("Section 2 Title");
Composite bottomSectionComposite = toolkit.createComposite(bottomSection);
bottomSectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
bottomSectionComposite.setLayout(new TableWrapLayout());
Table table = toolkit.createTable(bottomSectionComposite, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION |
SWT.V_SCROLL | SWT.H_SCROLL | SWT.RESIZE);
TableWrapData ttd222 = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB);
ttd222.maxHeight =200;
table.setLayoutData(ttd222);
table.setHeaderVisible(true);
tableViewer = new TableViewer(table);
tableViewer.add("New Element");
new TableColumn(table, SWT.LEFT).setText("Spalte 1");
TableLayout layoutDefault = new TableLayout();
layoutDefault.addColumnData(new ColumnWeightData(1));
table.setLayout(layoutDefault);
bottomSection.setClient(bottomSectionComposite);
form.reflow(true);
}

-make sure the Tree has the SWT.H_SCROLL style (if I remember correctly), that is has a minimum size (for example with GridLayout and GridData set the minHeight to X or with TableWrapLayout and TableData heightHint to X)
-if you don't manage to make it work just tell me and I'll try to make the code; also, a picture with the layout would be great

Related

How to create a text box when click on button in swt?

I have created 2 composite in swt. 1 button created inside 1st composite. I want to create one text box when I will click on the button. But I am unable to do that functionality.
Assuming you are using layouts for your code you just need to create the Text control and then redo the layout.
For example, using GridLayout:
shell.setLayout(new GridLayout());
final Composite buttonComposite = new Composite(shell, SWT.NONE);
buttonComposite.setLayout(new GridLayout());
final Button button = new Button(buttonComposite, SWT.PUSH);
button.setText("Create Text");
final Composite textComposite = new Composite(shell, SWT.NONE);
textComposite.setLayout(new GridLayout());
button.addSelectionListener(new SelectionAdapter()
{
#Override
public void widgetSelected(final SelectionEvent e)
{
final Text newText = new Text(textComposite, SWT.SINGLE | SWT.BORDER);
newText.setText("New text control");
newText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// Update the layout
shell.layout(true);
}
});
Alternatively you can create the Text control at the beginning but make it not visible and exclude it from the layout:
shell.setLayout(new GridLayout());
final Composite buttonComposite = new Composite(shell, SWT.NONE);
buttonComposite.setLayout(new GridLayout());
final Button button = new Button(buttonComposite, SWT.PUSH);
button.setText("Create Text");
final Composite textComposite = new Composite(shell, SWT.NONE);
textComposite.setLayout(new GridLayout());
final Text newText = new Text(textComposite, SWT.SINGLE | SWT.BORDER);
newText.setText("New text control");
// Not visible
newText.setVisible(false);
// Exclude from layout
final GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
data.exclude = true;
newText.setLayoutData(data);
button.addSelectionListener(new SelectionAdapter()
{
#Override
public void widgetSelected(final SelectionEvent e)
{
// Include in layout
final GridData data = (GridData)newText.getLayoutData();
data.exclude = false;
// Make visible
newText.setVisible(true);
// Redo layout
shell.layout(true);
}
});

How to replace a button and re position it dynamically?

I have a text box and a add button next to it, when I click on add button I am able to add a text box and delete button next to it. Now I want the add button on the first row to be changed to delete and the add button should be re-positioned below two rows, when the second row delete button is clicked (the second row is deleted )the add button should go back to the first row and replace delete button. It should look like following.
How do I achieve this?
If you create a Composite as a container of sorts, you can add and remove from it allowing everything outside to remain in the correct order. By reserving the space, the delete button is always below the contents of the container.
I have a text box and a add button next to it, when I click on add button I am able to add a text box and delete button next to it
For example, if we have a small Shell with an add Button as you mentioned, and an empty space to add the Text widgets to:
final Composite baseComposite = new Composite(shell, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
baseComposite.setLayout(new GridLayout());
final Composite rowsContainerComposite = new Composite(baseComposite, SWT.BORDER);
rowsContainerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
rowsContainerComposite.setLayout(new GridLayout());
final Button addButton = new Button(baseComposite, SWT.PUSH);
addButton.setText("Add");
(For now the empty space is grabbing all available space, but you can change that as needed)
When adding rows, you can add to the rowsContainerComposite:
addButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
new Row(rowsContainerComposite);
rowsContainerComposite.layout();
}
});
A sample Row class:
public class Row {
final Composite baseComposite;
public Row(final Composite parent) {
baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
baseComposite.setLayout(new GridLayout(2, false));
final Text text = new Text(baseComposite, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Button deleteButton = new Button(baseComposite, SWT.PUSH);
deleteButton.setText("Delete");
deleteButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
baseComposite.dispose();
parent.layout();
}
});
}
}
when the second row delete button is clicked (the second row is deleted )the add button should go back to the first row
Then when deleted, rows will shift back appropriately:
the add button should be re-positioned below two rows
The idea is that by using the "container" composite, you're reserving that space to add and remove the rows from. The delete button will always be below the rows as they are added and removed.
Full example:
public class AddDeleteButtonTest {
private static class Row {
final Composite baseComposite;
public Row(final Composite parent) {
baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
baseComposite.setLayout(new GridLayout(2, false));
final Text text = new Text(baseComposite, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Button deleteButton = new Button(baseComposite, SWT.PUSH);
deleteButton.setText("Delete");
deleteButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
baseComposite.dispose();
parent.layout();
}
});
}
}
private final Display display;
private final Shell shell;
public AddDeleteButtonTest() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new FillLayout());
final Composite baseComposite = new Composite(shell, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
baseComposite.setLayout(new GridLayout());
final Composite rowsContainerComposite = new Composite(baseComposite, SWT.BORDER);
rowsContainerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
rowsContainerComposite.setLayout(new GridLayout());
final Button addButton = new Button(baseComposite, SWT.PUSH);
addButton.setText("Add");
addButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
new Row(rowsContainerComposite);
rowsContainerComposite.layout();
}
});
}
public void run() {
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(final String... args) {
new AddDeleteButtonTest().run();
}
}
I did the same in one of my project. The code is bit complicated to do in Jface/SWT. Adding and removing widgets on composite will be bit heavy task. This will reduce UI performance.
If you use Jface tableviewer instead of creating composite, you will get better UI performance and good look as well. In table viewer in one column you can show textboxes and in one column you can show buttons. You can write table column Editing support/label providers to show the buttons.
With this approach you will be able show buttons for all rows or when you click on any cell you want to add or delete.
I can't share the code snippet right now, due to some reasons, but if you need I will share it on weekends

Unable to set size for a scrolled composite SWT

I have a main composite and within it two scrolled composites. The first scrolled composite does not have anything within it as of now. The second scrolled composite has a list. The problem is since that list is large, the second scrolled composite is occupying majority of the main composite area and leaves just a small square portion for the first scrolled composite. I want the two scrolled composite to be of at least equal sizes or one bigger than the other. I am not able to achieve this using the setSize() methods for the composites.
Code:
/** The main composite */
Composite leftComposite = new Composite(sashFormLeftRight, SWT.BORDER);
GridData leftCompositeGD = new GridData(SWT.FILL, GridData.FILL, true, false);
leftComposite.setLayoutData(leftCompositeGD);
leftComposite.setLayout(new GridLayout(1, false));
/** The first scrolled composite. Its UI elements will be filled at a later stage based on user input */
ScrolledComposite scrolledComposite = new ScrolledComposite(leftComposite, SWT.H_SCROLL | SWT.V_SCROLL);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
Composite composite = new Composite(scrolledComposite, SWT.BORDER);
composite.setLayout(new GridLayout(1, true));
composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
scrolledComposite.setContent(composite);
composite.layout(true, true);
scrolledComposite.layout(true, true);
scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
/** The second scrolled composite. It has an inner composite which has a list of string names */
ScrolledComposite scrolledParamComposite = new ScrolledComposite(leftComposite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
GridData scrolledParamCompositeGD = new GridData(SWT.FILL, GridData.FILL, true, true);
scrolledParamComposite.setLayoutData(scrolledParamCompositeGD);
scrolledParamComposite.setExpandHorizontal(true);
scrolledParamComposite.setExpandVertical(true);
Composite innerComp = new Composite(scrolledParamComposite, SWT.BORDER );
innerComp.setLayout(new GridLayout(1, true));
scrolledParamComposite.setContent(innerComp);
/** List which fills the second scrolled composite */
List parametersListForEnv = new List(innerComp, SWT.BORDER);
ParameterName[] namesList = Types.ParameterName.values();
for (int i = 0; i < namesList.length; i++) {
parametersListForEnv.add(namesList[i].name());
}
innerComp.layout(true, true);
scrolledParamComposite.layout(true, true);
scrolledParamComposite.setMinSize(innerComp.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Kindly help.
Thanks in advance.
Have you tried:
GridData compositeData = new GridData(GridData.FILL, GridData.FILL, true, true);
compositeData.heightHint = // your preferred height or the height of the other composite ;
compositeData.minimumHeight = // your preferred minimum height or the height of the other composite ;
and then
composite.setLayoutData(compositeData);
I had a similar problem and this worked for me.

Eclipse JFace/SWT ViewerFilter select never gets called

I'm trying to build a simple dialog with a TableViewer in it, along with a checkbox which would filter the data. However the table is empty and the filtering never gets done. Whats wrong with this code?
public class AsTestDialog extends TitleAreaDialog {
private Table table;
private AsTestFilter filter;
private TableViewer tableViewer;
public AsTestDialog(Shell parentShell) {
super(parentShell);
}
#Override
public void create() {
super.create();
setTitle("Table Test");
}
#Override
protected Control createDialogArea(Composite parent) {
Composite area = (Composite) super.createDialogArea(parent);
area.setLayout(new GridLayout(1, false));
tableViewer = new TableViewer(area, SWT.BORDER | SWT.FULL_SELECTION);
table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
tblclmnNewColumn.setWidth(130);
tblclmnNewColumn.setText("Column1");
TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnId = tableViewerColumn_2.getColumn();
tblclmnId.setWidth(150);
tblclmnId.setText("Column2");
Composite composite = new Composite(area, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
Button btnFilter = new Button(composite, SWT.CHECK);
btnFilter.setBounds(10, 10, 111, 20);
btnFilter.setText("Filter");
btnFilter.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("CHECKBOX SELECTED");
filter.setFilterType("foobar");
tableViewer.refresh();
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
addTestData(table);
//Filter
filter = new AsTestFilter();
tableViewer.addFilter(filter);
tableViewer.getTable().pack();
tableViewer.refresh();
return area;
}
private void addTestData(Table table) {
TableItem item1 = new TableItem(table, SWT.NONE);
item1.setText(new String[] {"1","2"});
item1.setData("1");
TableItem item2 = new TableItem(table, SWT.NONE);
item2.setText(new String[] {"3","4"});
item2.setData("3");
}
}
The filter class:
public class AsTestFilter extends ViewerFilter {
private String filterType = "all";
public void setFilterType(String tp) {
this.filterType = tp;
}
#Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
System.out.println("SELECT CALLED: "+filterType);
return true;
}
}
If you are using the JFace TableViewer you must use a 'content provider' set with
tableViewer.setContentProvider(provider);
and then call
tableViewer.setInput(input data);
creating TableItem objects directly will not work properly as TableViewer expects to create these objects itself.
If you have a simple array or List of objects the content provider can simply be:
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
and the set input:
tableViewer.setInput(array or list);
Your filter is not called because you have not called setInput, the table viewer does nothing until this is called.
The ViewerFilter operates on the TableViewer's input, which will be null in your case as you aren't using tableViewer.setInput(model). Instead you are creating TableItems directly.
You will need to set up a content provider, label provider, and define a model which you can pass to .setInput for the table viewer, and remove the function which directly creates the TableItems.
Once you do this, the ViewerFilter should work.
There are plenty of tutorials around which describe this, including https://eclipse.org/articles/Article-Table-viewer/table_viewer.html and http://wiki.eclipse.org/index.php/JFaceSnippets

How to add 2 different composite having different layout on main composite?

I want to show view which contains 2 Tree Viewers and one Table Viewer.
It will look as follow,
TreeViewer1 | TreeViewer2
-------------TableViewer------------
(Sorry as I can't upload the image from my machine due to some restrictions, but the above controls must fill the entire area of the view)
For this I had created one mainComposite, which will hold all the controls and which is having RowLayout with SWT.VERTICAL style.
After that I had created top composite which is going to hold TreeViewer1 and TreeViewer2, and which is having Grid layout with 2 columns.(Where each column will contain one TreeViewer resp.)
After that I had created bottom composite which is going to hold TableViewer, and which is again having grid layout with 1 column.
mainComposite holds top and bottom composite. The top and bottom composite needs to share mainComposites height equally and both composites needs to acquire entire width of mainComposite.
When I run the program, my controls are coming in order as I want.But they are not acquiring the entire width of the composite.( i.e. they are coming in left corner ).
I tried using different type of layouts but no help.
I tried with the post
http://www.programcreek.com/2012/03/eclipse-rcp-tutorial-5-how-to-layout-your-view-gridlayout-example/ but didn't work for me since I am having table viewer and not Text.
Any help is appreciated.
Regards,
Mandar
You can get the behavior that I think you're looking for (both trees as well as the table using all available space) by using a bunch of GridLayouts with alignments set to SWT.FILL and both grabExcess*Space parameters set to true.
Try this:
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout gl_container = new GridLayout(1, false);
gl_container.horizontalSpacing = 15;
container.setLayout(gl_container);
Composite mainComposite = new Composite(container, SWT.NONE);
mainComposite.setLayout(new GridLayout(1, false));
mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
Composite treesComposite = new Composite(mainComposite, SWT.NONE);
treesComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
treesComposite.setLayout(new GridLayout(2, false));
TreeViewer leftTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree leftTree = leftTreeViewer.getTree();
leftTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TreeViewer rightTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree rightTree = rightTreeViewer.getTree();
rightTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewer bottomTableViewer = new TableViewer(mainComposite, SWT.BORDER | SWT.FULL_SELECTION);
bottomTable = bottomTableViewer.getTable();
bottomTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
}
Alternatively, you could try using FormLayouts.
Here I specify the locations of things using the "numerator/offset" approach. Where you see numbers like 0/50/100, those are essentially percentages of the available space. The smaller numbers like 5/-5 are offsets, in pixels, from the positions described by those percentages; they provide a small margin between components.
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout gl_container = new GridLayout(1, false);
gl_container.horizontalSpacing = 15;
container.setLayout(gl_container);
Composite mainComposite = new Composite(container, SWT.NONE);
mainComposite.setLayout(new FormLayout());
mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
Composite treesComposite = new Composite(mainComposite, SWT.NONE);
FormData fd_treesComposite = new FormData();
fd_treesComposite.bottom = new FormAttachment(50);
fd_treesComposite.right = new FormAttachment(100);
fd_treesComposite.top = new FormAttachment(0);
fd_treesComposite.left = new FormAttachment(0);
treesComposite.setLayoutData(fd_treesComposite);
treesComposite.setLayout(new FormLayout());
TreeViewer leftTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree leftTree = leftTreeViewer.getTree();
FormData fd_leftTree = new FormData();
fd_leftTree.bottom = new FormAttachment(100);
fd_leftTree.right = new FormAttachment(50, -2);
fd_leftTree.top = new FormAttachment(0, 5);
fd_leftTree.left = new FormAttachment(0, 5);
leftTree.setLayoutData(fd_leftTree);
TreeViewer rightTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree rightTree = rightTreeViewer.getTree();
FormData fd_rightTree = new FormData();
fd_rightTree.bottom = new FormAttachment(100);
fd_rightTree.right = new FormAttachment(100, -5);
fd_rightTree.top = new FormAttachment(0, 5);
fd_rightTree.left = new FormAttachment(50, 3);
rightTree.setLayoutData(fd_rightTree);
TableViewer bottomTableViewer = new TableViewer(mainComposite, SWT.BORDER | SWT.FULL_SELECTION);
bottomTable = bottomTableViewer.getTable();
FormData fd_bottomTable = new FormData();
fd_bottomTable.bottom = new FormAttachment(100, -5);
fd_bottomTable.right = new FormAttachment(100, -5);
fd_bottomTable.top = new FormAttachment(50, 5);
fd_bottomTable.left = new FormAttachment(0, 5);
bottomTable.setLayoutData(fd_bottomTable);
}
Use in all composites FillLayout. Here is an small example how to use it. Important is to set SWT.VERTICAL/SWT.HORIZONTAL.