javaeclipseswtwindowbuilder

WindowBuilder: switching Composite within an application window


I have an application window, within I´d like to show different components depending on several circumstances.

package graphicalInterface;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.RowLayout;

public class parentWindow {
    protected Shell shell;
    
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
    
    protected void createContents() 
    {
        shell = new Shell();
        shell.setSize(600, 400);
        shell.setText("Test");
        shell.setLayout(new RowLayout(SWT.HORIZONTAL));
        menu myMenu = new menu(shell, SWT.NONE);    
        menu myMenu2 = new menu(shell, SWT.NONE);   
        menu myMenu3 = new menu(shell, SWT.NONE);   
    }
}

the Composite reads

package graphicalInterface;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.SWT;

public class menu extends Composite {
    public menu(Composite parent, int style) {
        super(parent, SWT.NONE);
        
        Button btnAzLicht = new Button(this, SWT.NONE);
        btnAzLicht.setBounds(10, 10, 150, 35);
        btnAzLicht.setText("AZ Licht");     
    }

    @Override
    protected void checkSubclass() {}
}

I have also several other composites, and like to load them as needed. Problem is, I dunno how to unload them. Here I have loaded three of the menus, which are added beginning in the topleft corner of the window. If I simply redraw the window (not loading the composites a second time) they keep showing, disposing them did not success. I can set them invisible, but if I load another one then, it´s position is not the position of the invisible one, it is added at th next free place. Setting bounds did also not help, and I did not find a way to set them to specified coordinates of the window, and always only set one of them visible.


Solution

  • First don't try and mix layouts with setBounds it won't work. Layouts override any bounds you use.

    There are several ways to do this. Probably the most flexible is by using GridLayout which supports excluding controls from the layout.

    For this example I am using this version of your menu class (renamed to MyMenu - please follow the Java coding conventions, class names start with an upper case letter):

    public class MyMenu extends Composite
    {
      public MyMenu(final Composite parent, final String text)
      {
        super(parent, SWT.NONE);
    
        setLayout(new FillLayout());
    
        Button btnAzLicht = new Button(this, SWT.NONE);
        btnAzLicht.setText(text);
      }
    
      @Override
      protected void checkSubclass()
      {
      }
    }
    

    The code to set up the Shell with just myMenu1 showing is:

    shell.setLayout(new GridLayout());
    
    MyMenu myMenu1 = new MyMenu(shell, "Text 1");
    myMenu2.setVisible(true);
    
    GridData data1 = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
    data1.exclude = false;
    myMenu1.setLayoutData(data1);
    
    MyMenu myMenu2 = new MyMenu(shell, "Text 2");
    myMenu2.setVisible(false);
    
    GridData data2 = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
    data2.exclude = true;
    myMenu2.setLayoutData(data1);
    
    MyMenu myMenu3 = new MyMenu(shell, "Text 3");
    myMenu3.setVisible(false);
    
    GridData data3 = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
    data3.exclude = true;
    myMenu3.setLayoutData(data1);
    

    The myMenu2 and myMenu3 controls are set to be not visible and are excluded from the layout.

    To make menu2 show you would do:

    myMenu1.setVisible(false);
    data1.exclude = true;
    
    myMenu2.setVisible(true);
    data2.exclude = false;
    
    shell.layout();
    

    which changes the visible and exclude settings and then calls layout to get the layout recalculated.