Button in einer JTable

Ein paar kleine fixes:

1.: Keine eigenen Buttons erstellen

In DataTableModel.java:

    public Object getValueAt(int row, int column) {
        TableData data = dataSets.get(row);
        switch (column) {
            case 0:
                return data.getForename();
            case 1:
                return data.getSurname();
            case 2:
                // return createButton(data); // ------------------ WEG!
                return "delete "+data.getForename(); // ----------- HIN!
                //return "button";
            default:
                throw new RuntimeException("Unzuläsiger Spaltenindex '" + column + "'.");
        }
    }

Dort soll praktisch die Button-Aufschrift zurückgegeben werden, und nicht „ein Button-Objekt“.

Darum, dass dort „ein Button ist“, kümmert sich die ButtonColumn. Die habe ich jetzt nicht komplett gelesen, aber beim Überfliegen sieht es nach dem Standard-Muster aus. Im speziellen: Dort sind keine Buttons in der Table :slight_smile: Stell’ dir vor, du hättest eine Table mit 10000 Zeilen - dort würden ja dann 10000 Buttons erstellt. Bei sowas verwendet (man in) Swing eine einzelne Komponente (z.B. einen JButton), und verwendet den „wie einen Stempel“: Intern geht Swing durch die Tabelle, und verwendet immer denselben(!) button, um den Zelleninhalt zu malen. Siehe auch How to Use Tables (The Java™ Tutorials > Creating a GUI With Swing > Using Swing Components)

2: Sagen, dass das Modell editierbar ist

In die DataTableModel.java muss

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 2;
    }

Die default-Implementierung vom AbstractTableModel gibt dort pauschal false zurück. Für die Buttons muss die cell aber als „editierbar“ gelten (komplizierte Gründe, … ist halt so)

3: Kein DefaultTableModel annehmen

In der ButtonColumnDemoWithTableDataObjects.java steht

        if (result == JOptionPane.YES_OPTION) {
            ((DefaultTableModel) table.getModel()).removeRow(row);
        }

Das kracht halt beim casten, weil dein DataTableModel eben kein DefaultTableModel ist. Man kann stattdessen

        if (result == JOptionPane.YES_OPTION) {
            dataSets.remove(row);
            tableModel.fireTableDataChanged();
        }

machen. Das fireTableDataChanged ist so eine Art Schrotflinte, und besagt: Alles könnte sich geändert haben - aktualisiere mal die ganze Tabelle. (Bei großen Tabellen wäre das ineffizient, aber solange es nicht um wirklich sehr große Tabellen geht, ist das erstmal egal…)


Weitere Hinweise:

  • Alles in einen Codeblock klatschen wäre etwas einfacher für Leute, die das kopieren und schnell ausprobieren wollen
  • Sagen, was genau eigentlich nicht funktioniert (bzw. was die Frage ist), wäre gut
  • Ignorier’ coffee_eater im Zweifelsfall…
2 „Gefällt mir“