# Composites ein- und ausblenden



## tuomo (9. Jul 2008)

Hallo Java-Gemeinde,

 ich bin gerade dabei mich in SWT reinzufummel, habe vorher meist mir Swing gearbeitet. Eigentlich dachte ich, so groß kann der Unterschied nicht sein, aber ich wurde eines besseren belehrt.

Ich habe ein LoginComposite geschrieben und möchte das abhängig von einem check-Button anzeigen lassen bzw. ausblenden. Mein Code sieht derzeit so aus:
	
	
	
	





```
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ShowHideLogin {

	public static void main(String[] args) {
	    Display display = new Display();
	    Shell shell = new Shell(display);
	    shell.setLayout(new GridLayout(1, false));
	    
	    Text tTop = new Text(shell, 0);
	    tTop.setText("Text oben");
	    
	    final Button bLogin = new Button (shell, SWT.CHECK);
	    bLogin.setText("ShowLogin");
	    bLogin.addSelectionListener(new SelectionListener() {

			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if (bLogin.getSelection())
					System.out.println("show Login!");
				else System.out.println("Hide Login");
			}
	    	
	    });
	    
	    Group gLogin = new Group(shell, 0);
	    gLogin.setLayout(new GridLayout(1, false));
	    gLogin.setText(" Login ");
	    	new Label(gLogin, SWT.NONE).setText("User:");
	    	Text tUser = new Text(gLogin, 0);
	    	new Label(gLogin, SWT.NONE).setText("Password:");
	    	Text tPassword = new Text(gLogin, 0);
	    
	    Text tBottom = new Text(shell, 0);
	    tBottom.setText("Text unten");

	    shell.pack();
	    shell.open();
	    while (!shell.isDisposed()) {
	      if (!display.readAndDispatch())
	        display.sleep();
	    }
	    display.dispose();
	  }
}
```
Leider weiß ich nicht, wie ich es anstelle, dass ich die LoginGroup invisible bekomm und das untere Textfeld mit nach oben verschoben wird. Vielleicht kann mir ja einer von Euch weiterhelfen. Da ich leider auch nicht weiß, wie sowas überhaupt bei SWT gemacht wird, kann ich auch schlecht danach suchen.

Danke,
Grüße


----------



## Wildcard (9. Jul 2008)

dispose und anschließend layout auf dem Parent.


----------



## tuomo (9. Jul 2008)

Danke.

Aber das ist nur die halbe Wahrheit. 
Das ausblenden funktioniert schon mal, aber wie kann ich es wieder einblenden??


----------



## Wildcard (9. Jul 2008)

Gar nicht, nach dem Dispose ist es weg. Bleibt nur neu erstellen.
Du kannst dir auch mal StackLayout ansehen, das entspricht dem CardLayout von Swing.


----------



## tuomo (9. Jul 2008)

Ich glaube, wenn ein Composite per dispose() "entsorgt" wurde, kann man es schlecht wieder anzeigen/einblenden. 

Hat jemand vielleicht noch eine andere Idee? 
Das muss doch irgendwie realisierbar sein.

P.S.: Na da lag ich ja mit meiner Vermutung (dispose ungünstig) richtig.


----------



## tuomo (9. Jul 2008)

Wie soll das denn mit einem StackLayout gemacht werden? Ich kann mir das ja nicht einmal vorstellen. :bahnhof: Das ist doch das, wo mehrere Composites übereinanderliegen und abwechselnd nach oben "geholt" werden können. Oder verwechsel ich da grad was :?:  :!:


----------



## Wildcard (9. Jul 2008)

Richtig


----------



## tuomo (9. Jul 2008)

Was soll ich nur mit dieser Antwort anfangen???


----------



## Verjigorm (9. Jul 2008)

Wie ein Kartenstapel -> CardLayout


----------



## Wildcard (9. Jul 2008)

Du hast gefragt ob du das richtig verstehst. Ja, das verstehst du richtig.
Es gibt nur die beiden Möglichkeiten um Widgets dynamisch aus und einzublenden. Wenn du etwas noch brauchst, dann StackLayout, wenn nicht, dann disposen.


----------



## tuomo (9. Jul 2008)

Aber wie soll das denn mit dem StackLayout funktionieren? Das StackLayout hat immer die Große des ParentComposite, d.h. selbst wenn es nicht sichtbar (setVisible(false) ist, dann wird dafür trotzdem der Platz "freigehalten". Deswegen verstehe ich nicht, wie mir das StackLayout weiterhelfen kann.


----------



## jupa (9. Jul 2008)

Hallo,

ich glaube du verstehst das Prinzip des Stacklayouts nicht.

Schau dir mal ein Beispiel an:
http://www.java2s.com/Tutorial/Java/0280__SWT/UsingStackLayouts.htm

Das Stacklayout ist wie ein Kartenspiel, eine Karte kann nur oben liegen und ist sichtbar.
Mit Topcontrol wird die gewünschte Karte sichtar gemacht, also in den Vordergrund gesetzt.

Am besten du testest das ganze mal anhand des Beispiels.

Grüsse Patrick


----------



## tuomo (10. Jul 2008)

Okay, ich habs ausprobiert und die drei Buttons werden durchlaufen. Aber ich möchte ja, ein Composite in der Mitte ausblenden und nicht wechseln. Und das Ausblenden sollte so funktionieren, das der Rest, in meinem Bsp. "Text unten" einfach nach rückt. Oder noch schöner wäre eine Komponente wie ein Splitter, der auf ein Doppelklick-Event hin, auf Position 0 und beim nächsten mal wieder auf Position 45 rutscht. Ich hab sowas auch schon mal in Swing gemacht, aber halt eben in Swing. Und ich denke, sowas sollte sich auch (irgendwie) in SWT realisieren lassen.

Für den Fall das ich das mit dem StackLayout immer noch nicht geblickt habe, vielleicht kann mir ja jemand mal das Ding in das obrige Bsp. einbauen. An/Aus is ja alles schon vorbereitet. Steht nur in der Konsole "showLogin"/"hideLogin". Würde mich riesig freuen, wenn das Login verschinden und dann wieder auftauchen würde. So wie wenn ich dispose(); layout(); aufrufe, nur das ich es danach wieder einblenden kann.


----------



## Wildcard (10. Jul 2008)

Was spricht den gegen ein leeres Widget und das eigentliche Widget auf dem Stack. Je nach Bedarf schaltest du um und lässt den Parent layouten.


----------



## tuomo (10. Jul 2008)

Okay, ich hab das jetzt mit dem StackLayout ausprobiert und (auf die Idee bin ich leider nicht von selbst gekommen) will das Login mit einem leeren Composite wechseln, aber es passiert nichts. Was mache ich falsch??
	
	
	
	





```
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ShowHideLoginStackLayout {
	static Shell shell = null;
	static StackLayout lStackLayout = null;
	static Group gLogin = null;
	static Composite lInvisibleComposite = null;
	
	public static void main(String[] args) {
	    Display display = new Display();
	    shell = new Shell(display);
	    shell.setLayout(new GridLayout(1, false));
	    
	    Text tTop = new Text(shell, 0);
	    tTop.setText("Text oben");
	    
	    final Button bLogin = new Button (shell, SWT.CHECK);
	    bLogin.setText("ShowLogin");
	    bLogin.setSelection(true);
	    bLogin.addSelectionListener(new SelectionListener() {
	    	
	    	public void widgetDefaultSelected(SelectionEvent e) {}
	    	
	    	public void widgetSelected(SelectionEvent e) {
	    		if (bLogin.getSelection()){
	    			lStackLayout.topControl = gLogin;
	    			System.out.println("show Login!");
	    		}
	    		else {
	    			lStackLayout.topControl = lInvisibleComposite;
	    			System.out.println("Hide Login");
	    		}
	    		
	    		shell.layout();
	    	}
	    });
	    
	    lStackLayout = new StackLayout();
	    Composite lStackLayoutComposite = new Composite(shell, 0);
	    lStackLayoutComposite.setLayout(lStackLayout);
	    
	    lInvisibleComposite = new Composite(lStackLayoutComposite, 0);
	    
	    gLogin = new Group(lStackLayoutComposite, 0);
	    gLogin.setLayout(new GridLayout(1, false));
	    gLogin.setText(" Login ");
	    	new Label(gLogin, SWT.NONE).setText("User:");
	    	Text tUser = new Text(gLogin, 0);
	    	new Label(gLogin, SWT.NONE).setText("Password:");
	    	Text tPassword = new Text(gLogin, 0);
	    
	    lStackLayout.topControl = gLogin;	
	    
	    Text tBottom = new Text(shell, 0);
	    tBottom.setText("Text unten");
	    

	    shell.pack();
	    shell.open();
	    while (!shell.isDisposed()) {
	      if (!display.readAndDispatch())
	        display.sleep();
	    }
	    display.dispose();
	  }
}
```


----------



## Wildcard (10. Jul 2008)

Auch das: lStackLayoutComposite muss gelayouted werden.


----------



## tuomo (10. Jul 2008)

Und wie?


----------

