当按下GUI上的X时,Java聊天将停止为未来的客户端工作

当按下GUI上的X时,Java聊天将停止为未来的客户端工作,java,user-interface,server,client,chat,Java,User Interface,Server,Client,Chat,我在这方面遇到了问题,我有服务器-客户端连接工作,任何数量的客户端都可以连接到聊天室并相互发送消息。但是,如果有人通过点击右上角的X退出GUI,那么一切都将转到****并且未来加入的客户端将无法执行任何操作 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; impo

我在这方面遇到了问题,我有服务器-客户端连接工作,任何数量的客户端都可以连接到聊天室并相互发送消息。但是,如果有人通过点击右上角的X退出GUI,那么一切都将转到****并且未来加入的客户端将无法执行任何操作

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

public class ChatC extends JFrame {

//Attributes
private JTextArea msgArea = new JTextArea();
private JTextField input = new JTextField(45);
private JTextArea onlineUsers;
private ArrayList<String> clientNames;
private String clientName = null;
private ObjectOutputStream out;
private Socket client;

/**
 * ChatC constructor
 * Creates an interactive GUI for the user
 * Establishes connection with the server
 */
public ChatC() {

    clientName = JOptionPane.showInputDialog("Enter username:");
    if (clientName == null || clientName.equals("")) clientName = "Guest" + 
    (int) (Math.random() * 200);

    setSize(600, 600);
    setLocationRelativeTo(null);
    setTitle("Welcome to Connect Four chat room,  " + clientName);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);
    setLayout(new BorderLayout());

    JButton sendMsg = new JButton("ENTER");
    getRootPane().setDefaultButton(sendMsg);

    msgArea.setEditable(false);

    JPanel south = new JPanel(new BorderLayout());

    JScrollPane scrollPane = new JScrollPane(msgArea);
    add(scrollPane, BorderLayout.CENTER);

    onlineUsers = new JTextArea();
    onlineUsers.setEditable(false);
    add(onlineUsers, BorderLayout.EAST);
    south.add(input, BorderLayout.WEST);
    south.add(sendMsg, BorderLayout.EAST);
    add(south, BorderLayout.SOUTH);

    JMenu menu = new JMenu("Menu");
    JMenuItem exit = new JMenuItem("Logout");
    menu.add(exit);
    JMenuBar menuBar = new JMenuBar();
    menuBar.add(menu);
    setJMenuBar(menuBar);

    exit.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent ae){

            JOptionPane.showMessageDialog(null, "Thanks for playing Connect Four!", "Farewell", JOptionPane.INFORMATION_MESSAGE);

            try{

                out.writeObject("////" + clientName);
                out.flush();

            }
            catch (IOException e1) {}

        }//end of actionPerformed()

    });//end of anonymous ActionListener

    setVisible(true);

    try{

        client = new Socket("localhost", 16789);
        out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(clientName);

        sendMsg.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent ae){

                if (input.getText() != null && !input.getText().equals("")) {
                    try{

                        out.writeObject(input.getText());
                        out.flush();

                    }//end of try
                    catch (IOException ioe){}

                    input.setText(null);

                }//end of if

            }//end of actionPerformed()

        });//end of anonymous ActionListener

    }//end of try
    catch (UnknownHostException uhe){}
    catch (IOException ioe) {}

    ChatCInner chatInner = new ChatCInner(client);
    chatInner.start();

}//end of ChatC()

/**
 * Main method
 * @param args Project arguments array
 */
public static void main(String[] args) {
    new ChatC();
}

/**
 * Method that displays names of users that are currently participating in the chat room
 */
protected void setOnlineUsers(){

    onlineUsers.setText("Users Online: \n");

    for (Object o : clientNames) {

        onlineUsers.append(o + "\n");

    }//end of for each

}//end of setOnlineUsers()

/**
 * Inner class that functions as a thread for each client
 * Handles user's actions on the GUI and communication with the server
 */
private class ChatCInner extends Thread {

    //Attributes
    Object obj;
    ObjectInputStream in;
    Socket clientC;

    /**
     * ChatCInner constructor
     * @param cl Client socket
     */
    public ChatCInner(Socket cl){

        clientC = cl;

    }//end of ChatCInner()

    /**
     * Method that defines what each thread does
     * Handles client interaction(sending messages etc.)
     */
    public void run() {

        try{

            in = new ObjectInputStream(clientC.getInputStream());

            while ( (obj = in.readObject()) != null ) {

                if (obj instanceof String) {

                    msgArea.append((String) obj);
                    msgArea.setCaretPosition(msgArea.getDocument().getLength());

                }//end of if

                if (obj instanceof ArrayList) {

                    clientNames = (ArrayList<String>) obj;

                    if ( (clientNames.indexOf(clientName) == -1) ) {

                        client.close();
                        System.exit(1);

                    }//end of if
                    else setOnlineUsers();

                }//end of if

            }//end of while loop

        }//end of try
        catch (NullPointerException npe) {}
        catch (IOException ioe) {

            JOptionPane.showMessageDialog(null, "Server was shut down... leaving chat room.", "Server malfunctioning",JOptionPane.WARNING_MESSAGE );
            System.exit(1);

        }
        catch (ClassNotFoundException cnfe) {}

    }//end of run()

}//end of ChatInner class

}//end of ChatC class
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.IOException;
导入java.io.ObjectInputStream;
导入java.io.ObjectOutputStream;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入java.util.ArrayList;
公共类ChatC扩展JFrame{
//属性
私有JTextArea msgArea=新JTextArea();
私有JTextField输入=新的JTextField(45);
私人区域在线用户;
私有ArrayList客户端名称;
私有字符串clientName=null;
私有对象输出流输出;
专用套接字客户端;
/**
*ChatC构造函数
*为用户创建交互式GUI
*建立与服务器的连接
*/
公众谘询委员会({
clientName=JOptionPane.showInputDialog(“输入用户名:”);
如果(clientName==null | | clientName.equals(“”)clientName=“Guest”+
(int)(Math.random()*200);
设置大小(600600);
setLocationRelativeTo(空);
setTitle(“欢迎连接四个聊天室,”+clientName);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
可设置大小(假);
setLayout(新的BorderLayout());
JButton sendMsg=新JButton(“输入”);
getRootPane().setDefaultButton(sendMsg);
msgArea.setEditable(false);
JPanel南部=新JPanel(新边界布局());
JScrollPane scrollPane=新的JScrollPane(msgArea);
添加(滚动窗格,BorderLayout.CENTER);
onlineUsers=新的JTextArea();
onlineUsers.setEditable(false);
添加(在线用户,BorderLayout.EAST);
南部。添加(输入,边界布局。西部);
添加(sendMsg,BorderLayout.EAST);
添加(南部,BorderLayout.south);
JMenu菜单=新JMenu(“菜单”);
JMenuItem退出=新的JMenuItem(“注销”);
菜单。添加(退出);
JMenuBar menuBar=新的JMenuBar();
菜单栏。添加(菜单);
setJMenuBar(菜单栏);
exit.addActionListener(新ActionListener(){
已执行的公共无效行动(行动事件ae){
showMessageDialog(null,“感谢您播放连接四!”,“再见”,JOptionPane.INFORMATION_MESSAGE);
试一试{
out.writeObject(“//”+clientName);
out.flush();
}
catch(IOException e1){}
}//已执行的操作结束()
});//匿名ActionListener的结尾
setVisible(真);
试一试{
client=新套接字(“localhost”,16789);
out=newObjectOutputStream(client.getOutputStream());
out.writeObject(clientName);
addActionListener(新的ActionListener(){
已执行的公共无效行动(行动事件ae){
if(input.getText()!=null&!input.getText().equals(“”){
试一试{
out.writeObject(input.getText());
out.flush();
}//尝试结束
捕获(ioe异常ioe){}
input.setText(空);
}//if结束
}//已执行的操作结束()
});//匿名ActionListener的结尾
}//尝试结束
捕获(未知后异常uhe){}
捕获(ioe异常ioe){}
chatchinner chatInner=新的chatchinner(客户端);
chatInner.start();
}//ChatC()结束
/**
*主要方法
*@param args项目参数数组
*/
公共静态void main(字符串[]args){
新ChatC();
}
/**
*方法,该方法显示当前参与聊天室的用户的名称
*/
受保护的void setOnlineUsers(){
setText(“联机用户:\n”);
for(对象o:clientNames){
onlineUsers.append(o+“\n”);
}//每一个的结束
}//setOnlineUsers()的结尾
/**
*作为每个客户端的线程运行的内部类
*处理用户在GUI上的操作以及与服务器的通信
*/
私有类chatchinner扩展线程{
//属性
对象对象对象;
目标输入流;
插座客户端c;
/**
*查奇纳构造器
*@param cl客户端套接字
*/
公共聊天室(插座cl){
clientC=cl;
}//Chatchinner()的结尾
/**
*方法,该方法定义每个线程的作用
*处理客户端交互(发送消息等)
*/
公开募捐{
试一试{
in=newObjectInputStream(clientC.getInputStream());
而((obj=in.readObject())!=null){
if(字符串的obj实例){
附加((字符串)obj);
msgArea.setCaretPosition(msgArea.getDocument().getLength());
}//if结束
if(数组列表的obj实例){
clientNames=(ArrayList)obj;
if((clientNames.indexOf(clientName)=-1)){
client.close();
系统出口(1);
}//if结束
else setOnlineUsers();
}//if结束
}//while循环结束
}//尝试结束
捕获(NullPointerException npe){}
捕获(ioe异常ioe){
showMessageDialog(null,“服务器已关闭…正在离开聊天室”,“服务器出现故障”,JOptionPane.WARNING_消息);
系统出口(1);
}
catch(ClassNotFoundException cnfe){}
}//运行结束()
}//课堂结束
}//ChatC课程结束
我是客户

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.Vector;

public class ChatS extends JFrame {

//Attributes
private ArrayList<String> clientNames = new ArrayList<>();
private Vector<ObjectOutputStream> outList = new Vector<>();
private Socket client = null;

/**
 * ChatS constructor
 * Build simple GUI with a button to terminate server
 * Establishes connection with clients
 */
public ChatS() {

    setTitle("Server Operational");
    setSize(300, 150);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setLayout(new GridLayout(0, 1));

    JButton stopServer = new JButton("Terminate Server");

    try{

        ServerSocket server = new ServerSocket(16789);

        JLabel localhost = new JLabel(InetAddress.getLocalHost().toString());
        JLabel hostName = new JLabel(InetAddress.getByName("localhost").toString());
        add(localhost);
        add(hostName);

        stopServer.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                System.exit(0);

            }//end of actionPerformed()

        });

        add(stopServer);
        setVisible(true);

        while (true) {

            client = server.accept();
            ChatSInner st = new ChatSInner(client);
            st.start();

        }//end of while loop

    }//end of try
    catch(IOException ioe){}

}//end of ChatS()

/**
 * Main method
 * @param args Project arguments array
 */
public static void main(String[] args){ new ChatS(); }

/**
 * Inner class that functions as a thread
 * Handles user interaction on the chat
 */
public class ChatSInner extends Thread {

    //Attributes
    private int index;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    private Socket clientInner;

    /**
     * ChatSInner constructor
     * Handles clients as separate threads
     * @param cl Socket of the client
     */
    public ChatSInner(Socket cl){

        try {

            clientInner = cl;
            in = new ObjectInputStream(clientInner.getInputStream());
            out = new ObjectOutputStream(clientInner.getOutputStream());
            outList.add(out);

        }//end of try
        catch(IOException ioe){}

    }//end of ChatSInner()

    /**
     * Method to broadcasts message to all clients connected to chat
     * @param msg Message that a client is sharing with everyone
     */
    protected void sendMsg(String msg){

        try {

            for (ObjectOutputStream out2 : outList){

                out2.writeObject(msg + "\n");
                out2.reset();

            }//end of for each

        }//end of try
        catch(IOException ioe){}

    }//end of sendMsg()

    /**
     * Method that sends ArrayList of online users back to each client
     */
    protected void sendArrayList(){

        try{

            for (ObjectOutputStream out2 : outList) {

                out2.writeObject(clientNames);
                out2.reset();

            }//end of for each

        }//end of try
        catch(IOException ioe){}

    }//end of sendArrayList()

    /**
     * Method that defines what each thread does
     * Handles client interaction in the chat room (sending messages etc.)
     */
    public void run() {

        String clientName;

        try{

            Object obj;
            clientName = (String) in.readObject();
            clientNames.add(clientName);
            index = clientNames.indexOf(clientName);

            sendMsg(clientName + " has entered the chat room.\n");
            sendArrayList();

            while ((obj = in.readObject()) != null){

                if (obj instanceof String) {

                    if ( (((String) obj).length() > 4 ) && ( (String) obj).substring(0, 4).equals("////") ){

                        sendMsg(clientNames.get(index) + " has logged out of the chat room.\n");
                        clientNames.remove(clientName);
                        sendArrayList();

                    } //end of if
                    else sendMsg(clientName + ": " + obj);

                }//end of if

            }//end of while loop

        } //end of try
        catch(IOException ioe){}
        catch(ClassNotFoundException cnfe) {}

    }//end of run()

}//end of ChatSInner class

}//end of ChatS class
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.IOException;
导入java.io.ObjectInputStream;
导入java.io.ObjectOutputStream;
导入java.net。*;
导入java.util.ArrayList;
导入java.uti
protected void sendMsg(String msg){
    for (ObjectOutputStream out2 : outList){
        try {//try moved to this line
            out2.writeObject(msg + "\n");
        }//end of try
        out2.reset();//reset even if an error occurs so that the next message sends smoothly
    catch(IOException ioe){} //catch moved to this line
    }//end of for each
}//end of sendMsg()
protected void sendMsg(String msg){
    try {
        for (ObjectOutputStream out2 : outList){
            out2.writeObject(msg + "\n");
            out2.reset();
        }//end of for each
    }//end of try
    catch(IOException ioe){}
}//end of sendMsg()
out2.writeObject(clientNames);
out2.reset();
                if ( (((String) obj).length() > 4 ) && ( (String) obj).substring(0, 4).equals("////") ){

                    //first copy the users name so we can use it in our message:
                    String disconnectedUser = clientNames.get(index);
                    //now remove the disconnected user before you do anything else:
                    clientNames.remove(clientName);
                    //now you can send your message without causing the error because the disconnected client has been removed from the clientName list:
                    sendMsg(clientNames.get(index) + " has logged out of the chat room.\n");

                    sendArrayList();

                } //end of if