JTextArea setText(veryLongString)花费了太多时间

时间:2014-05-30 09:22:41

标签: java swing jtextarea

我有一个非常长的字符串,我从书中得到。我使用setText()方法在JTextArea中显示它。它冻结了UI并花费了大量时间。我该如何解决这个问题?

这是SSCCE:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class SSCCE extends JFrame {

    JTextArea textArea;

    public SSCCE() {
        String text = buildLongString(400000);
        textArea = new JTextArea();
        textArea.setText(text);
        textArea.setLineWrap(true);
        add(new JScrollPane(textArea));

        setSize(400, 350);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private String buildLongString(int length) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            builder.append("x");
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SSCCE();
            }
        });
    }

}

2 个答案:

答案 0 :(得分:5)

在单独的线程中创建DefaultStyledDocument以构建GUI似乎是创建大文本区域的最快方法。 DefaultStyledDocument是线程安全的。

这是我用来测试DefaultStyledDocument的代码。我创建了带空格的文本,以便Swing代码换行有机会工作。

package com.ggl.testing;

import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;

public class HugeTextArea implements Runnable {

    private DefaultStyledDocument   document;

    private JFrame                  frame;

    private JTextArea               textArea;

    public HugeTextArea() {
        this.document = new DefaultStyledDocument();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                buildLongString(400000);
            }
        };
        new Thread(runnable).start();
    }

    @Override
    public void run() {
        frame = new JFrame();
        frame.setTitle("Huge Text");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        textArea = new JTextArea(document);
        textArea.setLineWrap(true);
        frame.add(new JScrollPane(textArea));

        frame.setSize(400, 350);
        frame.setLocationRelativeTo(null);

        frame.setVisible(true);
    }

    private void buildLongString(int length) {
        Random random = new Random();
        String[] chars = { "s", "t", "a", "y", " " };
        for (int i = 0; i < length; i++) {
            try {
                document.insertString(document.getLength(),
                        chars[random.nextInt(chars.length)],
                        null);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new HugeTextArea());
    }

}

答案 1 :(得分:0)

我从 setText(..) 块内部调用了方法 invokeLater(...),性能得到了很大的提升

EventQueue.invokeLater(new Runnable()
{
    public void run()
    {
        txt.setText(content);
    }
});