JTextArea setText(veryLongString) 花费太多时间

问题描述 投票:0回答:3

我有一条很长的绳子,是从书上得到的。我使用 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();
            }
        });
    }

}
java swing jtextarea
3个回答
5
投票
在构建 GUI 的单独线程中创建

DefaultStyledDocument 似乎是创建巨大文本区域的最快方法。 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()); } }
    

0
投票
我从

setText(..)

块内部调用方法
invokeLater(...)
,性能提高了很多

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

0
投票
无论您如何使用它,JTextArea 在显示大量文本(例如日志文件查看器)时都非常慢。对于速度快几个数量级的解决方案,请尝试使用

JList 而不是 JTextArea

,请参阅 
长字符串时 Swing 非常慢

© www.soinside.com 2019 - 2024. All rights reserved.