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

发布于 2024-08-18 13:03:45 字数 1312 浏览 3 评论 0原文

这些是我的类。当我运行 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("");
}

these are my classes.when i run my MainClient class,one frame will be shown that get text from client and then send it to the server.at the first time when i click on the Send button,it will work correctly and send data to the server but suddenly the frame will confused and I can not do any thing like writing or clicking on the button!!please help me.

MainClient class:

//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);
}

my gui class which get text from client and by clicking on the send button will send that text to the server:(Send button action performed)

 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("");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三寸金莲 2024-08-25 13:03:45

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 版本。

编辑:当事件调度线程访问 UI 组件 - jTextArea1.setText("") 时,必须在事件调度线程上调用 clear 方法。要使其在 EDT 上运行,请执行以下操作:

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

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

Java 7 中的闭包应该会让这类任务变得不再那么混乱。

The MainClient.active() call is blocking waiting for the Socket to respond. Because it is called in the ActionListener it is blocking the Swing event dispatch thread on which all UI events are triggered. This is causing the UI to be unresponsive.

If you can you should use SwingWorker to perform the blocking task in a background thread. See the documentation here:

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

If SwingWorker is not available then you can do it with something like this:

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();
}

That is an ugly way to do it but it is also the shortest and will work on any version of Java that has Swing.

Edit: The clear method has to be called on the event dispatch thread as it accesses a UI component - jTextArea1.setText(""). To make it run on the EDT do this:

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

Anonymous inner classes are ugly especially when they are inside other anonymous inner classes but they are convenient for code samples. In your actual implementation you should create a class that implements Runnable to do the original background task to make the code more readable.

Closures in Java 7 should make this sort of task a lot less cluttered.

桃气十足 2024-08-25 13:03:45

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

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

另外,关闭您的套接字连接。

c.Close();

I'd bet your problem stems from all the IO objects you didn't close. Try flushing and closing your Reader and Writer objects.

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

Also, close your socket connection.

c.Close();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文