Java – how to read and display large text files in swing?
It may sound a little complicated. I'll try to simplify my requirements
At present, I am using the standard reading method, which uses the BufferedReader instance contained in the jtextarea component What I want to do is load jtextarea and load a certain amount of text on the screen The rest of the screen is loaded in a separate thread in the background
Is it enough to use InputStream and write each character to the array and then write characters to jtextarea? Or should we use different methods? I am trying to implement a fast and effective reading method
Solution
There are two immediate questions at hand
First, you need to read the file in such a way that it can gradually update the UI without causing unacceptable delays
Second, jtextarea's ability to actually handle this amount of data
The first problem is relatively easy to fix You need to make sure that you do not block the event scheduling thread when reading the file, and you only update jtextarea in the context of the event scheduling thread For this reason, swingworker is a good choice, such as
public class FileReaderWorker extends SwingWorker<List<String>,String> { private File file; private JTextArea ta; public FileReaderWorker(File file,JTextArea ta) { this.file = file; this.ta = ta; } public File getFile() { return file; } public JTextArea getTextArea() { return ta; } @Override protected List<String> doInBackground() throws Exception { List<String> contents = new ArrayList<>(256); try (BufferedReader br = new BufferedReader(new FileReader(getFile()))) { String text = null; while ((text = br.readLine()) != null) { // You will want to deal with adding back in the new line characters // here if that is important to you... contents.add(text); publish(text); } } return contents; } @Override protected void done() { try { get(); } catch (InterruptedException | ExecutionException ex) { ex.printStackTrace(); // Handle exception here... } } @Override protected void process(List<String> chunks) { JTextArea ta = getTextArea(); for (String text : chunks) { ta.append(text); } } }
For more information, see concurrency in swing and worker threads and swingworker
PS - you don't need to use list to store content, I just take it as an example
The second problem is much more complex and requires some additional testing to ensure that it is actually a problem, but generally speaking, more than 1MB of content often leads to problems
To do this, you need to be able to manage the JScrollPane, be able to request text blocks backwards and forwards from the file, and try to effectively "fabricate" the process (so that you only need to load the required text, but still make it look like you loaded all the text in the jtextarea)
You can also look at filechannel, which provides better performance than standard Java IO class has more functions, including memory mapping. For beginners, please check reading, writing, and creating files
You can also consider using highly optimized JList or JTable to display large amounts of data This has some limitations because it is expected that a fixed row height will affect performance when changing (dynamic row height), but it may be a suitable alternative