2014-05-30 4 views
2

J'ai une très longue chaîne que je reçois d'un livre. Je l'affiche dans un JTextArea en utilisant la méthode setText(). Il gèle l'interface utilisateur et prend beaucoup de temps. Comment puis-je contourner cela?JTextArea setText (veryLongString) prend trop de temps

est ici comme 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

Vous déposez vraiment 400 000 caractères de texte sur le malheureux utilisateur? Quel est le point de tout cela? –

+0

Je ne vois aucune modification de code requise. – Arijit

+3

Il est intéressant de noter que 'textArea.setLineWrap (true);' (indirectement pas sur appel) prend tout le temps. Mettre le texte là-bas est réellement rapide. BAs un exemple, en concaténant "x", si vous concaténer "x \ n" il devient vraiment rapide. – DSquare

Répondre

5

Création d'un DefaultStyledDocument dans un thread séparé de construire l'interface graphique semble être le meilleur moyen de créer une vaste zone de texte. Un DefaultStyledDocument est thread-safe.

Voici le code que j'ai utilisé pour tester le DefaultStyledDocument. J'ai créé du texte avec des espaces pour que le code Swing to line wrap ait une chance de fonctionner.

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

Comment la méthode d'exécution est appelée? – usama8800

+0

@ usama8800: Quelle méthode d'exécution? –

+0

La deuxième méthode d'exécution. – usama8800