JTextArea::append umfangreichen Text in textarea darstellen
-
ich lese ein File ein, das ca. 100 KB groß ist.
Dann berechne ich mit einem internen Algorithmus eine Checksumme, die aus den Zeichen im File gebildet wird. Dazu benötige ich 100000 Rechenschritte.
Bei jedem Rechenschritt soll jetzt eine eigene Zeile in einer TextArea ausgegeben werden. In einer Schleife hänge ich mit append() hänge immer wieder eine neue Zeile mit dem Zwischenergebnis an. (Wenn die Schleife vollständig durchlaufen wurde, möchte ich alle Zeilen auf einmal ausgeben.)
Das dauert natürlich ewig.
Habt Ihr eine Idee, wie ich dieses Problem lösen könnte ? Habs auch schon mit insert() versucht. Das dauert auch lange.
Danke für Antworten.
-
Ich habe das Problem jetzt so gelöst.
Ich gebe nur die ersten 300 und die letzten 100 Zeilen aus.
Das reicht aus, festzustellen, ob das richtige File ausgewählt wurde.Da bin ich von Java schon ein bischen enttäuscht. Mit C++ wäre es kein Problem gewesen, 150000 Zeilen auszugeben, ohne den Rechner auszubremsen.
-
sorry wie soll dir auch jemand helfen wenn du keinen relevanten code postest.
zweitens, davon abgesehen dass das mal nichts mit der verwendeten programmiersprache sondern wohl eher von dem verwendeten toolkit abhängt, und fast noch mehr von deinem code, hab ich kein problem die paar tausend zeilen in ne JTextArea zu schreiben.und drittens noch ein genereller tipp: welcher benutzer soll pberhaupt 150000 zeilen lesen (scrollen :eek) ? wieso extrahierst du nicht einfach die für den benutzer wichtigen informationen...
-
Hallo Benutzername unregistrierter,
danke für Deine kritische Antwort.
Wenn Du meinen Beitrag genau gelesen hättest, hättest Du gesehen, dass ich wie Du es so schön ausdrückst, den wichtigen Text für den Bediener schon "extrahiert" habe.Das Problem ist nicht, die 150000 Zeilen in die TextArea zu schreiben, vielmehr dauert es sehr lange 150000-mal Text an einen bestehenden Text anzuhängen.
-
Wie hängst du den Text an? Wenn du z.B. "area.setText( area.getText() + neuerText )" schreibst, musst du dich über die Geschwindigkeit nicht wundern...
-
ich hänge den Text so an:
for (int i=0; i<laengeBuffer; i++) { alterString= alterString.concat(neuerString); }
Ein angehängter String ist ca. 30 Zeichen lang.
150000-mal werden diese 30 Zeichen angehängt.
-
"concat" legt jedesmal einen neuen String an, nicht so ideal, denn dabei wird ein - nicht kleines - Array kopiert. Ein StringBuffer oder StringBuilder würde z.B. diesen Befehl beschleunigen.
Zu der Gui: wenn man die Ausgabe ein bisschen verzögert, kann man da auch viel gewinnen. Oh ja, es sieht nicht mehr so smooth und toll aus, aber alles kann man nicht haben.
Hier zum Vergleich, mit der schnellen Variante benötige ich (Java 1.6, Laptop) etwa 5 Sekunden um die 150000 Strings zu schreiben:
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Beispiel{ // Anzahl Linien public static final int LENGTH = 150000; public static void main( String[] args ) { // Frame zusammenbasteln... nichts aufregendes hier Frame frame = new Frame(); frame.addWindowListener( new WindowAdapter(){ @Override public void windowClosing( WindowEvent e ) { System.exit( 0 ); } }); final TextArea area = new TextArea(); Button slow = new Button( "Langsam" ); Button fast = new Button( "Schnell" ); slow.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent e ) { new Tester( area, true ).start(); } }); fast.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent e ) { new Tester( area, false ).start(); } }); Panel panel = new Panel( new GridLayout( 1, 2 )); panel.add( slow ); panel.add( fast ); frame.setLayout( new BorderLayout() ); frame.add( area, BorderLayout.CENTER ); frame.add( panel, BorderLayout.SOUTH ); frame.setSize( 500, 200 ); frame.setVisible( true ); } /** * Diese Klasse sammelt Strings und leitet sie weiter an die TextArea. * Das geschieht mit wenigen Millisekunden Verzögerung. * @author Benjamin Sigg */ public static class Flusher implements Runnable{ private StringBuilder buffer = new StringBuilder(); private boolean waiting = true; private TextArea area; public Flusher( TextArea area ){ this.area = area; } public synchronized void append( String string ){ buffer.append( string ); if( waiting ){ waiting = false; EventQueue.invokeLater( this ); } } public synchronized void run() { waiting = true; area.append( buffer.toString() ); buffer.setLength( 0 ); } } /** * Dieses Klasse arbeitet hart... sie generiert Strings. Diese Strings fügt * sie entweder direkt einer TextArea hinzu, oder indirekt über einen * Flusher. */ public static class Tester extends Thread{ private TextArea area; private boolean slow; public Tester( TextArea area, boolean slow ){ this.area = area; this.slow = slow; } @Override public void run() { area.setText( "" ); if( slow ){ for( int i = 1; i <= LENGTH; i++ ){ area.append( "Diese Zeile hat die Nummer " + i + ".\n"); } } else{ Flusher flusher = new Flusher( area ); for( int i = 1; i <= LENGTH; i++ ){ flusher.append( "Diese Zeile hat die Nummer " + i + ".\n"); // Wenn man folgende Zeile einkommentiert, verhält sich der // Code plötzlich wie wenn "slow" auf "true" gesetzt wäre. // Thread.yield(); } } System.out.println( "done" ); } } }
-
Danke JBeni,
ich werde Deine Lösung ausprobieren.
Melde mich dann wieder.Bis dann