为什么框架会混淆!! [:-)]

时间:2010-01-15 20:21:38

标签: java swing networking

这些是我的类。当我运行我的MainClient类时,将显示一个框架,从客户端获取文本,然后将其发送到服务器。第一次单击“发送”按钮时,它将正常工作,发送数据到服务器,但突然框架会混淆,我不能做任何事情,如写或点击按钮!!请帮助我。

MainClient类:

//these are in the main(String[] args)

MainFrame farme = new MainFrame();
farme.setVisible(true);
c = new Socket("localhost", 5050);

os = new PrintWriter(c.getOutputStream(), true);
is = new BufferedReader(new InputStreamReader(c.getInputStream()));

//this method is not in the main(String[] args)
public static void active() {

    String teXt = MainClient.getText();
    System.out.println(teXt);
    os.println(teXt);
    String line = is.readLine();
    System.out.println("Text received: " + line);
}

我的gui类从客户端获取文本并单击发送按钮将该文本发送到服务器:(执行发送按钮操作)

 public ChatFrame(InformationClass client) {
    initComponents();


    jButton1.setEnabled(false);
    this.client = client;
    jTextArea2.setText("");

}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    submit();
    clear();
}
private void submit() {
    String text = jTextArea1.getText();

    jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
    MainClient.setText(client.getCurrentName() + " : " + text + "\n");
    MainClient.active();
}

private void clear() {
    jTextArea1.setText("");
}

2 个答案:

答案 0 :(得分:3)

MainClient.active()调用阻止等待Socket响应。因为它在ActionListener中被调用,所以它阻止了触发所有UI事件的Swing事件调度线程。这导致UI无响应。

如果可以,您应该使用SwingWorker在后台线程中执行阻止任务。请参阅此处的文档:

http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

如果SwingWorker不可用,那么你可以这样做:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            // This gets run in a background thread
            String text = jTextArea1.getText();
            jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
            MainClient.setText(client.getCurrentName() + " : " + text + "\n");
            MainClient.active();
        }
    }).start();
}

这是一种丑陋的方式,但它也是最短的,并且适用于任何具有Swing的Java版本。

编辑:必须在事件调度线程上调用clear方法,因为它访问UI组件 - jTextArea1.setText(“”)。要让它在EDT上运行,请执行以下操作:

SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
        clear();
    } 
});

匿名内部类很难看,特别是当它们在其他匿名内部类中时,但它们对代码示例很方便。在实际实现中,您应该创建一个实现Runnable的类来执行原始后台任务,以使代码更具可读性。

Java 7中的闭包应该使这类任务变得更加混乱。

答案 1 :(得分:0)

我敢打赌你的问题源于你没有关闭的所有IO对象。尝试刷新并关闭Reader和Writer对象。

os.Flush();
os.Close();
is.Flush();
is.Close();

另外,关闭套接字连接。

c.Close();