This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Swing / AWT / SWT and the fly likes Problem with JTextPane setDocument blocking the GUI Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Problem with JTextPane setDocument blocking the GUI" Watch "Problem with JTextPane setDocument blocking the GUI" New topic
Author

Problem with JTextPane setDocument blocking the GUI

Jean-Claude Dauphin
Greenhorn

Joined: Nov 14, 2012
Posts: 3
I don't know if you can help but in case ! We have spend a lot of time on this issue, trying different methods but without success.

We have a problem with JTextPane when loading big documents (>1.5 GB) with setDocument method. We get the following NetBeans message:

WARNING [org.netbeans.core.TimableEventQueue]: too much time in AWT thread null

And it takes lot of time before getting the text JTextPane content displayed and the hand back. We would like at least to inform the user of what is going on.

The process is done in a SwingWorker as follow:



We may have missed some trivial setting or coding, thanks in advance for your precious time.

Best,

JCD
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19672
    
  18

You're setting the entire document each time. The text pane actually throws away everything it has and rebuilds the entire thing. Instead of setting the document each time, set the document in the worker's constructor. Then move the insertion to process. That way, the text pane only needs to update part of its state.
About catching that exception, seriously - why was BadLocationException ever made a checked exception?


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Jean-Claude Dauphin
Greenhorn

Joined: Nov 14, 2012
Posts: 3
Thank you Rob for your prompt response.

The idea was in fact to isolate the Document from the JTextPane and to load the data directly in an empty Document using a thread outside the EDT, and then to call the setDocument method from the EDT to connect the document to the JTextPane.
I am not sure if the Document insertString method can be called outside the EDT, I didn't found any info on this issue. Calling the insertString method from doInBackground() works well and avoids to get the warning message at this stage.
WARNING [org.netbeans.core.TimableEventQueue]: too much time in AWT thread null
However, we get this message after calling the setDocument method from the EDT in the process method. I also noticed that the process method is called only once with the full list of strings sent by the calls to the publish method, thus I don't know how the process method can only get intermediate results.
It turns out that loading huge volume of data in a Document is not really time consuming, the real bottleneck seems to be with JTextPane setDocument and the rendering/painting which blocks the GUI.

Therefore, we think that using SwingWorker is not useful in that particular case and we came back to the following code:

Here is the result of above code:
FIELD TEXT LENGTH 2422482
20125 milliseconds to setDocument

It's not too bad, but the main issue is that the GUI is blocked after the call to setDocument. The JTextPane area stays empty for about 1 mn, then the text is displayed and it takes about 30s - 1mn to get back the hand on the GUI.

It's really annoying and I would like at least to inform the user that he has to wait and that the application is running and not stuck.

We are not sure to be in the right direction, any idea on how to manage this issue would be appreciated.

Best wishes,

JCD
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19672
    
  18

Jean-Claude Dauphin wrote:The idea was in fact to isolate the Document from the JTextPane and to load the data directly in an empty Document using a thread outside the EDT, and then to call the setDocument method from the EDT to connect the document to the JTextPane.

The idea is good, but because your Document is so incredibly large the EDT still has to do a lot of work. That's why the GUI gets blocked.

I am not sure if the Document insertString method can be called outside the EDT, I didn't found any info on this issue. Calling the insertString method from doInBackground() works well and avoids to get the warning message at this stage.

When the Document is not connected to the GUI it should be safe. However, in your case it is (setDocument doesn't create a copy, so the Document is used both by doInBackground and the EDT. That's not good, and can lead to threading issues.

WARNING [org.netbeans.core.TimableEventQueue]: too much time in AWT thread null
However, we get this message after calling the setDocument method from the EDT in the process method.

That's because setDocument take a lot of time if the Document contains a lot of text.

I also noticed that the process method is called only once with the full list of strings sent by the calls to the publish method, thus I don't know how the process method can only get intermediate results.

process doesn't necessarily get called after each single call to publish. The published chunks may be cached and then sent to process at some undetermined time. Usually a few published chunks will be grouped. If your process method gets called only once then this is probably caused because the EDT is still blocked. The gathering still occurs and when the EDT is free again, all chunks will be published.


My code will probably do exactly what you want. doInBackground reads chunks one at a time and publishes these. process will be called several times, each time adding the newly added chunks to the Document and therefore the GUI. You should see the text pane's content change gradually.
Jean-Claude Dauphin
Greenhorn

Joined: Nov 14, 2012
Posts: 3
Thanks Rob for the clarifications.

Even with your code, I cannot see the JTextPane's content changing gradually and the GUI remains blocked until all insertString calls are processed on the EDT (I suppose).
The main problem is that the strings are accumulated in a list and the process method is called only once with the full list of strings.

Thanks again for your help

JCD
 
 
subject: Problem with JTextPane setDocument blocking the GUI