Well a simple approach would be to write a method that reads the 20 MB file (call it myfile.txt) and creates a bunch of new files with names like
myfile_pages/0001.txt
myfile_pages/0002.txt
myfile_pages/0003.txt
...
Each of these files will have some set number of lines of text - 20, 50, 1000, whatever. You can generate them by reading the 20 MB file from a BufferedReader using readLine() and writing each line read to a PrintWriter. Every N lines, close the PrintWriter and replace it with a new PrintWriter which writes to the next file in the sequence.
Call this method before you try to display any pages. You can even use a separate
thread and display the first page once it's complete, before the remaining files have been generated. Or don't even bother generating the remaining files until they're called for - but that's a bit more complex. One step at a time.
I suppose the eventual evolution of this idea would be to create some sort of implementation of javax.swing.text.StyledDocument that reads data from the 20 MB file on demand (perhaps with a cache of some sort) rather than trying to read the whole file first and return a complete Document. (Which is what's happening now.) Then use setDocument() rather than setPage() or setText(). It's even possible someone's already written such a beast, if you can find out who & where. Good luck.