Search code examples
javaswinguser-interfaceconcurrencyevent-dispatching

Java Graphical User Interface is Freezing


Why is it that when I execute my Program when I click Enter my Application freezes?

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import java.io.*;
import java.net.*;

public class KnockKnockUI{

      private Socket kkSocket = null;
      private PrintWriter out = null;
      private BufferedReader in = null;
      JTextArea clientArea;
      JTextArea serverArea;
    public KnockKnockUI(){

        establishConnection();
        initComponents();

    }

    public void initComponents(){

        JFrame frame = new JFrame("Chat");
        frame.setVisible(true);
        frame.setSize(320,189);
        frame.getContentPane().setLayout(null);

        serverArea = new JTextArea();
        serverArea.setLineWrap(true);
        serverArea.setBounds(10, 11, 284, 45);
        frame.getContentPane().add(serverArea);

        clientArea = new JTextArea();
        clientArea.setBounds(10, 67, 284, 46);
        frame.getContentPane().add(clientArea);

        JButton btnEnter = new JButton("Enter");
        btnEnter.setBounds(96, 124, 89, 23);
        frame.getContentPane().add(btnEnter);

        btnEnter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try{
                    in.readLine();
                }catch(Exception e){

                }
                String fromUser = clientArea.getText();
                try {
                    fromUser = in.readLine();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                serverArea.setText(fromUser);
            }
        });

    }

    public void establishConnection(){

         //Establishes Connection
         try {
            kkSocket = new Socket("localhost", 4444);
            //
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: taranis.");
            System.exit(1);
        }

    }
    public static void main(String[] args){
        KnockKnockUI ui = new KnockKnockUI();
    }
}

This is a simple chat client using Java, there are other classes that I didn't include. like The Server class and the Protocol class


Solution

  • When you hit enter, the following is executed:

    try {
        in.readLine();
    } catch (Exception e) {
    }
    
    String fromUser = clientArea.getText();
    
    try {
        fromUser = in.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    serverArea.setText(fromUser);
    

    This chunk of code is being performed on the Event Dispatch Thread, which handles all Swing events. Your calls to in.readLine() will block until a line of input is available from your Socket, causing unhandled events to back up and thus causing your program to become unresponsive. If you want to perform a time expensive task, take a look at a SwingWorker (SwingWorker tutorial).

    Side note: Catching an Exception without printing its stack trace is almost always a bad idea. It can make problems with your code harder, if not impossible, to catch.