为什么Java GUI中的大循环滞后/冻结?

时间:2013-03-31 15:37:47

标签: java swing for-loop ascii jtextarea

我制作了一个生成ASCII字符的Java程序。

如果您想尝试以下代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class asciiTable implements ActionListener {
    private static JButton exebouton;
    private JTextArea ecran = new JTextArea();
    private JScrollPane scrollecran = new JScrollPane(ecran);
    String line = "-------------";

    public static void main(String[] args) {
        new asciiTable();
    }

    private asciiTable() {
        // Window
        JFrame frame = new JFrame("Name");
        frame.setBounds(400, 350, 625, 355);
        frame.setLayout(null);

        Container container = frame.getContentPane();

        // Panel
        JPanel panneau = new JPanel();
        panneau.setLayout(null);
        panneau.setBounds(2, 42, 146, 252);
        frame.add(panneau);

        JLabel nglabel = new JLabel("Click");
        nglabel.setBounds(5, 0, 200, 20);
        panneau.add(nglabel);

        // Button
        exebouton = new JButton("Execute");
        exebouton.setBounds(4, 18, 138, 47);
        exebouton.addActionListener(this);
        panneau.add(exebouton);

        // Text Area
        ecran.setEditable(false);
        ecran.setLineWrap(true);
        scrollecran.setBounds(150, 42, 467, 252);
        container.add(scrollecran);

        // Show
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object test = e.getSource();    

        ecran.setText(ecran.getText() + line + '\n'
                    + "[ASCII TABLE]" + '\n'
                    + line + '\n');
        for (int i = 32, j = 0; i <= 800; i++, j++){ // WARNING: Big loop might lag your computer
            String putzero = "";
            if (i < 100){
                putzero = "0";
            }
            if (j >= 5){
                ecran.setText(ecran.getText() + "\n");
                j = 0;
            }
            ecran.setText(ecran.getText() + "[" + putzero + i + "] " + Character.toString ((char) i) + "\t");
        }
        ecran.setText(ecran.getText() + "\n");
    }

}

我的问题是:为什么Java GUI中的大循环滞后或冻结我的计算机?有没有办法提高速度?

5 个答案:

答案 0 :(得分:3)

不应在处理所有事件的线程中执行Swing中的操作。

请参阅http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

答案 1 :(得分:2)

Swing是单线程的。您正在执行EDT阻止UI更新的资源密集型操作。使用Swing的concurrency mechanisms之一来处理此功能,例如SwingWorker

答案 2 :(得分:2)

您在Event Dispatch Thread中循环。在这个主题中,您正在处理GUI绘画,例如在JTextField中设置文本。这会冻结GUI并且不会让任何其他操作在GUI上执行。如果您想执行长任务,那么您应该在单独的工作线程中处理所有此类操作事件,例如SwingWorkerjavax.swing.Timer

答案 3 :(得分:1)

考虑使用工作线程。在线程完成其工作后,您可以使用SwingUtilities.invokeAndWait()或SwingUtilities.invokeLater()方法同步或异步更新UI。传递的Runnable在UI线程中执行,这使您可以更新该线程中的UI。

答案 4 :(得分:0)

因为您正在GUI线程中进行循环。你应该在另一个Thread中处理它,你的GUI不会挂起。