# GUI als eigene Klasse oder in die Startklasse?



## wolfgang12 (25. Aug 2010)

Hallo,

soll ich die GUI als eigene Klasse oder in die Startklasse packen?

Ich habe mal als Bsp folgendes gemacht:

Klasse "AUTO":

```
public class Auto {

	String name = "";
	int leistung = 0;
	int laenge = 0;
	int breite = 0;
	
	
	public Auto(String typ, int leistung){
		this.leistung = leistung;
		this.name = typ;
	}
	
	public int getLeistung(){
		return leistung;
	}
	
	public String getName(){
		return name;
	}
}
```

"START"-Klasse:

```
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Start {


	public static void main(String[] args) {


		
		
		Auto bmw = new Auto("BMW", 150);
		
		//GUI
		JFrame meinFrame = new JFrame("Fenster");
		meinFrame.setLayout(null);
		
		JTextField textField = new JTextField();
		textField.setBounds(20,20,50,20);
		textField.setText(bmw.getName());
		
		
		meinFrame.add(textField);
		meinFrame.setSize(300, 300);
		meinFrame.setVisible(true);		
		
		
		}

	}
```


Nun meine Frage:


Lohnt es sich die GUI als eigene Klasse zu machen, sprich nicht direkt in die Startklasse zu packen? Und wie mache ich das dann?

Danke


----------



## Brandenburgerin (25. Aug 2010)

Sowas lohnt sich meiner Meinung nach immer. Du solltest den Code wenigstens in eine extra Methode (like buildGui()) auslagern.


----------



## ARadauer (25. Aug 2010)

eigene Klasse


----------



## w0ddes (25. Aug 2010)

Da ich im Betrieb meistens nach dem MVC-Prinzip meine Programme aufbaue, ist die GUI immer ausgelagert. Das erhöht natürlich zum einen die Übersichtlichkeit aber auch den Arbeitsaufwand ein wenig.

Aber an sich musst du das für dich entscheiden:
Wenn es wirklich nur ne kleine Anwendung für dich zu Hause ist, kannst du's ja ruhig in der Startklasse lassen aber sobald mehrere Leute daran arbeiten oder du es später noc hausbauen willst, bietet sich eine auslagerung natürlich an


----------



## diggaa1984 (25. Aug 2010)

ich würde es aus Prinzip schon immer auslagern und nicht unbedingt zu sparsam sein was neue Klassen angeht, generell erstelle ich für jeden abgeschlossenen Komplex in der GUI eine neue Klasse, seis Logfenster, Editoren, Listenansichten etc.

So weiss ich genau wo ich zu suchen habe, wenn ich Komponente X ändern möchte.


----------



## Bergtroll (25. Aug 2010)

ganz klar auslagen, damit sich schlechte Gewohnheiten gar nicht erst einbürgern


----------



## wolfgang12 (25. Aug 2010)

Kann mir wer noch sagen, wie ich das auslagern? (Am Besten am beispiel des JFrames ganz oben).

Danke euch


----------



## bygones (25. Aug 2010)

```
public class MyFrame {
  private JFrame theFrame;

  public void buildGui() {
     theFrame = new JFrame("...");
     // alles mit theFrame wie in deinem code
    theFrame.setVisible(true);
  }
}
```

und als aufrufer

```
public static void main(String[] args) {
   new MyFrame().buildGui();
}
```


----------



## Tomate_Salat (25. Aug 2010)

bygones hat gesagt.:


> ```
> public class MyFrame {
> private JFrame theFrame;
> 
> ...



Naja würde ich eher so starten:

```
class MyFrame {
  private JFrame theFrame;

  public void buildGui() {
     theFrame = new JFrame("...");
     // alles mit theFrame wie in deinem code
     SwingUtilities.invokeLater(new Runnable()
	 {		
		@Override
		public void run()
		{
			theFrame.setVisible(true);			
		}
	 });
     
  }
}
```

aber ich baue meine GUI auch in einer eigenen Klasse mit eigener Methode zum starten. In die main kommt bei mir nur das Notwendigste.


----------



## wolfgang12 (25. Aug 2010)

bygones hat gesagt.:


> ```
> public class MyFrame {
> private JFrame theFrame;
> 
> ...





Danke so mache ichs. Nur wie benutze cih dann z.B. setText? denn die objekte habe ich ja noch nicht erstellt?!

Danke


----------



## icarus2 (25. Aug 2010)

Eigentlich sollte man ja EventQueue.invokeLater(...) benützen und nicht mehr die SwingUtilities.


----------



## wolfgang12 (25. Aug 2010)

Danke aber das mit den Threads mache ich später 

Es gine doch auch eine statische methode doer?


also:


```
static JFrame meinFrame = new JFrame("Fenster");
	
	public static void buildGui(){
//bla bla
```


Aufruf per 
	
	
	
	





```
MyGui.buildGui();
```


----------



## diggaa1984 (25. Aug 2010)

icarus2 hat gesagt.:


> Eigentlich sollte man ja EventQueue.invokeLater(...) benützen und nicht mehr die SwingUtilities.



hallo, kannst du mir dazu mal ne quelle geben? würde da gern mal nachlesen, mach es bisher auch immer über SwingUtilities.


----------



## XHelp (25. Aug 2010)

wolfgang12 hat gesagt.:


> Es gine doch auch eine statische methode doer?



Theoretisch schon. Macht aber eigentlich wenig Sinn, zumindest mal in der Regel.


----------



## icarus2 (25. Aug 2010)

Hab das von einem Artikel, den ich auf Java World gelesen habe. Wenn ich mich richtig erinnere wird dort erklärt wiso man EventQueue nutzen muss, damit die Swing Applikation threadsicher ist.

Korrigiert mich wenn ich was falsch im Kopf habe... habe den Artikel vor einem Jahr oder so gelesen. Ich glaube auf Seite 5 ganz unten in der "Conclusion" sieht man die Struktur. Aber es lohnt sich einmal den ganzen Artikel zu lesen.


----------



## diggaa1984 (25. Aug 2010)

```
public static void invokeLater(Runnable doRun) {
	EventQueue.invokeLater(doRun);
    }
```

 .. so wie ich es verstanden habe geht es in dem Artikel darum, die GUI von Anfang an in dem EDT zu erzeugen. Die obige Methode seh ich in der SwingUtilities-Klasse .. heisst sie schleift den Aufruf also direkt an die EventQueue weiter.

Ich weiss nicht genau, aber eventuell war das früher noch anders gewesen?! Aber mit der JDK1.6 - Lib die ich grad da hab, ist SwingUtilities.invokeLater identisch zu EventQueue.invokeLater .. aber dennoch ein interessanter Artikel der die Anfänge aufzeigt


----------



## icarus2 (25. Aug 2010)

Hab mir gerade die API angeschaut und es sieht ganz danach aus, als würde SwingUtilities auch funktionieren. Ich habe zumindest nichts finden können, was das Gegenteil beweisen würde.


----------



## Tomate_Salat (25. Aug 2010)

API hat gesagt.:
			
		

> As of 1.3 this method is just a cover for java.awt.EventQueue.invokeLater().



SwingUtilities kannst darf man nehmen, weil es hier das gleiche macht. Ich dachte schon ich wäre im falschen Film ^^


----------



## Bergtroll (25. Aug 2010)

Guuude Wolfgang,

du kannst mit dem einfachen Beispiel starten, aber du solltest sobald wie möglich versuchen zu verstehen, was es mit dem sog. Event Dispatcher Thread auf sich hat und warum dir das kompliziertere Beispiel mit dem SwingUtilities.invokeLater vorgelegt hat, google mal nach Tutorials darüber. Wenn du es nicht machst, wird es dir über kurz oder lang passieren, dass deine Software Fehler wegen race conditions wirf. 

Einstieg: Race Condition ? Wikipedia und die unten aufgeführten Verweise. Das wirst du brauchen, um Tutorials zum GUI Start zu verstehen.

Viele Grüße,
Bergtroll


----------



## hdi (25. Aug 2010)

Ich möchte auch noch nen Tipp abgeben:

Ich würde es vermeiden, eine Operation auf den EDT zu legen, wenn ich mich innerhalb von modularem Code befinde, d.h. in Klassen, die ich später für verschiedene Programme verwenden will.

Meiner Meinung nach sollte sowas immer erst vom jeweiligen Programm an geeigneten Stellen gemacht werden. Ansonsten hat man nie genau den "Überblick" über die EventQueue, wenn sie intern in irgendwelchen Klassen die man benutzt verwendet wird.

Dann fängt man an Code auf den EDT zu legen, der Code auf den EDT legt 

Das alleine ist wohl - wenn auch unnötig - nicht so schlimm. Ein absolutes No-Go ist allerdings imho ein invokeAndWait in modularem Code. Angenommen wir haben ein invokeAndWait in der buildGui() :


```
EventQueue.invokeLater(new Runnable(){
    public void run(){
         new MyFrame().buildGui(); // BOOM! 
    }
});
```

jm2c- keine Ahnung ob ich mit der Ansicht falsch liege? Klar es ist schön wenn eine Klasse möglichst viel kapselt, aber ich finde mit dem EDT sollte sie nicht rumpfuschen.. ueh:


----------



## wolfgang12 (29. Aug 2010)

Nun habe ich die GUI Sachen in eine eigene Klasse gepackt.

Doch wie weise ich z.B. einem TextField per "setText()" Strings zu, die auf Objekten basieren? Also im Beispiel z.B. jTextField1.setText(bmw.getName());


Die Objelkte werden ja erst später instanziert und daher ginge es so nicht direkt in der GUI Klasse, oder?


----------



## hdi (29. Aug 2010)

Macht ja nix - der Compiler hat damit kein Problem.
Damit es zur Laufzeit in so einem Fall nicht zum Fehler kommt musst du das halt überprüfen:


```
if(bwm != null){
    field.setText(bmw.getName());
}
else{
    field.setText("");
}
```


----------

