Tags: 100kb, becomes, files, java, jtextarea, laggy, loads, program, scroll, slow, speed, text
How to speed up JTextArea?
On Java Studio » Java Talk
12,589 words with 19 Comments; publish: Tue, 25 Sep 2007 06:02:00 GMT; (15093.75, « »)
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
http://java-studio.developerfaqs.com/q_java-newer_45119.html
All Comments
Leave a comment...
- 19 Comments

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.
#1; Sun, 15 Jul 2007 00:45:00 GMT

- 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(..)#2; Sun, 15 Jul 2007 00:45:00 GMT

- 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.#3; Sun, 15 Jul 2007 00:45:00 GMT

- I checked the JScrollbar but I could find any method to set the unit increment.#4; Sun, 15 Jul 2007 00:45:00 GMT

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
#5; Sun, 15 Jul 2007 00:45:00 GMT

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());
#6; Sun, 15 Jul 2007 00:45:00 GMT

- 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#7; Sun, 15 Jul 2007 00:45:00 GMT

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.
#8; Sun, 15 Jul 2007 00:45:00 GMT

- Thanks for the code. I'm having trouble running it though. It compiles but doesn't do anything. Is it supposed to do that?#9; Sun, 15 Jul 2007 00:45:00 GMT

- > 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.#10; Sun, 15 Jul 2007 00:45:00 GMT

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();}
});
}
#11; Sun, 15 Jul 2007 00:45:00 GMT

> 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.
#12; Sun, 15 Jul 2007 00:45:00 GMT

- 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.#13; Sun, 15 Jul 2007 00:45:00 GMT

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.
#14; Sun, 15 Jul 2007 00:45:00 GMT

- > 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 #15; Sat, 21 Jul 2007 11:23:00 GMT

- 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?#16; Sat, 21 Jul 2007 11:23:00 GMT

- .java-studio.developerfaqs.com.Op. Just a minor thing (I know that you already have solved your problem), don't invoke System.gc();Kaj#17; Sat, 21 Jul 2007 11:23:00 GMT

> 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".
#18; Sat, 21 Jul 2007 11:23:00 GMT

- Acutally its one line of code to read a file into a text area:textArea.read(...);#19; Sat, 21 Jul 2007 11:23:00 GMT