# Chat-Client



## tanzverfuehrung (13. Okt 2011)

also ich habe einen Chat- sErver und einen Chat -Client programmiert!
In swing habe ich alles hinbekommen, jetzt wollte ich versuchen die GUI in SWT zu schreiben.!
was ja eigentlich kein einfluss auf den client und den server hat...
sondern eigentlich müsste ich nur die GUI ändern!

es funktioniert nicht mehr...WIESO?


edit:Also wie ein chat funktioniert weiß ja jeder, man schriebt einen text in ein TextFeld und danach klickt man auf den Button "senden" ..und dann soll der text gesendet werden an den server und in das chat Feld ausgegeben werden!

also wenn ich z.b 123 eingebe und auf den Button klicke,kommt diese consolen ausgabe


netzwerkverbindung steht
gelesen: 123
Exception in thread "ReaderThread" org.eclipse.swt.SWTException: Invalid thread access
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.widgets.Widget.error(Unknown Source)
	at org.eclipse.swt.widgets.Widget.checkWidget(Unknown Source)
	at org.eclipse.swt.widgets.Text.append(Unknown Source)
	at swtChat.ChatClienInSWT$EingehendReader.run(ChatClienInSWT.java:99)
	at java.lang.Thread.run(Thread.java:722)

in meinem Programm java 99 ist:

```
eingehend.append(nachricht + "\n");
```

wieso sollte die zeile nicht funktionieren?!


also die verbindung steht ja, aber irgendwie kann es nicht eingefügt werden!?


```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class ChatServerInSWT {

	ArrayList<PrintWriter> clientAusgabeStröme;

	public class ClientHAndler implements Runnable {
		BufferedReader reader;
		Socket socket;

		public ClientHAndler(Socket clientSocket) {
			try {
				socket = clientSocket;
				InputStreamReader isReader = new InputStreamReader(socket.getInputStream());
				reader = new BufferedReader(isReader);
			}
			catch (IOException e) {
				e.printStackTrace();
				System.out.println("ERROR4");
			}
		}

		@Override
		public void run() {
			String nachricht;
			try {
				while ((nachricht = reader.readLine()) != null) {
					System.out.println("gelesen: " + nachricht);
					esAllenWeitersagen(nachricht);
				}
			}
			catch (IOException e) {
				e.printStackTrace();
				System.out.println("ERROR5");
			}
		}

		private void esAllenWeitersagen(String nachricht) {
			Iterator<PrintWriter> it = clientAusgabeStröme.iterator();
			while (it.hasNext()) {
				try{
				PrintWriter writer = (PrintWriter) it.next();
				writer.println(nachricht);
				writer.flush();}
				catch (Exception e) {
					e.printStackTrace();
					System.out.println("ERROR6");
				}
			}
		}
	}
	public static void main (String[]args){
		ChatServerInSWT chatServer = new ChatServerInSWT();
		chatServer.los();
	}
	private void los() {
	clientAusgabeStröme = new ArrayList();
	try {
		ServerSocket serverSocket  = new ServerSocket(5000);
		while (true) {
			Socket clientSocket = serverSocket.accept();
			PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
			clientAusgabeStröme.add(writer);
			
			Thread t = new Thread(new ClientHAndler(clientSocket));
			t.setName("Thread");
			t.start();
			System.out.println("sie haben eine Verbindung");
		}
	}
	catch (IOException e) {
		e.printStackTrace();
		System.out.println("ERROR7");
	}
	}
}
```


```
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ChatClienInSWT {

	Text eingehend;
	Text ausgehend;
	BufferedReader reader;
	PrintWriter writer;
	Socket socket;

	public static void main(String[] arg) {
		new ChatClienInSWT().los();
	}

	private void los() {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setText("Chat");
		FillLayout layout = new FillLayout();
		layout.type = SWT.VERTICAL;
		shell.setLayout(layout);

		ausgehend = new Text(shell, SWT.SINGLE);

		eingehend = new Text(shell, SWT.MULTI | SWT.V_SCROLL);
		eingehend.setEditable(false);
		// eingehend = new Browser(shell, SWT.MULTI | SWT.V_SCROLL);
		Button button = new Button(shell, SWT.PUSH);
		button.setText("Senden");
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					writer.println(ausgehend.getText());

					writer.flush();
				}
				catch (Exception ex) {
					ex.printStackTrace();
					System.out.println("ERROR1");
				}
				ausgehend.setText("");
			}
		});
		netzwerkEinrichten();
		Thread readerThread = new Thread(new EingehendReader());
		readerThread.setName("ReaderThread");
		readerThread.start();

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

	public void netzwerkEinrichten() {
		try {
			socket = new Socket("192.168.89.25", 5000);
			InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
			reader = new BufferedReader(streamReader);
			writer = new PrintWriter(socket.getOutputStream());
			System.out.println("netzwerkverbindung steht");
		}
		catch (IOException e) {
			e.printStackTrace();
			System.out.println("ERROR2");
		}
	}

	class EingehendReader implements Runnable {

		@Override
		public void run() {
			String nachricht;
			try {
				/** wenn was neues gesendet wurde... */
				while ((nachricht = reader.readLine()) != null) {
					System.out.println("gelesen: " + nachricht);

					/** fügt alle gesendeten NAchrichten in das Text Feld */
					eingehend.append(nachricht + "\n");
				}
			}
			catch (IOException e) {
				e.printStackTrace();
				System.out.println("ERROR3");
			}

		}
	}
}
```

reicht das als erklärung?


----------



## hdi (13. Okt 2011)

> es funktioniert nicht mehr...



Was für eine vorbildliche Fehlerbeschreibung :autsch: Topics, in denen pauschal das gesamte Programm hingeklatscht wird werden hier sowieso recht gern ignoriert. Wenn du dann nicht mal was genaueres dazu sagst kannst du dir das Topic gleich sparen. Also: Wenn du den Fehler schon nicht im Geringsten eingrenzen kannst, dann erkläre uns zumindest den Ist- und Soll-Zustand.


----------



## SlaterB (13. Okt 2011)

arbeite an deiner Art, anderen Informationen vorzuenthalten und genauso daran, es dem Programm dir gegenüber zu erlauben:
> catch (Exception ex) {}
Exceptions immer ausgeben


----------



## tanzverfuehrung (13. Okt 2011)

hdi hat gesagt.:


> Was für eine vorbildliche Fehlerbeschreibung :autsch: Topics, in denen pauschal das gesamte Programm hingeklatscht wird werden hier sowieso recht gern ignoriert. Wenn du dann nicht mal was genaueres dazu sagst kannst du dir das Topic gleich sparen. Also: Wenn du den Fehler schon nicht im Geringsten eingrenzen kannst, dann erkläre uns zumindest den Ist- und Soll-Zustand.




habe nochmal meine Fehlerbeschreibung überarbeitet.hoffe so ist es recht?


----------



## tanzverfuehrung (13. Okt 2011)

liegt es eventuell daran  das ich die falsche Komponente genommen habe?
also in SWING benutze ich für die eigehenden Nachrichten JTextArena
und in SWT  habe ich nun einfach TExt(SWT:MULTI) genommen!
ist das richtig oder muss ich eine andere Komponente nehmen und daran liegt mein fehler?!?!?!?!???:L


----------



## Tomate_Salat (13. Okt 2011)

Versuche es mal mit:

```
//EingehendReader von der ClientKlasse
display.asyncExec(new Runnable() {
    public void run() {
         eingehend.append(nachricht + "\n");
    }
});
```


----------



## hdi (13. Okt 2011)

Die Komponente ist schon richtig. SWT hat dir einen Fehler aufgezeigt, der in deiner Swing-Version wohl auch vorliegt. Du hast es dort nur nie gemerkt. SWT hat ein idiotensicheres Konzept zur Vermeidung von Race Conditions in Verbindung mit dem EDT.

Was der Fehler heißt: Du versucht Code auszuführen, der die GUI beeinflusst (beim append ans Textfeld), und das ganze nicht aus dem EDT heraus. Und das ist in SWT verboten, und wie gesagt in Swing (leider) nicht verboten, aber dort genauso schlecht.

Lösung: Verlagerung des Codes auf den EDT:


```
display.asyncExec(new Runnable(){
     public void run(){
         // dein Code, zB das append an die Textarea
     }
});
```

edit: waah es gibt zuviele user hier  Ich dachte ich bin der einzige der am Vormittag nix besseres zu tun hat

edit2 Um trotzdem noch etwas neues beizutragen: In deiner Swing-Version vom Code würde die Behebung dieses Fehlers (nochmal: Er existiert dort auch!) so aussehen:


```
SwingUtilities.invokeLater(new Runnable(){
     public void run(){
         // dein Code, zB das append an die Textarea
     }
});
```


----------



## Tomate_Salat (13. Okt 2011)

hdi hat gesagt.:


> edit: waah es gibt zuviele user hier  Ich dachte ich bin der einzige der am Vormittag nix besseres zu tun hat



Ok, dann geh ich eben wenn ich unerwünscht bin ueh::joke:


----------



## tanzverfuehrung (13. Okt 2011)

Tomate_Salat hat gesagt.:


> Ok, dann geh ich eben wenn ich unerwünscht bin ueh::joke:



keiner ist im meinen Beiträgen unerwünscht!!!


----------



## Sonecc (13. Okt 2011)

Bitte nicht vergessen das Display zu disposen, nach dem event loop.


----------



## hdi (13. Okt 2011)

Hey, kannst du nicht lesen? Raus mit dir! 

(Ich schreib den Post eig nur um dich darauf hinzuweisen dass du einen derben Grammatikfehler in deiner Signatur hast: it's -> its)


----------



## tanzverfuehrung (13. Okt 2011)

Tomate_Salat hat gesagt.:


> Versuche es mal mit:
> 
> ```
> //EingehendReader von der ClientKlasse
> ...



wo genau soll ich das einfügen???


```
class EingehendReader implements (display.asyncExec(new Runnable() {
```

so ja bestimmt nicht odeR?
also soll ich meine eigene Runnable weglassen(EingehenderReader)???


aber so geht es auch nicht??????

```
Thread readerThread = new Thread(display.asyncExec(new Runnable() {
		@Override
		public void run() {
			String nachricht;
			try {
				/** wenn was neues gesendet wurde... */
				while ((nachricht = reader.readLine()) != null) {
					System.out.println("gelesen: " + nachricht);

					/** fügt alle gesendeten NAchrichten in das Text Feld */
					eingehend.append(nachricht + "\n");
				}
			}
			catch (IOException e) {
				e.printStackTrace();
				System.out.println("ERROR3");
			}

		}
		readerThread.setName("ReaderThread");
		readerThread.start();
		}));
```


tut mir leid aber irgendwie stehe ich aufen schlauch!
oder muss ich eine neues runnable erzeugen!?


edit:


oder meint ihr einfach so
???

```
display.asyncExec(readerThread);
```
einfach meinem readerThread da hinzufügen?


----------



## Tomate_Salat (13. Okt 2011)

Die geposteten Zeilen erstzen einfach diese Zeile:

```
eingehend.append(nachricht + "\n");
```

besser gesagt, du schreibst das display.asyncExec darum. Das hat einfach nur zur folge, dass dieser Aufruf im EDT stattfindet. Also:


```
while (...) {
...
display.asyncExec(...
```

@Hdi: sorry


----------



## hdi (13. Okt 2011)

> so ja bestimmt nicht odeR?


Nein um Gottes Willen^^



> also soll ich meine eigene Runnable weglassen(EingehenderReader)???


Nein, auch nicht



> aber so geht es auch nicht??????


Nöö.

Du solltest mal nach_ anonyme Klasse_ googlen.

Es geht genauso wie es Tomate_Salat gepostet hat.

Aus:

```
eingehend.append(nachricht + "\n");
```

machst du:

```
display.asyncExec(new Runnable() {
    public void run() {
         eingehend.append(nachricht + "\n");
    }
});
```

edit: what the.. ;(


----------



## tanzverfuehrung (13. Okt 2011)

so ich DANKE euch ganz doll♥
hdi und TomatenSalat...fühlt euch ganz fest gedrückt und geknutscht von mir!
haha

ohne euch, wäre ich da glaube nie drauf gekommen!!!!
:toll::applaus:


----------



## hdi (13. Okt 2011)

Bitte. Und wenn du in ein paar Tagen nicht wieder vor einem ähnlichen Problem stehen willst, dann lies dich mal in dieses ganze EDT-Thema ein:

Swing/AWT
SWT


----------

