Auf Thema antworten

Es läuft immer über Listener, weil JTable solche beim TableModel registriert.


Hier mal ein Beispiel in komprimierter Form (Zeilenumbrüche weggelassen, alle Klassen in einer -> normal separat):

[code=Java]

import java.awt.BorderLayout;

import java.awt.FlowLayout;

import javax.swing.*;

import javax.swing.table.*;

import java.util.*;


public class Test {


    static class Customer {

        private String id;

        private String mail;


        public Customer(String id, String mail) {

            this.id = id;

            this.mail = mail;

        }


        public Customer(Customer c) {

            this.id = c.id;

            this.mail = c.mail;

        }


        public Customer workingCopy() {

            return new Customer(this);

        }


        public String getId() { return id; }

        public void setId(String id) { this.id = id; }

        public String getMail() { return mail; }

        public void setMail(String mail) { this.mail = mail; }

    }


    public class CustomersTableModel extends AbstractTableModel {

        private static final String[] COLUMNS = {"ID", "Mail"};

        private List<Customer> customers;


        public CustomersTableModel(List<Customer> customers) { this.customers = customers; }


        // TableModel-Implementierung

        // lesend

        @Override public int getRowCount() { return customers.size(); }

        @Override public int getColumnCount() { return COLUMNS.length; }

        @Override public String getColumnName(int col) { return COLUMNS[col]; }

        @Override

        public Object getValueAt(int row, int col) {

            Customer customer = customers.get(row);

            switch(col) {

                case 0: return customer.getId();

                case 1: return customer.getMail();

            }

            return null;

        }

        // ab hier das Thema ändern

        @Override public boolean isCellEditable(int row, int col) { return true; }

        @Override

        public void setValueAt(Object value, int row, int col) {

            Customer customer = customers.get(row);

            String text = value == null ? "" : value.toString();


            switch(col) {

                case 0: customer.setId(text); break;

                case 1: customer.setMail(text); break;

            }


            fireTableCellUpdated(row, col);

        }


        // von TableModel unabhängige Methoden,

        // so dass die JTable davon mitbekommt       

        public void add(Customer customer) {

            int row = getRowCount();

            customers.add(customer);

            fireTableRowsInserted(row, row);

        }

        public void remove(int row) {

            if (row < 0 || row >= getRowCount()) return;


            customers.remove(row);

            fireTableRowsDeleted(row, row);

        }   

    }



    public void run() {

        List<Customer> customers = new ArrayList<>();

        CustomersTableModel model = new CustomersTableModel(customers);

        JTable table = new JTable(model);


        JButton add = new JButton(" + ");

        add.addActionListener(e -> model.add(new Customer("", "")));

        JButton remove = new JButton(" - ");

        remove.addActionListener(e -> model.remove(table.getSelectedRow()));

        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));

        buttons.add(add);

        buttons.add(remove);


        JFrame frame = new JFrame();

        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        frame.add(new JScrollPane(table));

        frame.add(buttons, BorderLayout.SOUTH);

        frame.pack();

        frame.setVisible(true);

    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> new Test().run());

    }

}[/code]


Hier dient die List direkt als "Repository" und die Änderungen gehen unmittelbar in die Customer-Objekte bzw. die List ein.



Oben