How to speed up JTextArea?

Hi, I have a program that loads text files into a JTextArea. I've noticed that if the files are over 100KB it becomes very laggy and slow to scroll through it. Is there a setting to speed it up, or a different component that may be more suitable for this. Thanks in advance
[281 byte] By [ganninaa] at [2007-10-3 6:02:25]
# 1

What is being slow: loading the files? or moving through them once they're

loaded? or both?

100Kb files wouldn't be considered big - either to load or to use. Perhaps you

could post some code to illustrate the problem. Just post a small, but

compilable, example. Use the [code]code tags[/code] around your

code.

pbrockway2a at 2007-7-15 0:44:37 > top of Java-index,Java Essentials,New To Java...
# 2
if you are talking about the scroll is slow when clicking on the scrollbar's arrow buttons,get the scrollpane's scrollbar and setUnitIncrement(50) //50 is anything you wantif clicking in the track is also too slow, usesetBlockIncrement(..)
Michael_Dunna at 2007-7-15 0:44:37 > top of Java-index,Java Essentials,New To Java...
# 3
It is slow initializing the JTextArea (I'm using the read() method to read in a file stream). It is also slow to scroll. I'll try changing the increment setting.
ganninaa at 2007-7-15 0:44:37 > top of Java-index,Java Essentials,New To Java...
# 4
I checked the JScrollbar but I could find any method to set the unit increment.
ganninaa at 2007-7-15 0:44:37 > top of Java-index,Java Essentials,New To Java...
# 5

try

{

String line;

for(File file: loadMultipleFiles)

{

reader = new BufferedReader(new FileReader(file));

while((line = reader.readLine()) != null)

{

stringBuilder.append(line);

}

stringBuilder.append("\n");

reader.close();

System.gc();

}

String words;

words = stringBuilder.substring(0, stringBuilder.length() - 1);

stringReader = new StringReader(words);

ui.inputArea.read(stringReader, null);

}

Message was edited by:

gannina

ganninaa at 2007-7-15 0:44:37 > top of Java-index,Java Essentials,New To Java...
# 6

If inputArea is a JTextArea and stringBuilder is a StringBuilder, you can

dispense with words and stringReader and just say// remove trailing new line

stringBuilder.deleteCharAt(stringBuilder.length() - 1);

// set JTextArea's content

ui.inputArea.setText(stringBuilder.toString());

pbrockway2a at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 7
Thanks for the coding tip :) To load a 221KB file into the JTextArea still takes a very long time (roughly 20 seconds), and it is nearly impossible to scroll through it.Message was edited by: gannina
ganninaa at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 8

Compare what you're doing with the following. I load a 2Mb file in 906ms.import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.util.Date;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.SwingUtilities;

public class TextAreaEg extends JFrame {

private JTextArea ta;

private static File[] loadMultipleFiles;

public TextAreaEg(String title) {

super(title);

ta = new JTextArea();

add(new JScrollPane(ta), BorderLayout.CENTER);

JButton but = new JButton("Click me!");

but.addActionListener(doTest);

add(but, BorderLayout.SOUTH);

}

private ActionListener doTest = new ActionListener() {

public void actionPerformed(ActionEvent evt) {

long start = new Date().getTime();

try {

StringBuilder stringBuilder = new StringBuilder();

for(File file: loadMultipleFiles) {

BufferedReader reader = new BufferedReader(new FileReader(file));

String line;

while((line = reader.readLine()) != null) {

stringBuilder.append(line);

stringBuilder.append("\n");

}

reader.close();

}

stringBuilder.deleteCharAt(stringBuilder.length() - 1);

ta.setText(stringBuilder.toString());

} catch(Exception e) {

e.printStackTrace();

}

long now = new Date().getTime();

setTitle("Took " + (now - start) + "ms");

}

};

public static void main(String[] args) {

loadMultipleFiles = new File[] {new File("test.txt")};

SwingUtilities.invokeLater(new Runnable() {

public void run() {createAndShowGUI();}

});

}

private static void createAndShowGUI() {

JFrame.setDefaultLookAndFeelDecorated(true);

TextAreaEg app = new TextAreaEg("How Long?");

app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

app.pack();

app.setVisible(true);

}

}

Note: I have moved the line that appends a new line inside the while-loop where,

I guess, it belongs.

pbrockway2a at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 9
Thanks for the code. I'm having trouble running it though. It compiles but doesn't do anything. Is it supposed to do that?
ganninaa at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 10
> It compiles but doesn't do anything.It displays a JFrame containing a JTextArea and JButton. Whether the buttondoes anything (useful) depends on having a file called "test.txt" in the directoryfrom which you launch the program.
pbrockway2a at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 11

for this code. Can I put that in my main, so it's not inside my GUI class? When I put it in my class with the GUI it wants me to convert everyting to static methods and then the variables get messed up.

public static void main(String[] args) {

loadMultipleFiles = new File[] {new File("test.txt")};

SwingUtilities.invokeLater(new Runnable() {

public void run() {createAndShowGUI();}

});

}

ganninaa at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 12

> Can I put that in my main, so it's not inside my GUI class?

I haven't seen your main() method, so I don't know! But I doubt that random

stuff can be pasted into it with any productive consequence. What I posted was

designed to merely be compiled, then run. How depends on whatever

operating system and (I suspect) IDE you are using.

Alternatively, compare the try-block I used in the doTest listener with what you

posted before. There are three differences: eliminating the substring() call, not

using a StringReader and appending a newline between every line that you

read. All three can be incorporated into your code.

pbrockway2a at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 13
Wow, your program is a 1000x faster then mine... I'm not sure why mine is going so slow. The loading file part is nearly identical, it just that swingutilities method I didn't have. I added it to my program but it didn't make any difference.
ganninaa at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 14

My last post sort of "crossed" with yours.

> Wow, your program is a 1000x faster then mine... I'm not sure why mine is

> going so slow.

I guess you got what I posted to run.

OK, so now the hard bit starts. What I posted is at least an encouragement

(and a justification for what I said right at the start - that 100K isn't big).

(1) Have a look at the three things I mentioned in my last post and see if you

can incorporate them into your try-block. After having understood what they

do

(2) If you have no luck, you may have to post a compilable example of what

you are doing. Ie something others can reconstruct. Obviously nobody

wants 500 lines of code! Just a small example that shows the behaviour

you are trying to avoid. Creating a small example is not trivial and takes

time. However it can be very instructive and will help pinpoint (for you)

whatever it is that is causing the load to be so slow.

pbrockway2a at 2007-7-15 0:44:38 > top of Java-index,Java Essentials,New To Java...
# 15
> The loading file part is nearly identical, It was meant to be.> it just that swingutilities method I didn't have.That is just fluff - it seems to be the recommended way of launching anapplication. I could be wrong, but I don't think you problem lies
pbrockway2a at 2007-7-21 11:23:14 > top of Java-index,Java Essentials,New To Java...
# 16
It works! Thank you so much! That appended "\n" in the loop made all the difference. With it I can load huge files and scroll them without a problem without it is super slow. Why does that make such a big difference?
ganninaa at 2007-7-21 11:23:14 > top of Java-index,Java Essentials,New To Java...
# 17
@Op. Just a minor thing (I know that you already have solved your problem), don't invoke System.gc();Kaj
kajbja at 2007-7-21 11:23:14 > top of Java-index,Java Essentials,New To Java...
# 18

> It works! Thank you so much!

Great! You're welcome.

> Why does that make such a big difference?

The contents of a JTextArea can change (obviously). Behind the scenes this

means that there must be some mechanism for allowing inserts and

deletes without having to move huge amounts of data around.

One approach would be to keep the data in a linked list of smallish

"chunks". That way an insert or delete would only involve the particular

chunk that the data is in. I think (but am too lazy to look up) that the Swing

text components do some such thing, and that the actual strategy used can

be changed. In any case having a H - U - G - E string with no newlines

upsets this mechanism.

kajbj is right about not using gc() ... that was change number 4 I made to

your try-block. Basically the rule about gc() is just "don't".

pbrockway2a at 2007-7-21 11:23:14 > top of Java-index,Java Essentials,New To Java...
# 19
Acutally its one line of code to read a file into a text area:textArea.read(...);
camickra at 2007-7-21 11:23:14 > top of Java-index,Java Essentials,New To Java...