Java Swing GUI friert ein

Ich schreibe eine Java-Client / Server-GUI-Anwendung mit Sockets und hier ist das Problem:

Ich habe eine Schaltfläche, um auf einen bestimmten Port zu warten:

Schaltfläche actionPerformed-Methode

private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) { int port = Integer.parseInt(portTextfield.getText(), 10); try { socket.listen(port); } catch (IOException ex) { } } 

Hier ist die Methode socket.listen

 public static void listen() throws IOException { ServerSocket ss = new ServerSocket(port); while (true) new socket(ss.accept()); } 

“Socket” -class erweitert “Thread”
Nachdem ss.accept () einen Wert zurückgegeben hat, wird eine neue Socket-Instanz in einem separaten Thread erstellt.

Nach dem Klicken auf die Schaltfläche friert die GUI ein, da sich innerhalb der socket.listen-Methode eine Endlosschleife befindet. Wie kann ich das vermeiden?

   

Sie haben zwei Fallstricke in Ihrem Design:

  1. ss.accept() ist ein blockierender Aufruf, so dass Ihre Benutzerschnittstelle ss.accept() , wenn eine eingehende Verbindung besteht
  2. Laufen Sie niemals while(true) Schleifen in der EDT.

Stattdessen Folgendes tun:

  • Wenn Sie auf die Schaltfläche klicken, erstellen Sie einen Thread, der auf eingehende Verbindungen wartet.
  • Wenn Sie eine eingehende Verbindung haben, erstellen Sie einen anderen Thread, der die eingehende Clientverbindung übernimmt und damit umgehen kann.

so lange wie du

 new socket(ss.accept()); 

kehrt sofort zurück, Sie müssen nur Ihre ändern

 while (true) 

Dies bringt den EDT (Event Dispatch Thread) in eine Endlosschleife und Ihre GUI reactjs nicht mehr. Also, lösche diese Zeile.

Wenn Sie dann nicht die SwingWorker-class verwenden können ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List )) Erstellen Sie eine geschachtelte class, die expandiert SwingWorker: Rufen Sie einfach eine swingWoker.execute (); (nachdem Sie ihr Objekt erstellt haben) in Ihrer listenButtonActionPerformed (java.awt.event.ActionEvent evt) -Methode auf.

Siehe das Tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Erstellen Sie niemals einen neuen Thread und führen Sie ihn aus dem Swing EDT aus

Sie müssen Multi-Threading verwenden. Wenn ich wo wäre, würde ich den GUI-Code und den Server-Code trennen und wenn die Taste gedrückt wird, starte ich einfach den Server-Code als neuen Thread.

Ihr Code friert die GUI grundsätzlich ein, weil alle Ereignisse auf dem Event Dispatcher Thread (EDT) ausgeführt werden, der der Thread ist, der sich um all Ihre GUI-Sachen und die entsprechenden Ereignisse kümmert. Wenn Sie es entweder blockieren, stoppen oder Schleifen eincasting, wirkt sich das auf die performance aus.

Schau dir das an : http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html

1) Wenn Sie schreiben, GUI-Anwendung möglicherweise in Swing nie Blockierungsmethode im Event-Dispatcher-Thread oder im Event-Handler aufrufen. Wenn Sie zum Beispiel eine Datei lesen oder eine Netzwerkverbindung öffnen, wenn Sie auf eine Schaltfläche klicken, tun Sie dies nicht in der Methode actionPerformed (), sondern erstellen Sie einfach einen anderen Worker-Thread, um diesen Job auszuführen und von actionPerformed () zurückzukehren. Dadurch bleibt Ihre GUI reaktionsfähig, aber auch hier kommt es auf das Design an, wenn die Operation etwas ist, auf das der Benutzer warten muss, anstatt invokeAndWait () für die synchrone Aktualisierung zu verwenden.

Verwenden mehrerer Threads: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html

Probiere diese…

1. During getting the initial connection delay can occur, so first create and empty socket,then try to connect to the server. 1. During getting the initial connection delay can occur, so first create and empty socket,then try to connect to the server.

  `Socket s = new Socket();` `s.connect(new InetSocketAddress("ip_addr",port_nos),1000);` 

2. And Secondly always keep the Non-UI work out of Your UI thread..

Hier ist mein Beispiel für Server – Client Kommunikation.

Clientseitiger Code:

 public class ClientWala { public static void main(String[] args) throws Exception{ Boolean b = true; Socket s = new Socket(); s.connect(new InetSocketAddress("127.0.0.1", 4444),1000); System.out.println("connected: "+s.isConnected()); OutputStream output = s.getOutputStream(); PrintWriter pw = new PrintWriter(output,true); // to write data to server while(b){ if (!b){ System.exit(0); } else { pw.write(new Scanner(System.in).nextLine()); } } // to read data from server InputStream input = s.getInputStream(); InputStreamReader isr = new InputStreamReader(input); BufferedReader br = new BufferedReader(isr); String data = null; while ((data = br.readLine())!=null){ // Print it using sysout, or do whatever you want with the incoming data from server } } } 

Server-Seitencode:

 import java.io.* import java.net.*; public class ServerTest { ServerSocket s; public void go() { try { s = new ServerSocket(44457); while (true) { Socket incoming = s.accept(); Thread t = new Thread(new MyCon(incoming)); t.start(); } } catch (IOException e) { e.printStackTrace(); } } class MyCon implements Runnable { Socket incoming; public MyCon(Socket incoming) { this.incoming = incoming; } @Override public void run() { try { PrintWriter pw = new PrintWriter(incoming.getOutputStream(), true); InputStreamReader isr = new InputStreamReader( incoming.getInputStream()); BufferedReader br = new BufferedReader(isr); String inp = null; boolean isDone = true; System.out.println("TYPE : BYE"); System.out.println(); while (isDone && ((inp = br.readLine()) != null)) { System.out.println(inp); if (inp.trim().equals("BYE")) { System.out .println("THANKS FOR CONNECTING...Bye for now"); isDone = false; s.close(); } } } catch (IOException e) { // TODO Auto-generated catch block try { s.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } e.printStackTrace(); } } } public static void main(String[] args) { new ServerTest().go(); } }