# Trennung Gui und Logik - Strukturierte Client Anwendung



## odysseus (11. Jan 2004)

hallo kollegen,
ich programmiere einen Chat Client, sehr simpel vom anfang. ich will eine nette gui mit einem textfeld zum eintippen und einen button zum senden und eine textarea zum empfangen, dazu dann noch eine userliste, etc.

soweit ist das kein problem.
jetzt mein problem:

Ich will sehr strukturiert programmieren, d.h. ich trenne GUI und Logik soweit wie möglich!

*Client.java* ist das Hauptptogramm und instanziert*ClientCommand.java*, welches die Logik enthält, danach wird *ClientGui.java* instanziert und ClientCommand als Objekt übergeben:


```
public class Client {
//client zum connection eines Shirc-Servers ;)
	public static void main(String[] args) {
		//Client starten
		ClientCommand cmd= new ClientCommand();
		//Gui starten
		ClientGui gui = new ClientGui(cmd);		
	}
}
```

siehe Go2Java 2 28.2.3 Variante 3: Trennung von GUI- und Anwendungscode

ClientCommand.java implementiert ActionListener und KeyListener, damit ich Tastaturevents und ButtonEvents abfangen kann.
Empfange ich einen KeyEvent kann ich mit getSource die Gui instanzieren und auf ihre Methoden zugreifen.
Wird ein Button geklickt kann ich die Gui aber nicht instanzieren. getSource bringt mir in diesem Fall nur den Button, aber nicht die Gui.

Wie mache ich das ??




```
package client;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ClientCommand implements Runnable, KeyListener, ActionListener{
//client zum connection eines Shirc-Servers ;)
	public static int port;
	Socket socket;
	DataInputStream in;
	PrintStream out;
	Thread thread;
	
	public ClientCommand(){//konstruktor
		
	}
	
	public void run(){
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
	 */
	
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		[b]Frame f = (Frame)e.getSource();[/b]
		
		if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
			f.setVisible(false);
			f.dispose();
			System.exit(0);
		}
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
	 */
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
	 */
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
			
		[b]//wie komm ich von hier an die gui ??[/b]
		//der source des ActionEvents ist der Button auf der Gui
		
		System.out.println(e.getSource().toString());
		
	}
	
	
}
```

zuletzt die gui, hier registriere ich ClientCommand als ActionListener und KeyListener.


```
package client;
import java.awt.*;
import java.awt.event.*;
public class ClientGui
{
	//zun�chst einmal awt, sp�ter wandel ich es in Swing um
	
	public Frame wnd;
	public Label lblServer;
	public TextField txtServer;
	public TextField txtPort;
	public TextArea taOutputarea;
	public TextField txtInputarea;
	public Button btConnection;
	public Button btSend;
	public Button btQuit;
	public Panel  pnNorth;
	public Panel pnCenter;
	public Panel pnSouth;
	
	static String    font = "SansSerif";
  	static int       style = Font.PLAIN, size = 12;
  
	
	public ClientGui(KeyListener cmd){//konstruktor
		wnd = new Frame("Shirc");
		/*
		wnd.setMenuBar(new MainMenu());
		*/
		//m�glichkeit das fenster zu schliessen
				wnd.addWindowListener(new WindowClosingAdapter(true));
		
		//eigenschaften des fensters
		wnd.setLayout(new BorderLayout(20,20));
		wnd.setBackground(Color.LIGHT_GRAY);
		
		//North Panel
		pnNorth = new Panel();
			//Elemente instantiieren
			lblServer = new Label("Server: ");
			txtServer = new TextField("localhost");
			txtPort = new TextField("8765");
			btConnection = new Button("Connect");
			//cmd ist schon KeyListener, jetzt auch noch ActionListener durch cast !?!?
			btConnection.addActionListener((ActionListener)cmd);
			//Elemente hinzufügen
			pnNorth.add(lblServer);
			pnNorth.add(txtServer);
			pnNorth.add(txtPort);
			pnNorth.add(btConnection);
		
	
		
		//Center Panel
		pnCenter = new Panel();
			//Elemente instantiieren
			taOutputarea = new TextArea(10,40);
			taOutputarea.setBackground(Color.WHITE);
			taOutputarea.setEditable(false);
			taOutputarea.setFont(new Font(font, style, size));
			//Elemente hinzufügen
			pnCenter.add(taOutputarea);

		//South Panel
		pnSouth = new Panel();
			//Elemente instantiieren
			txtInputarea = new TextField(40);
			txtInputarea.setBackground(Color.WHITE);
			txtInputarea.setFont(new Font(font, style, size));
			btSend = new Button("Send");
			//Elemente hinzufügen
			pnSouth.add(txtInputarea);	
			pnSouth.add(btSend);
			btSend.addActionListener((ActionListener)cmd);
			
			
		//Panel hinzufügen
			wnd.add(pnNorth, BorderLayout.NORTH);
			wnd.add(pnCenter, BorderLayout.CENTER);
			wnd.add(pnSouth, BorderLayout.SOUTH);

		wnd.pack();
		//das fenster sichtbar machen
		wnd.setVisible(true);
	
		wnd.addKeyListener(cmd);
	}
}
```

ich bin dankbar für jede hilfe.


----------



## odysseus (11. Jan 2004)

odysseus hat gesagt.:
			
		

> public void actionPerformed(ActionEvent e) {
> // TODO Auto-generated method stub
> 
> *//wie komm ich von hier an die gui ??*
> ...


mit folgendem code erhalte ich eine instanz des buttons der geklickt wurde, und kann dann den button z.b. grün einfärben.


```
public void actionPerformed(ActionEvent e) {
		Button b =	(Button)e.getSource();
		//wie komm ich von hier an die gui ??
		//der source des ActionEvents ist der Button auf der Gui
		
		if(b.getActionCommand() == "Connect"){
			System.out.println("hola ho");
		}
		b.setBackground(Color.GREEN);
		
		System.out.println(e.getSource().toString());
		
	}
```


garnicht mal so schlecht, langsam gefällts mir 

aber, ich mag nicht den ActionCommand abfragen:
*b.getActionCommand() == "Connect"* 

das gefällt mir nicht weil nichts mehr funzen würde wenn ich die Beschriftung des Buttons ändern würde. ich will das Objekt abfragen, also:
*b  == btConnect*  << aber btConnect kennt er hier natürlich nicht ???

jemand einen Vorschlag ??


----------



## odysseus (11. Jan 2004)

ich hab hier glaube ich ein verständnisproblem. hab noch ein bisschen weitergebastelt, und bin jetzt soweit das der client läuft, ständig auf nachrichten vom server wartet und diese dann empfängt. hat der client eine nachricht empfangen, soll er sie natürlich anzeigen in dem er sie an die outputarea anhängt.

abermals die frage wie komme ich von clientCommand an ClientGui heran, denn ich weiss nciht wie ich die Nachricht an die Outputarea anhängen soll.
ich habe ja in clientCommand keinen Verbindung zur Gui ?!?!?


----------



## Kerberus (11. Jan 2004)

Wenn es dich interessiert. Bin auch an einem Messenger am schreiben. (Eigentlich ist er schon fertig. Er braucht einfach noch ein paar Features)
Also, wenn du willst, kann ich dir mal meinen Quellcode schicken.


----------



## odysseus (11. Jan 2004)

ja, wenn Du die trennung zwischen gui und logik drin hast, dann her damit, ich schick Dir ne pm.


----------

