0

我制作了一个生成 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 中的大循环会滞后或冻结我的计算机?有没有办法提高速度?

4

5 回答 5

3

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

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

于 2013-03-31T15:41:40.373 回答
2

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

于 2013-03-31T15:45:58.533 回答
2

Swing 是单线程的。您正在执行一项资源密集型操作以EDT阻止 UI 更新。使用 Swing 的一种并发机制来处理此功能,例如SwingWorker

于 2013-03-31T15:41:57.773 回答
1

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

于 2013-03-31T15:48:25.577 回答
0

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

于 2013-03-31T15:42:41.830 回答