6

I have a JComboBox whose values are retrieved across the net.

I'm looking for a way to indicate that fact to the user, when the user wants to see the list, expands the drop down, and only then the data is being retrieved.

The basic requirements include:

  1. JComboBox's drop-down shouldn't lock the EDT, but the combo's action should not work until there are values.
  2. User should know when all data has been retrieved.
  3. The size (UI real-estate) of the indication should be as small as possible.

Note that the data isn't retrieved until the user wants to see the combo's values (i.e. expands the drop-down list).

The solution i've used:

I've used a SwingWorker to keep the UI responsive. The combo box was overlayed using JIDE's Overlayable with JIDE's InfiniteProgressPanel that listens to the worker.

Asaf
  • 2,480
  • 4
  • 25
  • 33

3 Answers3

7

To avoid locking the EDT, your data retrieval should be done in a background thread. I would use a SwingWorker to find and load the values since this makes available a background thread with other goodies that make it very Swing-friendly. I would make the JComboBox enabled property false until all values have been loaded, and then enable it via setEnabled(true). You will know the SwingWorker is done either through its done() method (by overriding it), or by adding a PropertyChangeListener to the SwingWorker and being notified when its state is SwingWorker.StateValue.DONE.

One way for the user to know that the process is complete is that they will see when the combo box has been re-enabled. If you want a more obvious indicator, you could display a JProgressBar or a ProgressMonitor. This could be displayed in a dialog if you wish to leave the GUI appearance mostly unchanged.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • thanks! i've edited the question - the values should be filled only when requested, so enable/disable isn't what I'm looking for. A dialog isn't suitable either. As to the SwingWorker - I'll use one, but the question is about what UI to drive with it – Asaf Dec 26 '11 at 15:27
  • _filled only when requested_? _requested_ how? – trashgod Dec 26 '11 at 16:25
  • @trashgod when the drop down is opened for the first time – Asaf Dec 27 '11 at 05:58
3

I implemented it by adding "Loading..." item and a special border around the JComboBox. On click separate thread is started adding new items via SwingUtilities.invokeAndWait. When loading is completed the "Loading..." last item is removed.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • That's in the lines of what i thought. What do you do to prevent choosing "Loading..." or starting another separate thread? – Asaf Dec 27 '11 at 09:53
  • Don't prevent selecting "Loading..." simply do nothing. If the combo is closed after selecting it, when data is loaded, "Loading..." will be replaced by first option or blank. The special border will disappear also. You should check that you are not loading the data to avoid loading it twice. – helios Dec 27 '11 at 12:12
1

to not force my users to wait until the data is loaded, combine the answers by eel and stan :-)

  • start off with the model containing zero or one real value plus the dummy entry "loading"
  • register a PopupMenuListener and start a SwingWorker loading the data (into a separate datastructure, might be a new model) in its very first menuWillBecomeVisible
  • while loading, select the dummy entry (and/or whatever else is appropriate to inform the user what's happening), the action has to be aware of "nothing-to-do-yet" as well
  • listen to the worker, when receiving the DONE replace/fill the data into the combo's model
kleopatra
  • 51,061
  • 28
  • 99
  • 211