编类似qq的聊天软件时碰到了个很奇怪的问题
我把出错部分的代码简化了一下附在最后 大家帮我看看说明:
client类是聊天部分的代码
chatGui类是界面(大家不用看)在test类中监听按钮来新建client对象
程序会卡死 聊天界面只显示框架 无法显示文本域 必须用任务管理器来关掉但在test2类中单独新建client对象
不会有问题
源代码:
/////////////////////////////////////
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;public class Test implements ActionListener{
JFrame frame;
JButton button;
public static void main(String[] args) {
new Test();
}

public Test(){
frame = new JFrame();
button = new JButton("TEST");
button.addActionListener(this);
frame.getContentPane().add(button);
frame.setSize(80, 80);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} public void actionPerformed(ActionEvent e) {
new Client("ss",2002);
}
}////////////////////////////////////////////////
public class Test2 {
public static void main(String[] args) {
new Client("JJ",2003);
}
}///////////////////////////////////////////////
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Client {
DatagramPacket recData;
DatagramSocket recSocket;
ChatGui gui;

public Client(String name,int recPort){
gui = new ChatGui(name);
try {
recSocket = new DatagramSocket(recPort);
while (true) {
byte[] recBuffer = new byte[100];
recData = new DatagramPacket(recBuffer, recBuffer.length);
recSocket.receive(recData);
gui.outputArea.append(new String(recData.getData()) + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}///////////////////////////////////////
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ChatGui {
JFrame frame;
JTextArea inputArea;
JTextArea outputArea;
JButton sendButton;
JPanel downPanel;
JPanel sendPanel;
JLabel interLabel;
JPanel interPanel;
public ChatGui(String name){
frame = new JFrame(name);
inputArea = new JTextArea(4,60);
outputArea = new JTextArea(10,60);
sendButton = new JButton("发送");
downPanel = new JPanel();
sendPanel = new JPanel();
interPanel = new JPanel();
inputArea.setLineWrap(true);
frame.setSize(400,300);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sendPanel.setLayout(new BorderLayout());
sendPanel.add(sendButton, BorderLayout.EAST);
downPanel.setLayout(new BorderLayout());
downPanel.add(interPanel, BorderLayout.NORTH);
downPanel.add(inputArea,BorderLayout.CENTER);
downPanel.add(sendPanel,BorderLayout.SOUTH);
frame.add(outputArea,BorderLayout.CENTER);
frame.add(downPanel,BorderLayout.SOUTH);
// 使框架居中
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int x = (screenWidth - frame.getWidth())/2;
int y = (screenHeight - frame.getHeight())/2;
frame.setLocation(x, y);
frame.setVisible(true);
}
}

解决方案 »

  1.   

    发现把client继承thread
    把while循环放到run(){}里面
    就可以了
    不过原来会卡住的原因不是很清楚
    哪位高人指点我一下
      

  2.   

    public void actionPerformed(ActionEvent e) {
    if(e.getSource==button){
    new Client("ss",2002);
    }
    }
      

  3.   

    这个应该就是与swing的机制有关event-dispatching thread:事件分发线程event-dispatching thread是一个执行绘画与事件处理代码的线程,比如paint和actionPerformed方法就会自动在event-dispatching thread中被执行,当actionPerformed中执行流程被阻塞,paint会因为没有被执行而导致界面不刷新http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.htmlSwing的事件处理代码是运行在事件分发线程(event-dispatching thread)之上的
    为什么要这样,因为大部分Swing 对象方法是非线程安全的,如果以多线程方式去调用的话就会造成线程间的干涉与内存不一致错误在事件分发线程中执行就像一个排队机,在上面执行的代码就像一系列排队的任务(大部分任务都是调用事件处理方法,比如ActionListener.actionPerformed,其它任务就可以通过invokeLater或invokeAndWait来安排),任务如果不很快结束的话,就会造成未处理的事件拥堵累积且用户界面也会变得没有响应(事件分发线程也是负责处理GUI drawing的)