Swing Letzte Änderung in der Tabelle wird nicht gespeichert

kodela

Bekanntes Mitglied
Hallo,

in einem ListenFrame habe ich eine JTable-Liste mit 6 Spalten eingebunden. Der Inhalt der sechsten Spalte ist editierbar.

Die Tabelle funktioniert mit einer Ausnahme rundum einwandfrei. Die Ausnahme:
Wenn in der sechsten Spalte etwas verändert wird und diese Änderung ist noch nicht abgeschlossen, also der Textcursor ist noch in diesem Feld, wenn jetzt das ListenFrame geschlossen wird, wird die Änderung nicht gespeichert. Dieses Manko kann ich zwar umgehen, wenn ich vor dem Schließen irgend ein anderes Feld in der selben oder einer anderen Zeile selektiere. Das kann man aber übersehen und dann ist die Änderung verloren.

Ich habe schon diverse Versuche gemacht, zum Beispiel vor dem Schließen noch stopCellEditing() aufgerufen. Bisher habe ich aber noch keine Lösung gefunden. Kenn sich jemand besser aus mit JTable als ich und kann mir einen Tipp geben?

Gruß, kodela
 
Hallo,

die Daten werden bei mir immer dann gespeichert, wenn das ListenFrame den Fokus verliert. Das läuft über folgende Methode ab:
Java:
private void formWindowDeactivated(java.awt.event.WindowEvent evt) { 
    String tst = String.valueOf(listenModel.getValueAt(0, 5));            // nur zum Testen
    listeEditor.stopCellEditing();
    listenModel.datenSpeichern(strApp.getUserDir(), "str8ts.lst", true);
}

Die Abfrage beim Aufruf dieser Methode zeigt, dass für die editierte Zelle der ursprüngliche Wert zurückgegeben wird und nicht der aktuelle.

Gruß, kodela
 
Java:
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class Test {
    public void run() {
        DefaultTableModel model = new DefaultTableModel(5, 10);
       
        final JTable table = new JTable(new LoggingTableModel(model));
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (table.isEditing()) {
                    table.getCellEditor().stopCellEditing();
                }
                e.getWindow().dispose();
            }
        });
        frame.add(new JScrollPane(table));
        frame.setVisible(true);
        frame.setSize(800, 600);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().run());
    }
}
Das LoggingTableModel kannst Du ignorieren, das dient mir nur zu ... Logging-Zwecken 🙂
 
Danke mihe7,

das war es. Jetzt sieht die Methode, die immer dann aufgerufen wird, wenn das ListenFrame den Fokus verliert, bei mir so aus:
Java:
private void formWindowDeactivated(java.awt.event.WindowEvent evt) {                                    
    if (jTable.isEditing()) {
        jTable.getCellEditor().stopCellEditing();
    }
    listenModel.datenSpeichern(strApp.getUserDir(), "str8ts.lst");
}
und damit funktioniert alles so, wie ich es wollte. Bei mir ist einiges natürlich anders, als in Deinem Beispiel, das ändert aber an der grundsätzlichen Vorgehensweise nichts.

Nochmals vielen Dank für die kompetente und schnelle Hilfe,
kodela
 

Zurück
Oben