• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JTree - LazyLoad - SwingWorker

 
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have read several postings and several articles on lazy loading a JTree (using either the WillExpand event or writing a new TreeModel). One reason I want to lazy load is that I am populating the tree from a database over a somewhat slow network link. I am having difficulty wrapping my head around using a SwingWorker (or some other thread) to do the database access on demand - and my readings haven't cleared it up for me.

I don't know that I need to get the data until the user clicks on the tree. If I, at that point, go off and get the data synchronously the Event Dispatch Tread will be hung up until the query returns. If I use a thread to get the data, what do I tell the tree while I'm waiting for the query to return? Do I tell the tree that the selected node has zero children, and then asynchronously add the children and programatically open up the tree? ... I haven't seen any example code doing something like that.

Thanks
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron Alby wrote:Do I tell the tree that the selected node has zero children, and then asynchronously add the children and programatically open up the tree?



Did you already tell the tree that the selected node has zero children? Or did you tell the tree that the selected node does have children (so the user knows they can expand that node)? Clearly the latter is what you want to do.

But then what happens if it turns out there are no children, when you ask the database? At that point you're going to have to tell the tree the truth, that there are in fact no children. So it might be a good idea if your design included some visual clue that a node might or might not have children, but you don't know until the user asks.
 
Bartender
Posts: 3323
86
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are several strategies you can employ, such as:
1. If you think you are likely to use mots of the data you can start loading it all in the background and if the user selects something that hasn't been loaded yet then load that now.
2. You can load the current tree level in the background and wait until the user selects a node before loading the next level of the tree. Again any node that the user selects that hasn't been loaded yet must be loaded immediately.
3. You could get really clever and keep track of the recent data requests and if the same data is being repeatedly requested by this user load that first.
4. You can wait until a user selects a node and then load just that node.

If I, at that point, go off and get the data synchronously the Event Dispatch Tread will be hung up until the query returns. If I use a thread to get the data, what do I tell the tree while I'm waiting for the query to return?


First of all don't use the EDT to get the data, use another thread or use SwingWorker which is perfect for any task that requires a background action which updates the GUI.
As for what to do with the GUI, if the user is waiting for a node to load you need to reflect this in the GUI, there are many ways of doing this, such as
1. Display a progress bar.
2. Change the mouse to an hour glass.
3. Change the JTree node to display an image that informs the user the opening action is waiting for the data to be loaded ie a an hour glass, arrows in a circle etc

Action type 1 stops the user doing anything else until the data is loaded
Action type 2 suggest to the user they can't do anything else until the data is loaded (it's up to you if you allow further mouse clicks whilst the mouse is an hour glass but it's not very intuitive to do so).
Action type 3 allows the user to continue doing other things whilst the data is being loaded. Of course this assumes there are other things the user can do whilst waiting for the data.

 
Ron Alby
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let me be more specific ... perhaps the issue is how I do the lazy loading.

The user clicks on a node to expand it. The JTree calls the TreeModel method getChildCount, followed by a series of getChild. I currently do the loading in getChildCount. I must return out of this method with a number that the JTree will then use when it is laying itself out. Since I have no idea how many children there will be (if any), what number do I return?

Lets say I get fancy and restructure my code so that I am fetching one level of children in advance. Again, based on network traffic, I may still be in a situation where they have clicked on a node that has not yet had its children loaded and still have to deal with the getChildCount issue.

Thanks for taking the time to answer my question.
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron Alby wrote:I currently do the loading in getChildCount. I must return out of this method with a number that the JTree will then use when it is laying itself out. Since I have no idea how many children there will be (if any), what number do I return?



If you have to do it that way (and I would rather do it some other way, like the TreeNodeWillExpand event you mentioned earlier), then the answer is that you start the SwingWorker to load the children, and return zero immediately. The SwingWorker will create nodes and add them to the TreeModel; the model should be designed so that adding a node causes a standard event to be sent to all of its listeners, which would include the JTree.
 
Ron Alby
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Paul.
I moved to the listener and implemented the worker as you suggested.
Its all good now.

 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic