Jonno_FTW
Jonno_FTW

Reputation: 8809

TableCellEditor with a dialog not updating values

I am writing a JTable with a custom cell editor that opens up a dialog to allow the user to edit some more values in a 2nd table. The problem is, that the changes in the 2nd table are not reflected in the first table and are basically lost. I used the example provided here as a guide. Here is the CellEditor:

private class SizeClassTableCellEditor extends AbstractCellEditor 
                                       implements TableCellEditor, ActionListener{ 
    /**
     * 
     */
    protected static final String EDIT = "edit";
    private ArrayList<SizeClass> sizeClasses;
    private JButton button;
    private SizeClassEditor editor;
    public SizeClassTableCellEditor(){ 

        button = new JButton();
        button.setActionCommand(EDIT);
        button.addActionListener(this);
        button.setBorderPainted(false);

        editor = new SizeClassEditor(this);

    }

    @Override
    public Object getCellEditorValue() {
        System.out.println("Get Cell editor value was called");
        return sizeClasses;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        System.out.println("editting sc");
        if(EDIT.equals(e.getActionCommand())) {
            // User clicked the cell, bring up the editor
            System.out.println("Editing");
            editor.setVisible(true);
            editor.setSizeClasses(sizeClasses);
            editor.setAlwaysOnTop(true);
            fireEditingStopped();

        } else {
            System.out.println("Save button of dialogue was pressed");
            if(editor.validateInput()) {
                sizeClasses = editor.getSizeClasses();
                editor.setVisible(false);
                System.out.println("size classes are: "+sizeClasses);
                model.fireTableDataChanged();
            } else {
                // user needs to correct input
            }
        }

    }

    @Override
    public Component getTableCellEditorComponent(JTable table,
            Object value, boolean isSelected, int row, int column) {
        sizeClasses = (ArrayList<SizeClass>) value;
        return button;
    } 
} 

And here is the SizeClassEditor:

import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import java.awt.BorderLayout;


public class SizeClassEditor extends JFrame {

    /**
     * 
     */
    private static final long serialVersionUID = 6909421034651884335L;
    private JTable table;
    private SizeClassTableModel model;
    public SizeClassEditor(ActionListener lstn){
        setTitle("Edit Size Classes");
        model = new SizeClassTableModel();

        table = new JTable(model);
        JPanel panel = new JPanel();
        getContentPane().add(panel);
        panel.setLayout(new BorderLayout());

        panel.add(new JScrollPane(table),BorderLayout.CENTER);

        JPanel btn_panel = new JPanel();
        panel.add(btn_panel, BorderLayout.SOUTH);

        JButton btnSave = new JButton("Save");
        btn_panel.add(btnSave);
        btnSave.addActionListener(lstn);
        pack();
    }
    public void addRow(SizeClass sc) {
        model.addRow(new Object[] {sc.getMin(),sc.getMax(),sc.getMortality(),sc.getGrowShrinkP(),sc.getGrowShrinkPC()});
    }
    public void setSizeClasses(ArrayList<SizeClass>  sc) {
        model.setRowCount(0);
        for (SizeClass sizeClass : sc) {
            addRow(sizeClass);
        }
    }
    public boolean validateInput() {
        boolean valid = true;
        for(int i = 0; i < model.getRowCount(); i++) {
            // Should probably set background colours for the cell
            valid &= (Integer) table.getValueAt(i, 0) < (Integer) table.getValueAt(i, 1);
            for(int j = 2; j < 4; j++) 
                valid &= ((Double) table.getValueAt(i, j)) < 1 && ((Double) table.getValueAt(i, j)) >= 0;
        }
        return valid;
    }

    public ArrayList<SizeClass> getSizeClasses() {
         ArrayList<SizeClass> scs = new ArrayList<SizeClass>();
         for (int i = 0; i < table.getRowCount(); i++) {
            scs.add(new SizeClass(
                  (Integer)  table.getValueAt(i, 0),
                  (Integer)  table.getValueAt(i, 1),
                  (Double)  table.getValueAt(i, 2),
                  (Double)  table.getValueAt(i, 3),
                  (Double)  table.getValueAt(i, 4)));
        }
         return scs;
    }
    private class SizeClassTableModel  extends DefaultTableModel{
        /**
         * 
         */
        private static final long serialVersionUID = 6771833776664184864L;
        private final Object[] columns = new Object[] {"Min","Max","Mortality","growshrinkp","growshrinkp (c)"}; 
        public SizeClassTableModel() {
            for (Object i : columns) {
                addColumn(i);
            }
        } 
        @Override
        public int getColumnCount() {
            return columns.length;
        }

        @Override
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

    }

}

Upvotes: 1

Views: 609

Answers (1)

trashgod
trashgod

Reputation: 205875

Your question mentions two tables, but only a single subclass of DefaultTableModel is shown. To update the table in SizeClassEditor, you should update its model using setValueAt(). You should not update the model from your editor using fireTableDataChanged().

Upvotes: 2

Related Questions