我有一本书得很长。我使用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(); } }); } }
在与构造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()); } }