下面的是一个简单的 udp聊天程序,能运行一次,第二次就不可以了 
  
   我想应该是关闭窗口之后有异常,现在我想在加点代码 在关闭后 把ds1也关掉,程序也一起关掉。但运用WindowListener和WindowAdapter不是很会用 ,也就是 不是很了解啊 
下面是代码  有点问题
package UDPchat;
import java.awt.Color;
import java.awt.Container;import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
public class chat extends JFrame implements ActionListener{
public JTextField tip,txx;
public JLabel la1,la2;//la1输入ip,la2输入消息
public JList l1;
public JButton b1;
public DatagramSocket ds1;//接受和发送数据报包的套接字
public DatagramPacket dp1,dp2;//数据报包
public DefaultListModel listmode=new DefaultListModel();
public chat(){
try{
ds1=new DatagramSocket(3001);

}catch(Exception e){
e.printStackTrace();


}
//final DefaultListModel listmode=new DefaultListModel();
new Thread(new Runnable()   //接受信息

public void run(){
while(true){
try{
byte[] bug=new byte[1024];
dp2=new DatagramPacket(bug,bug.length);
ds1.receive(dp2);
String s=new String(bug);
l1.setModel(listmode);
listmode.add(0,s);
}catch(Exception e){
e.printStackTrace();
}
}
}

}).start();

l1 =new JList();
l1.setBounds(10, 10,400, 300);
la1 =new JLabel("IP");
la1.setBounds(10,350, 30, 20);
tip =new JTextField("");
tip.setBounds(70, 350,100 , 20);
la2 =new JLabel("输入消息框");
la2.setBounds(190,350, 80, 20);
txx =new JTextField("",20);
txx.setBounds(280, 350, 100, 20);

b1=new JButton("发送");
b1.setBounds(200, 400, 80, 50);
b1.addActionListener(this);
Container rq=this.getContentPane();
rq.setLayout(null);
rq.add(l1);
rq.add(la1);
rq.add(la2);
rq.add(tip);
rq.add(txx);
rq.add(b1);
this.setTitle("毛毛虫的聊天程序");
this.setSize(420,500);
this.setVisible(true);


}
 public static void main(String[] args){
 chat c=new chat();
 }
     public void actionPerformed(ActionEvent e){
      if(e.getSource()==b1){
      try{                   //发送信息
      byte[] bug;
      bug=txx.getText().getBytes();
      dp1 =new DatagramPacket(bug,bug.length,InetAddress.getByName(tip.getText()),3001);
      ds1.send(dp1);
      }catch(Exception ex){
      ex.printStackTrace();
      }
      }  
      addWindowListener(new WindowListener());//关闭窗口
      class WindowMonitor extends WindowAdapter{
      public void windowClosing(WindowEvent e) {
      
      ds1.close();
      dispose();
      System.exit(0);
      }
      
      }      
      }
     在没加addWindowListener时能运行一次

解决方案 »

  1.   

    一开始代码是这样的package UDPchat;
    import java.awt.Color;
    import java.awt.Container;import javax.swing.*;
    import java.net.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.io.File;
    public class chat extends JFrame implements ActionListener{
    public JTextField tip,txx;
    public JLabel la1,la2;//la1输入ip,la2输入消息
    public JList l1;
    public JButton b1;
    public DatagramSocket ds1;//接受和发送数据报包的套接字
    public DatagramPacket dp1,dp2;//数据报包
    public DefaultListModel listmode=new DefaultListModel();
    //public JScrollPane sc1;
    public chat(){
    try{
    ds1=new DatagramSocket(3008);

    }catch(Exception e){
    e.printStackTrace();


    }
    //final DefaultListModel listmode=new DefaultListModel();
    new Thread(new Runnable()   //接受信息

    public void run(){
    while(true){
    try{
    byte[] bug=new byte[1024];
    dp2=new DatagramPacket(bug,bug.length);
    ds1.receive(dp2);
    String s=new String(bug);
    l1.setModel(listmode);
    listmode.add(0,s);
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }

    }).start();

    l1 =new JList();
    l1.setBounds(10, 10,400, 300);
    //sc1=new JScrollPane(l1);
    //sc1.setBounds(10, 10,400, 300);
    la1 =new JLabel("IP");
    la1.setBounds(10,350, 30, 20);
    tip =new JTextField("");
    tip.setBounds(70, 350,100 , 20);
    la2 =new JLabel("输入消息框");
    la2.setBounds(190,350, 80, 20);
    txx =new JTextField("",20);
    txx.setBounds(280, 350, 100, 20);

    b1=new JButton("发送");
    b1.setBounds(200, 400, 80, 50);
    b1.addActionListener(this);
    Container rq=this.getContentPane();
    rq.setLayout(null);
    //rq.add(sc1);
    rq.add(l1);
    rq.add(la1);
    rq.add(la2);
    rq.add(tip);
    rq.add(txx);
    rq.add(b1);
    this.setTitle("毛毛虫的聊天程序");
    this.setSize(420,500);
    this.setVisible(true);


    }
     public static void main(String[] args){
     chat c=new chat();
     }
         public void actionPerformed(ActionEvent e){
          if(e.getSource()==b1){
          try{                   //发送信息
          byte[] bug;
          bug=txx.getText().getBytes();
          dp1 =new DatagramPacket(bug,bug.length,InetAddress.getByName(tip.getText()),3008);
          ds1.send(dp1);
          }catch(Exception ex){
          ex.printStackTrace();
          }
          }
         }
    }
        
    但只能运行一次  ,  可能是关闭时出了问题
    之后我就加了点代码  addWindowListener(new WindowListener());//关闭窗口
             class WindowMonitor extends WindowAdapter{
                 public void windowClosing(WindowEvent e) {
                     
                     ds1.close();
                     dispose();
                     System.exit(0);
    想点击关闭窗口时关闭程序 
      但这里有问题    其实问题也出在这里加的代码。 
    不知道谁能有好的方法
      

  2.   


    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;import javax.swing.DefaultListModel;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JTextField;
    public class chat extends JFrame implements ActionListener,Runnable{
        public JTextField tip,txx;
        public JLabel la1,la2;//la1输入ip,la2输入消息
        public JList l1;
        public JButton b1;
        public DatagramSocket ds1;//接受和发送数据报包的套接字
        public DatagramPacket dp1,dp2;//数据报包
        public DefaultListModel listmode=new DefaultListModel();
        public chat(){
            try{
                ds1=new DatagramSocket(3001);
                
            }catch(Exception e){
                e.printStackTrace();
                
                
            }
            
            new Thread(this).start();
            
            l1 =new JList();
            l1.setBounds(10, 10,400, 300);
            la1 =new JLabel("IP");
            la1.setBounds(10,350, 30, 20);
            tip =new JTextField("");
            tip.setBounds(70, 350,100 , 20);
            la2 =new JLabel("输入消息框");
            la2.setBounds(190,350, 80, 20);
            txx =new JTextField("",20);
            txx.setBounds(280, 350, 100, 20);
            
            b1=new JButton("发送");
            b1.setBounds(200, 400, 80, 50);
            b1.addActionListener(this);
            Container rq=this.getContentPane();
            rq.setLayout(null);
            rq.add(l1);
            rq.add(la1);
            rq.add(la2);
            rq.add(tip);
            rq.add(txx);
            rq.add(b1);
            this.setTitle("毛毛虫的聊天程序");
            this.setSize(420,500);
            this.setVisible(true);
            
            
        }
        public void run(){
            while(true){
                try{
            byte[] bug=new byte[1024];
            dp2=new DatagramPacket(bug,bug.length);
            ds1.receive(dp2);
            String s=new String(bug);
            l1.setModel(listmode);
            listmode.add(0,s);
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
        
         public static void main(String[] args){
             chat c=new chat();
         }
         public void actionPerformed(ActionEvent e){
             if(e.getSource()==b1){
                 try{                   //发送信息
                     byte[] bug;
                     bug=txx.getText().getBytes();
                     dp1 =new DatagramPacket(bug,bug.length,InetAddress.getByName(tip.getText()),3001);
                     ds1.send(dp1);
                 }catch(Exception ex){
                     ex.printStackTrace();
                 }
             }  
             addWindowListener(new WindowAdapter(){
                 public void windowClosing(WindowEvent e) {
                     System.exit(0);
                 }});
         }
        
    }
      

  3.   

    你原来那种线程启动方式感觉有点怪,所以我改了实现runnable,然后类内启动。
    addWindowListener(new WindowAdapter(){
                 public void windowClosing(WindowEvent e) {
                     System.exit(0);
                 }});
    这个是匿名内部类的用法,简单的退出程序。你原来关闭ds1的话,可以是可以,但是那个时候线程还在走,关闭ds1会造成线程异常,虽然没什么大问题,不过会抛很多异常,简单退出程序就可以了。