Wie per PN gewünscht: Hier ein paar Erläuterungen.
Vorab: Kannst Du wirklich die Daten erst laden, wenn der Benutzer auf den Pfeil der JComboBox klickt? Oder könntest Du die Daten schon vorher laden? Wenn Du nur die Daten der JComboBox setzen möchtest, dann geht das viel einfacher. Wenn Du sie wirklich erst zum Zeitpunkt des Aufklappens abholen kannst, dann ist mein Ansatz gut.
Ich bin mir nicht ganz sicher, wie weit ich ausholen muss. Daher erkläre ich etwas weitläufiger.
[SIZE="+1"]Modell einer JComboBox[/SIZE]
Jede nicht triviale Swing-Komponente hat ein Modell. Ein Modell stellt der Komponente eine Schnittstelle zu deren Daten zur Verfügung und benachrichtigt sie über Änderungen an den Daten. Die Komponente selbst kennt ihre Daten nur in Form des Modells. Ein Modell ist auf die Art der Komponente zugeschnitten. Das Modell einer JComboBox ist das
ComboBoxModel. Eine JComboBox kann in ihrem Popup die selbe Art Daten darstellen wie eine JList*. Eine bestimmte Anzahl an Zeilen (
getSize()). In jeder Zeile ein Element (
getElementAt(int)). Das ComboBoxModel basiert daher auf der
ListModel-Schnittstelle. Eine JComboBox hat darüber hinaus einen ausgewählten Wert den sie abfragen und verändern kann. Deshalb erweitert die ComboBoxModel-Schnittstelle die ListModel-Schnittstelle um zwei Methoden. Eine Methode
getSelectedItem() liefert den ausgewählten Wert, die Methode
setSelectedItem(Object) ändert den ausgewählten Wert im Modell. Eine mitgelieferte und fertige Implementation des ComboBoxModels heißt
DefaultComboBoxModel.
[SIZE="+1"]Wie funktioniert das MyDBComboBoxModel?[/SIZE]
Die Klasse ist abgeleitet vom DefaultComboBoxModel. Sie überschreibt die beiden oben erwähnten Methoden des zu Grunde liegenden ListModels (geerbt aus AbstractListModel). Die Methoden stellen sicher, dass das Modell initialisiert ist (
ensureInitialized()). Danach delegieren sie an die darunter liegende Methodenimplementation.
Wenn der Benutzer auf das Dreieck der JComboBox klickt, wird ein Event erzeugt. Die JComboBox wird dann Ihr Modell befragen, welche Daten sie im Popup anzeigen soll. All das geschieht im Event Dispatch Thread. Dieser Thread arbeitet alle Events nacheinander ab. Er ist für das Zeichnen und alle Benutzereingaben zuständig. Wenn man zeitaufwändige Aktionen im Event Dispatch Thread ausführt, kann er während dessen nichts anderes machen. Datenbankzugriffe sind zeitaufwändige Aktionen. Würde man diese direkt im Modell implementieren, könnte das Popup der JComboBox erst nach dem Empfang aller Daten gezeigt werden. Deshalb müssen solche Aktionen in einen anderen Thread ausgelagert werden.
Die Methode
ensureInitialized() prüft, ob sie schon einmal aufgerufen wurde. Wenn das nicht der Fall ist, startet sie einen neuen Thread. Dieser Thread übernimmt die zeitaufwändige Aktion, Daten zu laden. Ich habe anstatt eines einfachen
Thread-Objektes die SwingWorker**-Klasse verwendet. Ein SwingWorker startet beim Aufruf der
execute()-Methode einen Thread der die Methode
doInBackground() ausführt. Diese Methode lädt die Daten und fügt sie dem Modell hinzu. Allerdings muss der Entwickler dafür sorgen, dass alle Änderungen einer Komponente synchron zum Event Dispatch Thread ausgeführt werden...
Aus diesem Grund benutzt man einen SwingWorker und keinen nackeligen Thread. Die
doInBackground()-Methode darf nicht selbst
addElement(Object) aufrufen. Sonst wären die Änderungen am Modell nicht synchron zum Event Dispatch Thread. Stattdessen ruft
doInBackground() die
publish(Object...)-Methode des SwingWorkers auf. Diese Methode "merkt" sich alle ihr übergebenen Objekte. Dann sendet Sie einen Event den der Event Dispatch Thread später behandelt. Der Event Dispatch Thread ruft beim Abarbeiten dieses Events die
process(List<Object>)-Methode auf und übergibt ihr alle bis dahin angesammelten Daten aus den
publish(Object...)-Aufrufen. Da der Event Dispatch Thread die
process(List<Object>)-Methode selbst aufruft, kann diese die Änderungen am Modell sicher vornehmen. Die Methode
addElement(Object) (aus AbstractListModel geerbt) fügt die zuvor geladenen Daten dem Modell hinzu und benachrichtigt die JComboBox. Die JComboBox aktualisiert daraufhin die Liste des Popups.
Kannst Du mit dieser Erklärung etwas anfangen?
Ebenius
__________
[SIZE="-2"]* Deshalb wird auch intern eine JList innerhalb des Popups benutzt, um die Daten darzustellen.
** Mehr zum SwingWorker im
Sun Java™ Tutorial: Concurrency in Swing.[/SIZE]