import java.util.ArrayList;
import java.util.List;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

/** Satu baris data tugas. */
record BarisTugas(String nama, boolean selesai) {
}

/** TableModel kustom: sumber data berupa List of record. */
class DaftarTugasModel extends AbstractTableModel {
    private final List<BarisTugas> baris = new ArrayList<>(List.of(
            new BarisTugas("Belajar Java", true),
            new BarisTugas("Kerjakan latihan", false)));
    private final String[] kolom = { "Tugas", "Selesai" };

    @Override public int getRowCount() { return baris.size(); }
    @Override public int getColumnCount() { return kolom.length; }
    @Override public String getColumnName(int c) { return kolom[c]; }

    @Override public Object getValueAt(int r, int c) {
        BarisTugas t = baris.get(r);
        return c == 0 ? t.nama() : t.selesai();
    }

    void tambah(String nama) {
        baris.add(new BarisTugas(nama, false));
        fireTableRowsInserted(baris.size() - 1, baris.size() - 1);
    }

    void hapus(int r) {
        baris.remove(r);
        fireTableRowsDeleted(r, r);
    }
}

public class ModelTugas {
    public static void main(String[] args) {
        DaftarTugasModel model = new DaftarTugasModel();
        List<String> catatan = new ArrayList<>();

        model.addTableModelListener((TableModelEvent e) -> {
            String jenis = switch (e.getType()) {
                case TableModelEvent.INSERT -> "INSERT";
                case TableModelEvent.DELETE -> "DELETE";
                default -> "UPDATE";
            };
            catatan.add(jenis + " baris " + e.getFirstRow());
        });

        System.out.println("ukuran awal   = " + model.getRowCount() + "x" + model.getColumnCount());
        System.out.println("header kolom  = " + model.getColumnName(0) + ", " + model.getColumnName(1));

        model.tambah("Baca dokumentasi JTable");
        model.hapus(0);

        System.out.println("kejadian model = " + catatan);
        for (int r = 0; r < model.getRowCount(); r++) {
            System.out.println("baris " + r + ": " + model.getValueAt(r, 0)
                    + " | selesai=" + model.getValueAt(r, 1));
        }

        // View tipis: JTable hanya membaca model, tanpa menyimpan data sendiri.
        JTable tabel = new JTable(model);
        System.out.println("dimensi JTable = " + tabel.getRowCount() + "x" + tabel.getColumnCount());
        System.out.println("nilai via view = " + tabel.getValueAt(1, 0)
                + " | editable(1,1)=" + tabel.isCellEditable(1, 1));
    }
}
