【问题标题】:Java Graphical User Interface is FreezingJava 图形用户界面正在冻结
【发布时间】:2012-02-23 03:15:02
【问题描述】:

为什么当我点击 Enter 时执行我的程序时我的应用程序冻结了?

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import java.io.*;
import java.net.*;

public class KnockKnockUI{

      private Socket kkSocket = null;
      private PrintWriter out = null;
      private BufferedReader in = null;
      JTextArea clientArea;
      JTextArea serverArea;
    public KnockKnockUI(){

        establishConnection();
        initComponents();

    }

    public void initComponents(){

        JFrame frame = new JFrame("Chat");
        frame.setVisible(true);
        frame.setSize(320,189);
        frame.getContentPane().setLayout(null);

        serverArea = new JTextArea();
        serverArea.setLineWrap(true);
        serverArea.setBounds(10, 11, 284, 45);
        frame.getContentPane().add(serverArea);

        clientArea = new JTextArea();
        clientArea.setBounds(10, 67, 284, 46);
        frame.getContentPane().add(clientArea);

        JButton btnEnter = new JButton("Enter");
        btnEnter.setBounds(96, 124, 89, 23);
        frame.getContentPane().add(btnEnter);

        btnEnter.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try{
                    in.readLine();
                }catch(Exception e){

                }
                String fromUser = clientArea.getText();
                try {
                    fromUser = in.readLine();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                serverArea.setText(fromUser);
            }
        });

    }

    public void establishConnection(){

         //Establishes Connection
         try {
            kkSocket = new Socket("localhost", 4444);
            //
            out = new PrintWriter(kkSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: taranis.");
            System.exit(1);
        }

    }
    public static void main(String[] args){
        KnockKnockUI ui = new KnockKnockUI();
    }
}

这是一个使用 Java 的简单聊天客户端,还有其他类我没有包括在内。比如Server类和Protocol类

【问题讨论】:

  • 你如何调试这个?请向我们展示您遇到的异常情况。
  • 你需要一个单独的线程来监听套接字。
  • 与眼前的问题无关,但永远不要这样做}catch(Exception e){},尤其是在不工作的代码中。而是做类似 this }catch(Exception e){e.printStackTrace();}.

标签: java swing user-interface concurrency event-dispatching


【解决方案1】:

当你回车时,会执行以下操作:

try {
    in.readLine();
} catch (Exception e) {
}

String fromUser = clientArea.getText();

try {
    fromUser = in.readLine();
} catch (IOException e) {
    e.printStackTrace();
}

serverArea.setText(fromUser);

这段代码正在Event Dispatch Thread 上执行,它处理所有 Swing 事件。您对in.readLine() 的调用将阻塞,直到您的Socket 有一行输入可用,导致未处理的事件备份,从而导致您的程序变得无响应。如果您想执行一项耗时的任务,请查看SwingWorker (SwingWorker tutorial)。

旁注:捕获Exception 而不打印其堆栈跟踪几乎总是一个坏主意。它会使您的代码出现问题,即使不是不可能,也更难发现。

【讨论】:

  • 你能给我什么建议/解决办法来解决这个问题?
  • @user962206 看看SwingWorker,以及我帖子中的教程。
  • @use962206 因为对in.readLine() 的调用会阻塞,直到它们完成。他们可能会在您拨打电话后立即或 20 分钟后返回,甚至可能永远不会。
【解决方案2】:

下面frame的setSize表示添加所有组件后

public void initComponents(){

    JFrame frame = new JFrame("Chat");

    frame.getContentPane().setLayout(null);

    serverArea = new JTextArea();
    serverArea.setLineWrap(true);
    serverArea.setBounds(10, 11, 284, 45);
    frame.getContentPane().add(serverArea);

    clientArea = new JTextArea();
    clientArea.setBounds(10, 67, 284, 46);
    frame.getContentPane().add(clientArea);

    JButton btnEnter = new JButton("Enter");
    btnEnter.setBounds(96, 124, 89, 23);
    frame.getContentPane().add(btnEnter);

    btnEnter.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            try{
                in.readLine();
            }catch(Exception e){

            }
            String fromUser = clientArea.getText();
            try {
                fromUser = in.readLine();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            serverArea.setText(fromUser);
        }
    });

   frame.setVisible(true);
    frame.setSize(320,189);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-22
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多