# Swing hängt sich auf bei Verbindung zum Server



## Ice (23. Sep 2014)

Hallo,
ich habe ein simples "Tip of the Day" Programm geschrieben,
es funktioniert (oder sollte es zumindest  ) so:
Client sendet Anfrage an Server -> _"Hey Server, gib mir einen Tipp"
_
Dies geschieht per Button (ActionListener)

Der Server hält die verschiedenen Tipps, empfängt Verbindungen von Clients, verwaltet sie und verteilt dann
zufällige Tipps ->_ "Nun mein Junge, hier hast du einen Tipp!"_

Tipp wird auf dem JFrame per JLabel angezeigt, das Design wird per BorderLayout geregelt. 

Ich habs vom Konzept her fertig,
nur leider hängt sich mein Client-Interface (Swing) auf, sobald ich auf mein Button klicke und einen Tipp haben möchte.

Hier sind meine 2 Klassen : 1. Client - 2. Server  

```
import java.util.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;

import javax.swing.*;

public class Client implements ActionListener {
	private BufferedReader reader;
	private Socket socket;
	private JFrame frame;
	private JLabel label;
	private JButton button;
	private JLabel status;
	
	public Client() { } ;

	
	private void connect()
	{
		try
		{	socket = new Socket("localhost", 32000);
			InputStreamReader is = new InputStreamReader(socket.getInputStream());
			reader = new BufferedReader(is);
			if(socket.getInputStream() != null) status.setText("Connected");
			
		} catch(Exception e) 
		{
			e.printStackTrace();
		}
	}
	private void getTip()
	{
		String message;
		try {
			while((message = reader.readLine()) != null)
			{
				label.setText("message");
				System.out.println(message);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}
	void go()
	{
		frame = new JFrame();
		frame.setSize(800,600);
		frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
		label = new JLabel();
		button = new JButton("Get Tip of the Day");
		button.addActionListener(this);
		status = new JLabel();
		status.setText("Not connected");
		frame.getContentPane().add(BorderLayout.CENTER,label);
		frame.getContentPane().add(BorderLayout.SOUTH,button);
		frame.getContentPane().add(BorderLayout.NORTH,status);
		connect();
		frame.setVisible(true);
		
	}


	public void actionPerformed(ActionEvent arg0) {
		getTip();
	}
}
```

2. Klasse: Server

```
import java.net.*;
import java.io.*;
import java.util.*;

public class Server {
	BufferedReader reader;
	Socket a;			//Client
	String[] Tips = {"First Tip", "Never give up", "always be yourself unless you can be Dan Bilzerian!",
						"God loves u!"};
	ArrayList ClientOutputStreams;
	public class ClientHandler implements Runnable
	{
		public ClientHandler(Socket client) 
		{
			a = client;
			try
			{
				InputStreamReader is = new InputStreamReader(a.getInputStream());
				reader = new BufferedReader(is);
			} catch(Exception e)
			{
				System.out.println("Oops, something went wrong with the ClientHandler");
			}
		}

		@Override
		public void run() {
			notifyClient();
		}
	}


	public static void main(String[] args)
	{
		new Server().go();
	}
	private void notifyClient()
	{
		
		Iterator it = ClientOutputStreams.iterator();
		while(it.hasNext())
		{
			try
			{
				PrintWriter writer = (PrintWriter) it.next();
				System.out.println("Before sending a message");
				System.out.println("houston houston , bravo 555 here");
                                writer.print(getTip());
				writer.flush();
				System.out.println("after sending a message");
			} catch(Exception e)
			{
				System.out.println("Oops, something went wrong with notifyClient() -> writers");
			}
		}
		
	}
	
	public void go()
	{
		try
		{
			ClientOutputStreams = new ArrayList();
		ServerSocket ss = new ServerSocket(32000);
		while(true)
		{
			try
			{
				Socket b = ss.accept();
				PrintWriter writer = new PrintWriter(b.getOutputStream());
				System.out.println("Before adding writer");
				
				ClientOutputStreams.add(writer);
				System.out.println("after adding a writer");
				Thread client = new Thread(new ClientHandler(b));
				client.run();
				System.out.println("made a connection");
				
				
				
			} catch(Exception e) 
			{
				System.out.println("There was a mistake at go() son!");
			}
		}
		} catch(Exception e)
		{
			System.out.println("There was an error with creating the Server!");
		}
	}
	public String getATip()
	{
		int x = (int) (Math.random() * Tips.length);
		return Tips[x];
	}
}
```

Zuerst wird der Server gestartet,
dann der Client per einer neuen Klasse mit den folgenden Zeilen:

	try {
			Client a = new Client();
			a.go();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("No such Server!");
		}


BTW: Die ganzen System.out.println's dienen nur als Invariante, die ich bei der Fehleranalyse genutzt habe
Vielen Dank und eisige Grüße vom Ice


----------



## Ice (24. Sep 2014)

Niemand? ^^


----------



## JavaMeister (24. Sep 2014)

Readline ist ein blockierender Aufruf. Den führst du im Edt aus. 

Readline wartet auf eine komplette Zeile, die mit \n beendet wird. Der Server schickt das aber nicht. 

Der edt ist blockiert und kann die GUI nicht zeichnen.


----------



## Gucky (24. Sep 2014)

Und sollten solche Dinge nicht in einen anderen Thread ausgelagert werden? Damit, falls es mal Probleme gibt, sich nicht alles aufhängt?


----------

