Swing AWT-Exception bei JTable mit JComboBox beim Löschen der letzten Zeile

speckyspooky

Mitglied
Hallo Zusammen,

ich hoffe mir kann jemand hier weiterhelfen.
Ich schreibe eine GUI mit einer JTable. Damit der User nicht alles eingeben muss, bekommt die JTable JComboBoxen als DefaultCellEditor zugehordnet, welche durch eine Datenbank befüllt werden.
Weiterhin habe ich zwei Buttons angelegt zum hinzufügen und löschen von Rows.
Das hinzufügen klappt ohne Probleme.
Allerdings macht das löschen Probleme, aber nur der letzten Zeile. Wenn ich die letzte Zeile von zum Beispiel 6 Zeilen lösche, dann bekomme ich beim Focus setzen auf die Tabelle eine "AWT-EventQueue-0"-Exception. ;(
Diese Fehlermeldung wird nicht beim löschen direkt ausgegeben, sondern beim setzen des Focus auf die JTable. Hier die Fehlermeldung:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 5 >= 5
at java.util.Vector.elementAt(Vector.java:427)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:648)
at javax.swing.JTable.setValueAt(JTable.java:2709)
at javax.swing.JTable.editingStopped(JTable.java:4711)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:125)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:350)
at javax.swing.DefaultCellEditor$3.stopCellEditing(DefaultCellEditor.java:140)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:215)
at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(BasicTableUI.java:980)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:263)
at java.awt.Component.processMouseEvent(Component.java:6260)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4235)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Irgendein Element versucht Zeile 6 zu aktualisieren, die ja schon weg ist. Da würde ich natürlich auch schimpfen. Wenn ich die JComboBoxen wieder heraus nehme, dann tritt dieser Fehler nicht auf.

1. So definiere ich meine Tabelle:
Java:
    jTable.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {},
        new String [] {"Title 1", "Title 2", "Title 3", "Title 4", "Title 5", "Title 6", "Title 7", "Title 8", "Title 9"}
    ) {
        Class[] types = new Class [] {
            java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
        };
        boolean[] canEdit = new boolean [] {
            true, true, true, false, true, true, true, true, true
        };

        public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }

        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return canEdit [columnIndex];
        }
    });

2. Erstellung der JComboBox und Zuweisung zur JTable
(Der Fehler tritt unabhängig von Items in der JComboBox auf.)
Java:
javax.swing.JComboBox cbCondition   = new javax.swing.JComboBox();
javax.swing.table.TableColumn tbColumn = jTable1.getColumnModel().getColumn(0);
tbColumn.setCellEditor(new javax.swing.DefaultCellEditor(cbCondition));

3. Meine Add- bzw. Del-Methode
Java:
    private void jBRowAddMouseClicked(java.awt.event.MouseEvent evt) {                                      
        javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) jTable1.getModel();
        int addrow[] = jTable1.getSelectedRows();
        if ( addrow.length != 0) {
            for ( int i=addrow.length; i > 0 ; i--) {
                model.insertRow(addrow[i-1]+1, new Object[]{"","","","",false,false,"","","AddLine"});
            }
        } else {
            model.addRow(new Object[]{"","","","",false,false,"","","AddBottom"});
        }
}                                     

    private void jBRowDelMouseClicked(java.awt.event.MouseEvent evt) {                                      
        javax.swing.table.DefaultTableModel model =  (javax.swing.table.DefaultTableModel) jTable1.getModel();
        int delrow[] = jTable1.getSelectedRows();
        for ( int i=delrow.length ; i > 0 ; i--) {
            model.removeRow(delrow[i-1]);
        }
}

Ich habe das TableModel untersucht und die Tabelle an sich aber beide weisen nach dem löschen der letzten Zeile die gleiche Struktur auf. Überhaupt beim Löschen der anderen Zeilen besteht das Problem nicht. ???:L

Lösungsansatz:
Das einzige was ich herausgefunden habe ist, wenn ich im delete ein "model.fireTableStructureChanged();" dann wird die Tabelle vollständig neu gesetzt und der Fehler tritt nicht mehr auf. Dafür muss ich aber alle DefaultCellEditor(en), sowie die weiteren Tabelleneigenschaften, damit die Tabelle wie vorher aussieht.

Gibt es nicht neine andere Methode außer als mit dem Hammer darauf zu hauen???

Danke an euch!!!
 
wenn du eine der vorherigen Zeilen löschst, dann gibt es bisher ja keinen Fehler weil der Index noch hoch genug ist,
aber wird dann nicht der Wert einer anderen Zeile verändert?.. (*)

vielleicht hilft folgende Option
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
so dass diese noch offene Änderung vor dem Button zur Löschung ausgeführt wird

eine andere extreme Variante wäre noch, setValueAt() im Model zu überschreiben und dort nichts zu tun wenn der Index nicht passt,
aber das ist allgemein ja keine schöne Vorstellung, besonders wegen (*)
 
Die Methode zum Löschen der Zeilen funktioniert ja eben, sprich alle Indix-Werte die angesprochen werden könne auch gelöscht werden.
Der Überlauf passiert wenn ich den Focus neu auf die Tablle setze. Es kommt mir so vor, als ob "Irgendetwas" versucht die Tabelle neu zu aktualisieren und dieses "Irgendetwas" hat nicht mitbekommen, dass die letzte Zeile entfernt wurde.
Wenn er dann mit dem alten Vektor arbeitet, geht das natürlich schief. Allerdings tritt dies nur auf "mit JComboBox!" ohne geht es perfekt.

Dein putClientProperty probiere ich heute Abend mal aus.

PS.: Ich habe gestern Abend noch meinen Hammer fertig gestellt und wenn ich nach fireTableStructureChanged(); die Tabelle in ihrer Struktur/Aussehen neu aufbaue, sieht es aus wie vorher und es geht auch nichts verloren.
 
Ich habe den putClientProperty ausprobiert, allerdings hat dieser nichts genutzt. Es scheint, als ob es an dem DefaultCellEditor liegt. Dieser scheint noch den alten Tabellen-Index zu besitzen und bei aktualisierung des DatenVektors tritt der Fehler auf.
 

Neue Themen


Zurück
Oben