0

I'm writing a simply chat client and am moving it over to a nice GUI. The constructor for the server side (client side is android) contains a list that's in the JFrame, and the first part of the server runs, but then the entire frame locks up. Does anyone see the issue? Sorry for the relatively disorganized, not cleanly commented code... Server:

    import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;


public class ChatServer {

    private final int CHAT_PORT = 4453;
    ServerSocket sSocket;
    Socket cSocket;
    PrintWriter pWriter;
    BufferedReader bReader;
    InetAddress localAddr;
    List messageList;

    public ChatServer(List entList)
    {
        messageList = entList;
    }

    public synchronized void run()
    {
        messageList.add("Chat Server Starting...");
        try {
            localAddr = InetAddress.getLocalHost();
        } catch (UnknownHostException e1) {
            messageList.add("InnetAddress error");
        }
        while(true)
        {
            try {
                sSocket = new ServerSocket(CHAT_PORT);
                sSocket.setReuseAddress(true);
                messageList.add("Server has IP:" + localAddr.getHostAddress());
                messageList.add("Server has hostname:" + localAddr.getHostName());
                messageList.add("Server has port:" + CHAT_PORT);
            } catch (IOException e) {
                //ERRORS
                if(cSocket.isConnected())
                {
                    messageList.add("User disconnected\n");
                    try {
                        cSocket.close();
                    } catch (IOException e1) {
                        messageList.add("Error closing client socket");
                    }
                }
                else
                {
                    messageList.add("ERROR CREATING SOCKET\n");
                }
            }

            try {
                cSocket = sSocket.accept();
                cSocket.setReuseAddress(true);
                messageList.add("INFO: socket connected");
            } catch (IOException e) {
                messageList.add("Client Socket Error");
                System.exit(-1);
            }

            try {
                pWriter = new PrintWriter(cSocket.getOutputStream(), true);
                messageList.add("INFO: Print writer opened");
            } catch (IOException e) {
                messageList.add("PrintWriter error");
            }

            try {
                bReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
                messageList.add("INFO: buffered reader opened");
            } catch (IOException e) {
                messageList.add("BufferedReader error");
            }

            String inputLine;

            try {
                while((inputLine = bReader.readLine()) != null)
                {
                    messageList.add(inputLine);
                    if(inputLine.equals("close"))
                    {
                        close();
                    }
                }
            } catch (IOException e) {
                messageList.add("Buffered Reader error");
            }
        }

    }


    public synchronized void close()
    {
        messageList.add("****Server closing****");
        try {
            sSocket.close();
        } catch (IOException e) {
            messageList.add("Error closing server socket");
        }

        try {
            cSocket.close();
        } catch (IOException e) {
            messageList.add("Error closing client socket");
        }

        pWriter.close();


        try {
            bReader.close();
        } catch (IOException e) {
            messageList.add("Error closing buffered reader");
        }
        messageList.add("****It's been fun, but I've got to go.****\n****Server has shut down.****");
        System.exit(0);
    }

}

GUI:

    import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.List;
import java.awt.Toolkit;


@SuppressWarnings("serial")
public class ClientGUI extends JFrame {

    private JPanel contentPane;
    private JTextField txtEnterTextHere;
    private JMenuBar menuBar;
    private List messageList;
    private JMenu mnOptions;
    private JMenu mnHelp;
    private JMenuItem mntmStartServer;
    private JMenuItem mntmStopServer;
    private JMenuItem mntmConnectionInfo;
    private JMenuItem mntmEmailDeveloper;
    private static String userName;
    private ChatServer cServer;


    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ClientGUI frame = new ClientGUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ClientGUI() {
        setTitle("Ben's Chat Client");
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);

        menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu mnFile = new JMenu("File");
        menuBar.add(mnFile);

        JMenuItem mntmExit = new JMenuItem("Exit");
        mntmExit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?");
            }



        });
        mnFile.add(mntmExit);

        mnOptions = new JMenu("Options");
        menuBar.add(mnOptions);

        mntmStartServer = new JMenuItem("Start Server");
        mntmStartServer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                ChatServer cServer = new ChatServer(messageList);   
                cServer.run();
            }
        });
        mnOptions.add(mntmStartServer);

        mntmStopServer = new JMenuItem("Stop Server");
        mnOptions.add(mntmStopServer);

        mntmConnectionInfo = new JMenuItem("Connection Info");
        mnOptions.add(mntmConnectionInfo);

        mnHelp = new JMenu("Help");
        menuBar.add(mnHelp);

        mntmEmailDeveloper = new JMenuItem("Email Developer");
        mnHelp.add(mntmEmailDeveloper);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        txtEnterTextHere = new JTextField();
        txtEnterTextHere.setBounds(10, 220, 334, 20);
        txtEnterTextHere.setText("Enter text here...");
        contentPane.add(txtEnterTextHere);
        txtEnterTextHere.setColumns(10);

        JButton btnSend = new JButton("Send");
        btnSend.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                messageList.add(userName + ": " + txtEnterTextHere.getText().toString());
            }
        });

        messageList = new List();   
        btnSend.setBounds(349, 219, 85, 23);
        contentPane.add(btnSend);
        messageList.setBounds(10, 10, 424, 204);
        contentPane.add(messageList);

    }

    public static String getUsername()
    {
        return userName;
    }

    public static void setUsername(String entName)
    {
        userName = entName;
    }
}

Thanks!

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
bensherms
  • 83
  • 2
  • 14

1 Answers1

3

It looks like you're starting the server on the Swing thread (see: The Event Dispatch Thread). As soon as you call cServer.run(); in the ActionListener, you are blocking the EDT from doing anything else (such as updating your JFrame and responding to events). Start your server in a background thread instead:

new Thread(new Runnable()
{
  @Override
  public void run()
  {
    // start your server
  }
}).start();
DannyMo
  • 11,344
  • 4
  • 31
  • 37