170314网络编程之TCP聊天窗口

目录2017-03-14

1.先做一个漂亮的GUI页面

2.DefaultListModel

3.java.net.InetAddress类的使用

4.setPreferredSize的用法

5.Socket中的一些方法(getRemoteSocketAddress())

6.addWindowListener

7.调用时间函数

8.tcpServer.java代码

9.tcp客户端的GUI页面

10.java中@override的含义

11.java中// TODO Auto-generated method stub的含义

12.printStackTrace()//打印堆栈跟踪

13.socket is not bound yet

14.Address already in use: JVM_Bind

15.tcpClient.java代码

1.先做一个漂亮的GUI页面

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;


public class tcpServerGUI extends JFrame{

    JPanel jpbottom,jpfirst,jpsecond,jpthird;
    JScrollPane jspContent;//滚动面板
    JList jlistContent;//显示聊天信息的列表
    JLabel jlblAddress,jlblPort,jlblfriend,jlblsent;
    JTextField  jtxtAddress,jtxtPort,jtxtSent;
    JComboBox<String> jcbfriend;
    JButton jbtListener,jbtSend;
    DefaultListModel<String> dlm=null;//保存聊天记录列表
    boolean isExit=false;
    
    //List<Socket> clientList=new ArrayList<socket>;
    
    public tcpServerGUI(){
                
        //dlm=new DefaultListModel<String>();
        this.setTitle("TCP聊天窗口");//设置窗体标题 this 该类当前的对象
        this.setLocation(200,200);//设置窗体显示的位置
        this.setSize(500,600);//设置大小
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setLayout(new BorderLayout());
                
        jlistContent=new JList();
        jspContent=new JScrollPane(jlistContent);
        this.add(jspContent,BorderLayout.CENTER);
                
        jpbottom=new JPanel();
        jpbottom.setLayout(new GridLayout(3,1));
            
        jpfirst=new JPanel();
        jlblAddress=new JLabel("服务器地址:");
        jtxtAddress=new JTextField(15);
        jlblPort=new JLabel("侦听端口:");
        jtxtPort=new JTextField(5);
        jbtListener=new JButton("开始侦听");
        
        jpfirst.add(jlblAddress);
        jpfirst.add(jtxtAddress);
        jpfirst.add(jlblPort);
        jpfirst.add(jtxtPort);
        jpfirst.add(jbtListener);
        jpbottom.add(jpfirst);
                
        jpsecond=new JPanel();
        jlblfriend=new JLabel("在线好友:");
        jcbfriend=new JComboBox<String>();
        jcbfriend.setPreferredSize(new Dimension(400,20));//??
        //在线好友
        jpsecond.add(jlblfriend);
        jpsecond.add(jcbfriend);
        jpbottom.add(jpsecond);
        
        
        jpthird=new JPanel();
        jlblsent=new JLabel("发送信息:");
        jtxtSent=new JTextField(30);
        jbtSend=new JButton("发送");
        jpthird.add(jlblsent);
        jpthird.add(jtxtSent);
        jpthird.add(jbtSend);
        jpbottom.add(jpthird);
        
        
        this.add(jpbottom,BorderLayout.SOUTH);
        
        this.setVisible(true);
        
    }
    
    public static void main(String[]args){
        new tcpServerGUI();
    }

}

2.DefaultListModel回到目录

使用了defaultListModel可以是列表的可选项是动态改变的!如果不用,列表中只能出现代码中定义的那些可选项。

创建并且设置列表数据模型
DefaultListModel listModel = new DefaultListModel();
listModel.addElement("Jane Doe");
list = new JList(listModel);//将“Rabbit”放到列表中,list为列表框的名字

3.java.net.InetAddress类的使用回到目录

3.1  IP地址是IP使用的32位(IPv4)或者128位(IPv6)位无符号数字,它是传输层协议TCP,UDP的基础。InetAddress是Java对IP地址的封装,在java.net中有许多类都使用到了InetAddress,包括ServerSocket,Socket,DatagramSocket等等。

  InetAddress的实例对象包含以数字形式保存的IP地址,同时还可能包含主机名(如果使用主机名来获取InetAddress的实例,或者使用数字来构造,并且启用了反向主机名解析的功能)。InetAddress类提供了将主机名解析为IP地址(或反之)的方法。

  InetAddress对域名进行解析是使用本地机器配置或者网络命名服务(如域名系统(Domain Name System,DNS)和网络信息服务(Network Information Service,NIS))来实现。对于DNS来说,本地需要向DNS服务器发送查询的请求,然后服务器根据一系列的操作,返回对应的IP地址,为了提高效率,通常本地会缓存一些主机名与IP地址的映射,这样访问相同的地址,就不需要重复发送DNS请求了。在java.net.InetAddress类同样采用了这种策略。在默认情况下,会缓存一段有限时间的映射,对于主机名解析不成功的结果,会缓存非常短的时间(10秒)来提高性能。

String ip=InetAddress.getLocalHost().getHostAddress();

3.2. InetAddress对象的获取

InetAddress的构造函数不是公开的(public),所以需要通过它提供的静态方法来获取,有以下的方法:

static InetAddress[] getAllByName(String host)

static InetAddress getByAddress(byte[] addr)

static InetAddress getByAddress(String host,byte[] addr)

static InetAddress getByName(String host)

static InetAddress getLocalHost()

在这些静态方法中,最为常用的应该是getByName(String host)方法,只需要传入目标主机的名字,InetAddress会尝试做连接DNS服务器,并且获取IP地址的操作。代码片段如下,注意我们假设以下的代码,都是默认导入了java.net中的包,在程序的开头加上import java.net.*,否则需要指定类的全名java.net.InetAddress。

InetAddress address=InetAddress.getByName("www.baidu.com");

4.setPreferredSize的用法回到目录

4.1 setPreferredSize需要在使用布局管理器的时候使用,布局管理器会获取空间的preferredsize,因而可以生效。例如borderlayout在north中放入一个panel,panel的高度可以通过这样实现:panel.setPreferredSize(new Dimension(0, 100));这样就设置了一个高度为100的panel,宽度随窗口变化。

jcbfriend.setPreferredSize(new Dimension(400,20));

4.2 setSize,setLocation,setBounds方法需要在不使用布局管理器的时候使用,也就是setLayout(null)的时候可以使用这三个方法控制布局。
区分好这两个不同点之后,我相信你的布局会更随心所欲。

5.Socket中的一些方法(getRemoteSocketAddress())回到目录

InputStream      getInputStream()     从socket中获取输入流

OutputStream  getOutputStream() 从socket中获取输出流

int              getLocalPort()     获取本地的端口,端口用于监听服务器端的返回值,如果没绑定则为-1

int              getPort()    获取连接的服务器端的连接端口,如果没连接则为0

InetAddress    getInetAddress()      获取另一端的IP地址,toString后为/加上IP地址。

InetAddress    etLocalAddress()      获取本地的IP地址,toString后如:/10.0.11.204

SocketAddress  getRemoteSocketAddress()     获取另一端的IP和端口,toString后如:/10.0.11.204:8808

ScoketAddress  getLocalSocketAddress()    获取本地的IP和端口,toString后如:/10.0.11.204:3513

Int         getReceiveBufferSize() 获取接收端Socket的缓冲大小,默认是8kb.有get就有set。

Boolean    isBound       是否此套接字绑定到本地地址和端口

6.addWindowListener回到目录

WindowListener是java中的接口。主要作用:
用于接收窗口事件的侦听器 接口。
旨在处理窗口事件的类要么实现此 接口(及其包含的所有方法),要么扩展 抽象类 WindowAdapter(仅重写所需的方法)。
然后使用窗口的 addWindowListener 方法将从该类所创建的侦听器对象向该 Window 注册。
当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给该方法。
WindowListener接口所有方法
1)public void windowClosed(WindowEvent e){}
  窗口被完全关闭时调用的方法
2)public void windowDeactivated(WindowEvent e){}
  窗口失去活性时调用的方法
3)public void windowActivated(WindowEvent e){}
  窗口被完全激活时调用的方法
4) public void windowIconified(WindowEvent e){}
  窗口被最小化时调用的方法
5)public void windowDeiconified(WindowEvent e){}
  窗口被从最小化还原时调用的方法
6)public void windowOpened(WindowEvent e){}
  窗口被完全激活时调用的方法
7)public void windowClosing(WindowEvent e){}
  窗口的关闭按钮被点击时调用的方法
this.addWindowListener(new WindowListener(){
@Override
            public void windowClosing(WindowEvent arg0) {
                // TODO Auto-generated method stub
                isExit=true;//让线程有机会退出
                try{
                    if(listenerSocket!=null&&!listenerSocket.isClosed())
                        listenerSocket.close();
                }catch(IOException e1){
                    e1.printStackTrace();
                }
                for(int i=0;i<clientList.size();i++){
                    try{
                        clientList.get(1).close();
                    }catch(IOException e1){
                        e1.printStackTrace();
                    }
                }
            }
}

7.调用时间函数回到目录

Date now=new Date();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String date=dateFormat.format(now);

8.tcpServer.java代码回到目录

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;


public class a extends JFrame {
    JScrollPane jspContent;
    JList jstContent;
    JPanel jpbottom,jpfirst,jpsecond,jpthird;
    JLabel jlbAddress,jlbPort,jlbFriend,jlbInfo;
    JTextField jtxtAddress,jtxtPort,jtxtSend;
    JButton jbListener,jbSend;
    JComboBox <String> jcbfriend;
    
    
    DefaultListModel<String> dlm=null;
    List<Socket> clientList=new ArrayList<Socket>();
    ServerSocket listenerSocket;
    
    boolean isExit=false;
    
    public Socket findClientSocket(String selectClientInfo){
        Socket clientSocket=null;
        for(int i=0;i<clientList.size();i++){
            clientSocket=clientList.get(i);
            String remoteAddress=clientSocket.getRemoteSocketAddress().toString();
            if(remoteAddress.substring(1).equals(selectClientInfo)){
                break;
            }
        }
        return clientSocket;
    }
    
    public a(){
        dlm=new DefaultListModel<String>();
        this.setSize(500,600);
        this.setLocation(100,100);
        this.setTitle("tcp Server");
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setLayout(new BorderLayout());
        
        jstContent=new JList();
        jspContent=new JScrollPane(jstContent);
        this.add(jspContent,BorderLayout.CENTER);
        
        
        
        jpbottom=new JPanel();
        jpbottom.setLayout(new GridLayout(3, 1));
        
        jpfirst=new JPanel();
        jlbAddress=new JLabel("服务器地址:");
        jtxtAddress=new JTextField(15);
        jlbPort=new JLabel("侦听端口:");
        jtxtPort=new JTextField(5);
        jbListener=new JButton("开始侦听");
        
        
        
        jbListener.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                int port=Integer.parseInt(jtxtPort.getText().trim());
                try{
                    listenerSocket=new ServerSocket(port);
                    dlm.addElement(port+"");
                    jstContent.setModel(dlm);
                    new Thread(new Runnable(){

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            while(!isExit){
                                try{
                                    Socket clientSocket=listenerSocket.accept();
                                    clientList.add(clientSocket);
                                    String remoteAddress=clientSocket.getRemoteSocketAddress().toString();
                                    String info=remoteAddress.substring(1);
                                    dlm.addElement(info);
                                    jstContent.setModel(dlm);
                                    
                                    jcbfriend.addItem(remoteAddress.substring(1));
                                    
                                    Thread receiveThread=new ReceiveThread(clientSocket);
                                    receiveThread.start();
                                    
                                }catch(IOException e){
                                    e.printStackTrace();
                                    break;
                                }
                                
                            }
                        }
                    
                        
                        
                    }).start();;
                }catch(IOException e1){
                    
                }
                
            }
            
            
        });
        jpfirst.add(jlbAddress);
        jpfirst.add(jtxtAddress);
        jpfirst.add(jlbPort);
        jpfirst.add(jtxtPort);
        jpfirst.add(jbListener);
        jpbottom.add(jpfirst);
        
        jpsecond=new JPanel();
        
        jlbFriend=new JLabel("在线好友:");
        jcbfriend=new JComboBox<String>();
        jcbfriend.setPreferredSize(new Dimension(400, 20));
        
        jpsecond.add(jlbFriend);
        jpsecond.add(jcbfriend);
        jpbottom.add(jpsecond);
        
        
        jpthird=new JPanel();
        jlbInfo=new JLabel("发送信息:");
        jtxtSend=new JTextField(30);
        jbSend=new JButton("发送");
        
        jbSend.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                String sendInfo=jtxtSend.getText().trim();
                String selectClientInfo=jcbfriend.getSelectedItem().toString();
                Socket clientSocket=findClientSocket(selectClientInfo);
                try{
                    PrintWriter out=new PrintWriter(clientSocket.getOutputStream());
                    out.println(sendInfo);
                    out.flush();
                    
                }catch(IOException e){
                    
                }
            }
            
            
        });
        
        jpthird.add(jlbInfo);
        jpthird.add(jtxtSend);
        jpthird.add(jbSend);
        
        jpbottom.add(jpthird);
        
        
        this.add(jpbottom, BorderLayout.SOUTH);
        
        this.setVisible(true);
        
        this.addWindowListener(new WindowListener() {

            @Override
            public void windowActivated(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowClosed(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowClosing(WindowEvent arg0) {
                // TODO Auto-generated method stub
                isExit=true;
                try{
                    if(listenerSocket!=null&&!listenerSocket.isClosed())
                        listenerSocket.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
                
                for(int i=0;i<clientList.size();i++){
                    try{
                        clientList.get(i).close();
                    }catch(IOException e1){
                        e1.printStackTrace();
                    }
                }
            }

            @Override
            public void windowDeactivated(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowDeiconified(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowIconified(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowOpened(WindowEvent arg0) {
                // TODO Auto-generated method stub
                
            }
            
        });
        
        try{
            String ip=InetAddress.getLocalHost().getHostAddress();
            jtxtAddress.setText(ip);
            jtxtPort.setText(8000+"");
            
        }catch(UnknownHostException e){
            e.printStackTrace();
        }
        
        
        
        
        
        
    }
    
    public static void main(String[] args){
        new a();
        
    }
    class ReceiveThread extends Thread{
        private Socket clientSocket;
        public ReceiveThread(Socket clientSocket){
            this.clientSocket=clientSocket;
        }
        public void run(){
            try{
                BufferedReader in=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                while(!isExit){
                    String info = in.readLine();
                    dlm.addElement(info);
                    jstContent.setModel(dlm);
                }
            }catch(IOException e ){
                e.printStackTrace();
            }
            
        }
        
    }
    
    

}

9.tcp客户端的GUI页面回到目录

  1 import java.awt.BorderLayout;
  2 import java.awt.GridLayout;
  3 import java.awt.event.WindowEvent;
  4 import java.awt.event.WindowListener;
  5 
  6 import javax.swing.*;
  7 
  8 public class tcpClient extends JFrame{
  9     JPanel jpbottom,jpfirst,jpsecond,jpthird;
 10     JList jlistContent;
 11     JScrollPane jspContent;
 12     JLabel jlbAddress,jlbPort,jlbSend;
 13     JTextField jtxtAddress,jtxtPort,jtxtSend;
 14     JButton jbConnect,jbSend;
 15     public tcpClient(){
 16         this.setLocation(200,200);
 17         this.setSize(500,600);
 18         this.setLayout(new BorderLayout());
 19         this.setTitle("tcp客户端程序");
 20         this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 21         
 22         jlistContent=new JList();
 23         jspContent=new JScrollPane(jlistContent);
 24         this.add(jspContent,BorderLayout.CENTER);
 25         
 26         jpbottom=new JPanel();
 27         jpbottom.setLayout(new GridLayout(3,1));
 28         
 29         jpfirst=new JPanel();
 30         jlbAddress=new JLabel("服务器地址:");
 31         jlbPort=new JLabel("服务器端口:");
 32         jbConnect=new JButton("连接");
 33         jtxtAddress=new JTextField(15);
 34         jtxtPort=new JTextField(5);
 35         jpfirst.add(jlbAddress);
 36         jpfirst.add(jtxtAddress);
 37         jpfirst.add(jlbPort);
 38         jpfirst.add(jtxtPort);
 39         jpfirst.add(jbConnect);
 40         jpbottom.add(jpfirst);
 41         
 42         jpsecond=new JPanel();
 43         jlbSend=new JLabel("发送信息:");
 44         jtxtSend=new JTextField(30);
 45         jbSend=new JButton("发送");
 46         jpsecond.add(jlbSend);
 47         jpsecond.add(jtxtSend);
 48         jpsecond.add(jbSend);
 49         jpbottom.add(jpsecond);
 50         
 51         this.add(jpbottom,BorderLayout.SOUTH);
 52         
 53         this.addWindowListener(new WindowListener(){
 54 
 55             @Override
 56             public void windowOpened(WindowEvent e) {
 57                 // TODO Auto-generated method stub
 58                 
 59             }
 60 
 61             @Override
 62             public void windowClosing(WindowEvent e) {
 63                 // TODO Auto-generated method stub
 64                 
 65             }
 66 
 67             @Override
 68             public void windowClosed(WindowEvent e) {
 69                 // TODO Auto-generated method stub
 70                 
 71             }
 72 
 73             @Override
 74             public void windowIconified(WindowEvent e) {
 75                 // TODO Auto-generated method stub
 76                 
 77             }
 78 
 79             @Override
 80             public void windowDeiconified(WindowEvent e) {
 81                 // TODO Auto-generated method stub
 82                 
 83             }
 84 
 85             @Override
 86             public void windowActivated(WindowEvent e) {
 87                 // TODO Auto-generated method stub
 88                 
 89             }
 90 
 91             @Override
 92             public void windowDeactivated(WindowEvent e) {
 93                 // TODO Auto-generated method stub
 94                 
 95             }
 96         });
 97         
 98         
 99         this.setVisible(true);
100     }
101     public static void main(String[]args){
102         new tcpClient();
103     }
104     
105 }

10.java中@override的含义回到目录

@Override是伪代码,表示重写(当然不写也可以)
建议写上,有如下好处:
1、可以当注释用,方便阅读;
2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错,比如你如果没写@Override而你下面的方法名又写错了,这时你的编译器是可以通过的(它以为这个方法是你的子类中自己增加的方法)。

11.java中// TODO Auto-generated method stub的含义回到目录

这是在你用eclipse这样的Java集成开发环境是开发环境自动帮你写的,意思是告诉你这些代码是自动生成的,不是你自己写的,就是一个提示的作用,没大作用

12.printStackTrace()//打印堆栈跟踪回到目录

catch(Exception e){
e.printStackTrace() ;
}
当try语句中出现异常是时,会执行catch中的语句,java运行时系统会自动将catch括号中的Exception e 初始化,也就是实例化Exception类型的对象。e是此对象引用名称。然后e(引用)会自动调用Exception类中指定的方法,也就出现了e.printStackTrace() ;。
printStackTrace()方法的意思是:在命令行打印异常信息在程序中出错的位置及原因。(这是白话解释,比较容易理解)

13.socket is not bound yet回到目录

套接字尚未绑定

14.Address already in use: JVM_Bind回到目录

JVM已经被占用了。

结束在运行的其他java项目?????

15.tcpClient.java代码回到目录

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.*;


public class b extends JFrame{
    JList<String> jlist;
    JScrollPane jsp;
    JPanel jp1,jp2,jp3;
    JLabel jbl1,jbl2,jbl3,jbl4,jbl5;
    JTextField jtx,jtxIP,jtxPort;
    JButton jbSend,jbConnect;
    Socket clientSocket=null;
    BufferedReader in=null;
    PrintWriter out=null;
    boolean isExit=false;
    DefaultListModel<String> dlm=null;
    public static void main(String[] args){
        new b();
    }
    public b(){
        dlm=new DefaultListModel<String>();
        this.setSize(500,600);//大小
        this.setTitle("聊天窗体");
        this.setLocation(100, 100);//显示位置
        this.setLayout(new BorderLayout());//布局
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);//关闭操作
        jlist=new JList<String>();
        jsp=new JScrollPane(jlist);
        this.add(jsp,BorderLayout.CENTER);
        jp1=new JPanel();
        jp1.setLayout(new GridLayout(3,1));
        
        jp2=new JPanel();
        jbl1=new JLabel("服务器地址:");
        jbl2=new JLabel("服务器端口:");
        jtxIP=new JTextField(15);
        jtxPort=new JTextField(5);
        jbConnect=new JButton("连接");
        jbConnect.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                try{
                    clientSocket=new Socket("127.0.0.1",8000);
                    in=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    out=new PrintWriter(clientSocket.getOutputStream());
                    new Thread(new Runnable(){

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            while(!isExit){
                                String str;
                                try{
                                    str=in.readLine();
                                    dlm.addElement("收到服务器发过来的信息:"+str);
                                    jlist.setModel(dlm);
                                    
                                }catch(IOException e){
                                    e.printStackTrace();
                                    break;
                                }
                                
                            }
                        }
                        
                    }).start();
                }catch(UnknownHostException e1){
                    e1.printStackTrace();
                }catch(IOException e2){
                    e2.printStackTrace();
                }
            }
            
        });
        jp2.add(jbl1);
        jp2.add(jtxIP);
        jp2.add(jbl2);
        jp2.add(jtxPort);
        jp2.add(jbConnect);
        jp1.add(jp2);
        
        jp3=new JPanel();
        jbl3=new JLabel("发送信息:");
        jtx=new JTextField(30);
        jbSend=new JButton("发送");
        
        jbSend.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                out.println(jtx.getText().trim());
                out.flush();
                
            }
            
        });
        
        jp3.add(jbl3);
        jp3.add(jtx);
        jp3.add(jbSend);
        jp1.add(jp3);
        this.add(jp1,BorderLayout.SOUTH);
        this.addWindowListener(new WindowListener() {

            @Override
            public void windowOpened(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowClosing(WindowEvent e) {
                // TODO Auto-generated method stub
                isExit=true;
                try{
                    in.close();
                    out.close();
                    clientSocket.close();
                }catch(IOException e3){
                    e3.printStackTrace();
                }
            }

            @Override
            public void windowClosed(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowIconified(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowActivated(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                // TODO Auto-generated method stub
                
            }
            
        });
        this.setVisible(true);
    }

}

原文地址:https://www.cnblogs.com/liao13160678112/p/6550002.html