# Server / Client Anwendung, Client GUI Probleme



## bobo90 (25. Apr 2010)

Hallo,

ich bin gerade dabei eine Server / Client Anwendung zu schreiben. Soll nichts großes werden, Client sendet eine Anfrage an den Server, dieser Wertet aus, und sendet zurück. Zum Beispiel wird die Zahl 5 geschickt, und Server sendet 6 oder so zurück.

Soweit ist das kein Problem, ich habe beides auf Konsolenbasis. Den Clienten wollte ich doch nun jedoch Grafisch durch eine GUI darstellen. allerdings hapert es da schon. 
Wie sieht der Aufbau aus, also wo muss ich die Socket Anbindung hinschreiben? Da ich mehrere Buttons haben möchte, und diese auf die Funktionen (zum Beispiel output stream) zugreifen, müssten die doch global Definiert werden oder nciht? Oder bin ich nu total auf den Holzweg ?

Ich danke jetzt schonmal für jeden denkanstoß 

Gruß


----------



## _Andi91 (26. Apr 2010)

Ich weis nicht ob ich dich jetzt richtig verstanden habe aber ich würde es so machen:

Für die GUI 2 Klassen. einen View und einen ViewController
Im View "malst" du deine Oberfläche mit den Buttons. Die ViewController Klasse implementiert das Interface ActionListener und deine Buttons registrien sich beim ViewController (bsp jButton.addActionListener(controller)).
In der Methode actionPerformed() im Controller kannst du dann entsprechend die Aktionen behandeln.
Entweder du schreibst die Logik für alle Aktionen direkt in diese Methode oder - besser - du schreibst für jeden (unterschiedlichen) Vorgang eine Methode die dann je nachdem aus der actionPerformed() aufgerufen wird.
Unterscheiden kannst du die Actions mittels des ActionCommands (bei Buttons jButton.setActionCommand, beim ActionEvent event.getActionCommand)

Ich bin jetzt übrigens mal von Swing ausgegangen.


Gruß, Andi


----------



## bobo90 (26. Apr 2010)

okay, danke.. soweit klingt das logisch, aber eine Frage habe ich nmch, wie mache ich das, dass sich die Buttons  beim ViewController registrieren?


----------



## _Andi91 (26. Apr 2010)

über die Methode addActionListener eines JButtons.
Du musst dir dafür die Referenz auf den Controller im View natürlich speichern. Diesen gibst du dann als Übergabeparameter an.


----------



## bobo90 (26. Apr 2010)

also so wie ich das nun verstanden habe, würde ich das so umsetzen:

```
class View 
{
 //zeichne Fenster
}

 class ViewController
{
//Verwalte Methoden
jButton.addActionListener(controller)
}
```


----------



## _Andi91 (26. Apr 2010)

nicht ganz. Ich hab dazu mal ein kleines(!) Beispiel geschrieben:

View:


```
public class View extends JFrame
{
	private static final long serialVersionUID = 8739874783218737794L;
	private ViewController controller = null;
	private JButton button = null;
	
	public View(ViewController controller)
	{
		setController(controller);
		
		init();
	}

	public void setController(ViewController controller) 
	{
		this.controller = controller;
	}
	public ViewController getController() 
	{
		return controller;
	}
	
	private void init()
	{
		//Fenster+Komponenten initialisieren etc.
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JButton button = new JButton("Beschriftung");
		button.setActionCommand("action1");
		button.addActionListener(controller);
		
		add(button);
		
		pack();
	}
}
```


ViewController

```
public class ViewController implements ActionListener
{
	private View view = null;

	public ViewController()
	{
		setView(new View(this));
		
		view.setVisible(true);
	}
	
	public void setView(View view)
	{
		this.view = view;
	}
	public View getView()
	{
		return view;
	}
	
	@Override
	public void actionPerformed(ActionEvent event) 
	{
		if(event.getActionCommand().equals("action1"))
		{
			doHandleAction1();
		}
	}

	private void doHandleAction1() 
	{
		//Hier Aktion bearbeiten
		
		JOptionPane.showMessageDialog(getView(), "Button gedrueckt");
	}
}
```


Klasse um Beispiel Anwendung zu starten:

```
public class AppStart 
{
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		new ViewController();
	}
}
```


----------



## bobo90 (26. Apr 2010)

super, dankeschön das Funktioniert =)

Wenn du mir noch eine Sache verraten könntest ( ich komm grad nicht drauf, allerdings seh ich hute den Wald lauter Bäumen nicht mehr...), wo du alles das Fenster zeichnest. Ich wollte ein neues reinsetzen, das etwas größer ist, und wo ich mehr Buttons reinsetzen kann. Wenn ich die Funktion umprogrammiere, zeichnet er mir immer zwei Fenster....


----------



## _Andi91 (27. Apr 2010)

das Fenster wird nur in der Methode init() in der Klasse View gezeichnet.
Die Methode init() wird im Konstruktor der View Klasse aufgerufen.

Im Konstruktor des ViewControllers wird der View erzeugt(=View Konstruktor Aufruf) und anschließend auf sichtbar gesetzt.


----------



## bobo90 (27. Apr 2010)

ich dumbatz... hatte die Groß / kleinschreibung nicht beachtet, deswegen ging es nicht. 

Also das Fenster malt er mir ganz perfekt, aber ohne Buttons etc. 

add(btnverbinden) funktioniert, allerdings füllt er das Fenster mit einem Button. D.h. der Button wird mit dem Fenster größer.

Verändere ich das add() in View.add(button) um, zeichent er mir das Fenster ohne irgendeinen Inhalt..

Gibt es da spezielle Methoden oder sowas für?
Dankeschonmal =)


```
private void init()
    {
        
        //Fenster+Komponenten initialisieren etc.
        JFrame View = new JFrame("FrameDemo");
        setDefaultCloseOperation(View.EXIT_ON_CLOSE);
        //View.getContentPane().add(btn_verbinden, BorderLayout.CENTER);


        JTextField tfipserver = new JTextField("");
        JButton btnverbinden = new JButton("Verbinden");
        
        //JTextField tf1 = new JTextField("");

        btnverbinden.setActionCommand("action1");
        btnverbinden.addActionListener(controller);
        
       
        add(btnverbinden);
        
        //View.add(btnverbinden);

        pack();
        
    }
```


----------



## _Andi91 (27. Apr 2010)

mh ich glaub du hast da was falsch verstanden.
In der init Methode brauchst du keine neue Instanz von JFrame erzeugen, da die Klasse View bereits von JFrame erbt.
So hast du im Moment 2 Frames wobei dein "View" (Variablen bitte klein am Anfang  ) Frame niemals angezeigt wird, weil kein setVisible(true) erfolgt.

Für die Anordung der Buttons, Textfelder etc. gibt es in Swing sogenannte LayoutManager (bsp. BorderLayout, GridLayout, GridBagLayout etc.)


----------



## bobo90 (27. Apr 2010)

okay... also so wie ich das verstanden habe: Gitter legen, Buttons drauf und fertig ... Rein Theoretisch... 

Danke =) Nach der Prüfung mach ich dann mal weiter. Vielen Dank nochmal


----------



## bobo90 (2. Mai 2010)

vielen dank nochmal für die hilfe  Ich komme bisher ganz gut zurecht, allerdings noch eine Frage, wo ich nicht weiter komme:

Ich habe ein Eingabefeld, und einen Button. In das Feld soll die Adresse des Servers (Standard: 127.0.0.1) und der Button dient zum Verbinden. Die Verbindung bleibt allerdings nur in der Funktion. kann also nicht weiter auf sie zugreifen (Server Socket). 

Bin ich auf den richtigen Weg, wenn ich eine globale Funktion mache, und das dort definiere? Oder liege ich komplett falsch ?


----------

