Question

I know that GUI code in Java Swing must be put inside SwingUtilities.invokeAndWait or SwingUtilities.invokeLater. This way threading works fine.

Sadly, in my situation, the GUI update it that thing which takes much longer than background thread(s). More specific: I update a JTree with about just 400 entries, nesting depth is maximum 4, so should be nothing scary, right? But it takes sometimes one second! I need to ensure that the user is able to type in a JTextPane without delays. Well, guess what, the slow JTree updates do cause delays for JTextPane during input. It refreshes only as soon as the tree gets updated.

I am using Netbeans and know empirically that a Java app can update lots of information without freezing the rest of the UI.

How can it be done?

NOTE 1: All those DefaultMutableTreeNodes are prepared outside the invokeAndWait.
NOTE 2: When I replace invokeAndWait with invokeLater the tree doesn't get updated.
NOTE 3: Fond out that recursive tree expansion takes far the most time.
NOTE 4: I'm using custom tree cell renderer, will try without and report.
NOTE 4a: My tree cell renderer uses a map to cache and reuse created JTextComponents, depending on tree node (as a key).

CLUE 1: Wow! Without setting custom cell renderer it's 10 times faster. I think, I'll need few good tutorials on writing custom tree cell renderers. Sadly, I need a custom cell renderer.

This tutorial involving lazy loading might help, I'll work this through.

Was it helpful?

Solution

[There are some details missing, such as: what type of processing is happening each time the user updates the JTextPane? Is the whole tree being rebuilt?]

Anyway, what has worked for me in the past (when I experienced significant slowdown due to JTree updates) is that I rolled out my own TreeModel.

Most programmers choose to use DefaultTreeModel. This is indeed an off-the-shelf solution that works well in most cases. However, it is quite slow when significant parts of the tree needs to be updated. Obviously, Writing your own TableModel is more work than using a canned solution, but it is much less painful than you think.

In particular, my custom tree model is fast because it does not build any tree, per-se. It just observes my domain model and computes the answers to the method invoked on it (getChild(), getParent(), ...) by extracting the relevant information from that model. Try it. It works like a charm.

OTHER TIPS

I do not know why it only works with invokeAndWait() (this is strange), but a simple hack would be to invoke this method in a new background thread.

I would also advise you not to populate all the tree at once. This is often a huge amount of work that just cannot be easily sped up. Instead, update only those nodes that are visible and update more nodes as the user expands them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top