Java swing GUI freezes

I am writing a GUI application for a Java client / server using sockets, and here is the problem:

I have a button to start listening to a specific port:

action buttonPerformed

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

Here is the socket.listen method

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

"socket" class extends "Thread"
Therefore, after ss.accept () returns a value, it creates a new instance of the socket in a separate thread.

After clicking the button, the GUI freezes because an infinite loop exists inside the socket.listen method. How can i avoid this?

+4
source share
5 answers

You have two pitfalls in your design:

  • ss.accept() is a blocking call, so your user interface will freeze until an incoming connection appears.
  • Never run while(true) loops in EDT.

Instead, do the following:

  • When the button is pressed, create a stream that starts listening on incoming connections.
  • Whenever you have an incoming connection, create another thread that will accept the incoming client connection and deal with it.
+5
source

bye your

 new socket(ss.accept()); 

returns immediately, you only need to change

 while (true) 

this puts EDT (Thread Dispatch Thread) in an endless loop, and your GUI becomes irresponsible. So delete this line.

If you cannot use the SwingWorker class ( http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List ) Create a nested class that extends SwingWorker. Just call swingWoker.execute (); (after you created your object) in your listenButtonActionPerformed method (java.awt.event.ActionEvent evt).

See the tutorial: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Never create a new thread and start it from Swing EDT

+5
source

You will need multithreading. If I were where you are, I would separate the GUI code and the server code, and when I clicked the button, I just started the server code as a new thread.

Your code freezes the GUI mainly because all events are executed in the Dispatcher thread (EDT) thread, which is the thread that takes care of all your GUI files and related events. If you either lock it, stop it, or throw it in cycles, it will affect its performance.

+3
source

Check this out: http://javarevisited.blogspot.ro/2012/02/what-is-blocking-methods-in-java-and.html

1) If you are writing a graphical application that may be in Swing, never call the lock method in the event manager thread or in the event handler. for example, if you are reading a file or opening a network connection when the button is pressed, do not do this using the actionPerformed () method, instead just create another workflow to do this work and return from actionPerformed (). this will support your GUI, but again it depends on the design, if the operation is what the user needs to wait, than consider using invokeAndWait () for a synchronous update.

Using multiple threads: http://javarevisited.blogspot.ro/2011/02/how-to-implement-thread-in-java.html

+3
source

Try these ...

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..

Here is my server example - communication with the client.

Client 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 Side Code:

 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(); } } 
+2
source

All Articles