# JComboBox in JTable, Actionlistener



## betram (2. Aug 2010)

Hallo, 

ich habe eine JTable, bei der ich einzelne Zellen mit unterschiedlichen JComboBoxes befüllen möchte. Folglich habe ich einen DefaultCellEditor wie folgt umgeschrieben (zur Übersichtlichkeit ein wenig gekürzt:

```
class MyTableCellEditor extends DefaultCellEditor {

        private List<JComboBox> data;

        public MyTableCellEditor() {
            super(new JComboBox());
            data = new LinkedList();

        }

        public void addItemForCell(int row, int column, Object item) {
            boolean exists = false;

            if (column == 10) // nur spalte 10 wird im moment benötigt
            {
                if (data .size() - 1 < row) {    // already item added for cell
                    data .add(new JComboBox());
                }
                 data .get(row).addItem(item);
               
            }         
        public JComboBox getItemsForCell(int row, int column) {
            JComboBox temp = new JComboBox();
            if (column == 10) {
                temp = data .get(row);
            }             return temp;
        }

        @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            JComboBox combo = (JComboBox) super.getTableCellEditorComponent(table, value, isSelected, row, column);
            combo.removeAllItems();
            combo.addActionListener(new ComboBoxSelectionHandler());
            JComboBox temp = getItemsForCell(row, column);
            for (int i = 0; i < temp.getItemCount(); i++) {
                combo.addItem(temp.getItemAt(i));
            }

            return combo;
        }
    }
```

Wenn ich nun in meinem ActionListener das aktuelle Element der Zelle mit jTable.getSelectedRow(); anzeigen lasse, so ist dies immer das Element, welches zu vor angewählt war. Ich muss folglich immer zweimal auf ein ComboBox Item klicken, damit ich das aktuelle Ergebnis verarbeiten kann...Da es mit einem StandardListener (allerdings mit gleichen ComboBoxes für die ganze Spalte) funktioniert ht, vermute ich, daß es am geposteten Code liegen muss.
Muss ich selbst eine Funktion schreiben/überschreiben, welche das aktuelle Element setzt?


----------



## ymene (2. Aug 2010)

Ein sehr ähnliches Thema gab es kürzlich bereits. Schau mal, ob dir das weiter hilft: 

JComboBox als CellEditor in JTable zeigt Elemente nicht sofort an


----------



## betram (2. Aug 2010)

Hallo, 

danke für den Hinweis. Dein DefaultCellRenderer ist ja prinzipiell sehr ähnlich mit dem Unterschied, daß ich die ComboBox später erst befülle. Ich werde mal schauen ob das was ändert.
Die letzte Antwort des Threads von ElJarno habe ich nicht verstanden. Wie weist man combobox items einem Modell zu?

Schöne Grüße 

Bertrand


----------



## betram2 (3. Aug 2010)

also, das hat auch keinen unterschied gemacht.

wenn ich nun einen itemlistener verwende und mit e.getItem() das Object anzeige, so wird das richtige Objekt angezeit. Allerdings
ist es so schwierig die Quelle zu erfahren, da ich mit e.getSource() nur weiß, dass es von einer ComboBox ausgelöst wurde, aber nicht von welcher.
wenn ich das objekt der Zelle auslese wird nach wie vor das vorherige angezeigt. Dieses wähle ich auch explizit aus, also es ist nicht so, daß da nur die Bestätigung fehlen würde..


----------



## Michael... (3. Aug 2010)

betram2 hat gesagt.:


> wenn ich nun einen itemlistener verwende und mit e.getItem() das Object anzeige, so wird das richtige Objekt angezeit. Allerdings
> ist es so schwierig die Quelle zu erfahren, da ich mit e.getSource() nur weiß, dass es von einer ComboBox ausgelöst wurde, aber nicht von welcher.


Verwende nur eine ComboBox.
Ich hab mir den alten Code nicht so genau angeschaut und kenne den neuen nicht. Aber im alten Code wird jedes mal wenn ein Editor benötigt wird eine neue ComboBox erzeugt. (Ist nicht unbedingt im Sinne des Erfinders) ;-)

Und für was die List<JComboBox> gut sein soll, habe ich nicht verstanden.


----------



## betram2 (3. Aug 2010)

ok ich verwende nun eine Instanz. Die verketteten Listen sind dazu da, den Inhalt der Zellen-Combobox zu puffern. Wieviele ComboBoxen auftauchen hängt an der Anzeil von Zeilen ab, welche dynamisch ist da SQL abfrage.

Ich habe das o.g. Problem nun in den Griff bekommen, indem ich in dem ActionListener ein stopCellEditing() eingeführt habe.
Ist zwar nicht besonders elegant (eigtl sollte das Editieren nach der Auswahl ja erledigt sein) aber es funktioniert


----------



## Michael... (3. Aug 2010)

betram2 hat gesagt.:


> ok ich verwende nun eine Instanz. Die verketteten Listen sind dazu da, den Inhalt der Zellen-Combobox zu puffern.


Aber warum ein Liste bestehend aus ComboBoxen?


betram2 hat gesagt.:


> Wieviele ComboBoxen auftauchen hängt an der Anzeil von Zeilen ab, welche dynamisch ist da SQL abfrage.


Wo tauchen da mehrere ComboBoxen auf? Ich seh nur eine ComboBox als Editor für eine Zelle.




betram2 hat gesagt.:


> Ich habe das o.g. Problem nun in den Griff bekommen, indem ich in dem ActionListener ein stopCellEditing() eingeführt habe.
> Ist zwar nicht besonders elegant (eigtl sollte das Editieren nach der Auswahl ja erledigt sein) aber es funktioniert


Irgendwie muss man der Tabelle sagen, dass die Bearbeitung abgeschlossen ist.


----------



## betram2 (3. Aug 2010)

es stimmt, dass es sinnvoller wäre, nur den inhalt der combobox und nicht die combobox selbst zu speichern, ich werde das auch noch ändern, ist aber hierfür erstmal irrelevant.

ich habe nun ein anderes Problem. kann man in einem itemlistener herausfinden, aus welcher Spalte eine Combobox editiert wurde?
(ich habe 2 verschiedene Typen von CBs je nach Spalte und möchte eine Aktion nur dann ausführen, wenn auch diese CB verändert wurde). mit getSource() bekomme ich leider nur die Klasse zurück.
Mir fällt im mom nur ein, zwei instanzen eines itemlisteners mit IDs zu erstellen, jeweils einer spalte zuzuweisen und dann in der klasse die eigene ID zu vergleichen, aber das wirkt mir zu umständlich


----------



## ymene (3. Aug 2010)

betram2 hat gesagt.:
			
		

> ich habe nun ein anderes Problem. kann man in einem itemlistener herausfinden, aus welcher Spalte eine Combobox editiert wurde?
> (ich habe 2 verschiedene Typen von CBs je nach Spalte und möchte eine Aktion nur dann ausführen, wenn auch diese CB verändert wurde). mit getSource() bekomme ich leider nur die Klasse zurück.



Bin mir noch nicht ganz im klaren darüber, was das mit dem ItemListener zu tun hat, aber du kannst Celleditoren sowohl auf bestimmte Datentypen, als auch auf bestimmte Spalten anmelden. Solltest du die Spalte nicht eindeutig am Datentyp festmachen können, so kannst du sie also direkt über den Spaltenindex adressieren und so den jeweiligen Editor anmelden. Beim Anmelden deines Cell-Editors übergibst du dann einfach die entsprechende Combobox (A oder B) an den CellEditor.


```
table.getColumn( SPALTE3 ).setCellEditor( new ComboBoxCellEditor( new JComboBoxA(  ) ) );
    table.getColumn( SPALTE5 ).setCellEditor( new ComboBoxCellEditor( new JComboBoxB(  ) ) );
```

Sollte es sichbei den verschiedenen Comboboxen um nicht überschriebene sondern eigene Methoden handeln, die du aufrufen musst, so musst du den CellEditor entsprechend anpassen, so dass er beide Comboboxen managen kann, oder halt einen eigenen CellEditor für jede Combobox schreiben, wenn die unterschiede zu gravierend sind.


----------



## Michael... (3. Aug 2010)

betram2 hat gesagt.:


> ich habe nun ein anderes Problem. kann man in einem itemlistener herausfinden, aus welcher Spalte eine Combobox editiert wurde?


Wozu soll das interessant sein?
Es werden keine ComboBoxen editiert, sondern Zelleninhalte ;-)

Wenn Dich interessiert in welcher Spalte etwas geändert wurde, dann häng doch einen TableModelListener ans TableModel.


----------



## betram2 (3. Aug 2010)

Das war es was ich gesucht habe! Danke allen Beteiligten!


----------

