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