GUI在Java的While循环期间冻结 [英] GUI Freezes During While Loop in Java

查看:76
本文介绍了GUI在Java的While循环期间冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

http://i.stack.imgur.com/XvHm5.png

当我单击打开"按钮时,它将开始在JTextField上发送垃圾邮件1. 而是冻结整个GUI,包括关闭按钮.我使用的是while循环,当您再次单击jButton时,它将停止.因为jButton被冻结,所以我无法停止该程序.我已经读过线程和多线程将有所帮助,但是所有教程都太复杂了,以至于我无法理解.他们说将循环和GUI放在不同的线程上.我想了解这一点,以修复我正在处理的另一个程序,该程序要复杂得多.这就是为什么我举了一个简单的例子来说明我的问题.

When I click the On button it should start spamming 1's across the JTextField. Instead The entire GUI freezes, including the close button. I am using a while loop that will stop when you click the jButton again. Because the jButton is frozen i cannot stop this program. I have read that Threads and Multithreading would help but all of the tutorials are too complex for me to understand. They say to put the loop and GUI on different threads. I want to understand this to fix another program that I am working on which is much more complex. Thats why I made a simple example to show my problem.

http://i.stack.imgur.com/tbNAF.png

这是程序显示的方式. (jTextField甚至都没有更新.我要问的是,是否有人知道解决此问题的方法,无论是否使用线程. 我为此程序编写的代码如下.

This is how the program shows. (The jTextField is not even updated. What I am asking is if someone knows a way to fix this, whether using threads or not. My code for this program is below.

public class whileLoop extends javax.swing.JFrame {
public whileLoop() {
    initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jTextField1 = new javax.swing.JTextField();
    jToggleButton1 = new javax.swing.JToggleButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jToggleButton1.setText("On");
    jToggleButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jToggleButton1ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jToggleButton1)
            .addGap(18, 18, 18)
            .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
            .addContainerGap())
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jToggleButton1))
            .addContainerGap(12, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>

private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    if (jToggleButton1.isSelected()) {
        jToggleButton1.setText("Off");
        while (jToggleButton1.isSelected()) {
            jTextField1.setText(jTextField1.getText() + "1");
        }
    } else {
        jToggleButton1.setText("On");
    }
}
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new whileLoop().setVisible(true);
        }
    });
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JTextField jTextField1;
private javax.swing.JToggleButton jToggleButton1;
// End of variables declaration

}

代码的主要区域是:

private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    if (jToggleButton1.isSelected()) {
        jToggleButton1.setText("Off");
        while (jToggleButton1.isSelected()) {
            jTextField1.setText(jTextField1.getText() + "1");
        }
    } else {
        jToggleButton1.setText("On");
    }
}

推荐答案

您有一个无限循环.设置为true后,切换按钮的状态永远不会改变.

You have an infinite loop. The state of the toggle button is never changed after being set to true.

Java的UI(以及我使用过的所有UI)均由单个线程驱动.用户输入通过该单线程反馈给您.渲染也在此单线程上完成.

Java's UI (and all UI I've worked with) is driven by a single thread. User input is fed back to you on this single thread. Rendering is also done on this single thread.

文本字段从未更新的原因是UI线程再也无法渲染屏幕了,因为它陷入了无限循环.

The reason the textfield is never updated is the UI thread is never getting to render the screen again, as its tied up in your infinite loop.

是的,您需要将此代码放在单独的线程中,并在切换按钮被选中时启动它.然后,您需要从该单独的线程更新文本字段.查看 SwingWorker .

Yes, you need to put this code in a separate thread, and start it when the toggle button becomes selected. Then, you need to update the textfield from this separate thread. Look into SwingWorker.

这篇关于GUI在Java的While循环期间冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆