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

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