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.