• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Refreshing contents of a ComboBox while it is still visible

 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have implemented a ComboBoxModel that is populated based on data from a database:


As you can see, refreshModel() is a template method and subclasses fill in the details by implementing three abstract methods: getSQLString(), setSQLParameters(), and getDatabaseRecord(). I have several subclasses for different tables in the database I am working with. TeacherComboBoxModel and SchoolComboBoxModel are the ones I am working with at the moment.

Maybe I need to back up a little. This is being used in an "attendance tracker" application. The details are not too important at the moment. What I want to do is have two ComboBoxes on a JPanel. One uses SchoolComboBoxModel and another uses TeacherComboBoxModel. When the user selects a school in the former, the later should be populated with only teachers that work at that particular school.

I figure a good way to do this is to add an ItemListener to the school ComboBox. When itemStateChanged() is called with a SELECTED event, then I can call the refreshModel() method on the model used for the teacher ComboBox, which happens to be an instance of TeacherComboBoxModel. Here's the code that I'm using:



I thought this would work. However, when I selected a school name in schoolComboBox, the drop list in teacherComboBox is blank. The drop down list is drawn, but there are no Strings painted in it. I can't even see the "(Choose One)" option that should be listed first. Also, no matter where I click on the drop down list, it always selects the same teacher.

Does anyone have any ideas how I can fix this? Is there another method that I need to override in my ComboBoxModel subclass? I will greatly appreciate any suggestions that can point me in the right direction.

Thanks,

Layne
 
Scott Delap
author
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Layne,

If you look at DefaultComboBoxModel you will see that changes call fireIntervalXXX(); methods after they are finished. These methods fire events to ComboBoxModel listener like the JComboBox itself. This tells the JComboxBox to refresh based off the model changes.

Scott Delap
ClientJava.com
Desktop Java Live
 
Michael Dunn
Ranch Hand
Posts: 4632
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
just going by your subject line, this seems to work OK
(when it opens, click the combobox to show the popup, and wait for the timer)

 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Scott Delap:
Layne,

If you look at DefaultComboBoxModel you will see that changes call fireIntervalXXX(); methods after they are finished. These methods fire events to ComboBoxModel listener like the JComboBox itself. This tells the JComboxBox to refresh based off the model changes.

Scott Delap
ClientJava.com
Desktop Java Live


Thanks. After a little bit of searching, I found the fireIntervalXXX() methods are located in AbstractListModel. That looks exactly like what I need, especially if I change this implementation to only add and remove items from the model as records are inserted and deleted from the table. At the moment, it just does a batch refresh whenever the dialog containing the ComboBox is displayed.

Layne
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Michael Dunn:
just going by your subject line, this seems to work OK
(when it opens, click the combobox to show the popup, and wait for the timer)



According to Scott, DefaultComboBoxModel notifies its listeners that changes are made and so the ComboBox knows to repaint. My custom ComboBoxModel is missing this functionality apparently.

Layne
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, Scott. Your suggestion helped me fix the problem. I ended up calling AbstractListModel.fireContentsChanged() at the end of DatabaseComboBoxModel.refreshModel() since I am completely changing the contents of the model. It seems to work just fine now.

Layne
 
Zon Horn
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HAD A SIMILAR PROBLEM:
after adding a new row to mysql database, corresponding combobox list failed to show any contents (several empty rows and any selection results in last list selection), though iterating to system.out.println() showed correct contents of combobox list and it worked correctly after program restart (without list changes).

HOW THIS POST HELPED:
adding fireContentsChanged(this, 0, 0); to the end of Combobox mouseEntered event solved the problem - adding new row is now dynamically shown in Combobox list and can be chosen. Combobox one-by-one removeItem and addItem methods precede fireContentsChanged(this, 0, 0).

ALSO:
solved other similar combobox display problems with a hack: combobox.showPopup; combobox hidePopup; in the same mouseEntered event.

USED:
public class MyComboboxModel extends AbstractListModel implements ComboBoxModel, MutableComboBoxModel, KeyListener, ItemListener
 
Rob Spoor
Sheriff
Pie
Posts: 20545
56
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That call should not be necessary at that point in time. Instead you should fire the right events when the data is actually modified. If you adhere to all the rules in Swing (like not doing any updates to the GUI from a thread that's not the Event Dispatcher Thread) that should work just fine.
 
Darryl Burke
Bartender
Posts: 5132
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Zon Horn wrote:USED:
public class MyComboboxModel extends AbstractListModel implements ComboBoxModel, MutableComboBoxModel, KeyListener, ItemListener

If you really, really need a customized model, I'd hazard a guess that you'd be much better off extending DefaultComboBoxModel.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic