TableCellEditor,对话框不更新值

时间:2012-08-18 18:17:47

标签: java swing jtable tablecelleditor

我正在使用自定义单元格编辑器编写JTable,打开一个对话框,允许用户在第二个表中编辑更多值。问题是,第二个表中的更改没有反映在第一个表中,并且基本上丢失了。我使用了here提供的示例作为指导。这是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;
    } 
} 

这是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();
        }

    }

}

1 个答案:

答案 0 :(得分:2)

您的问题提到了两个表,但只显示了DefaultTableModel的一个子类。要更新table中的SizeClassEditor,您应该使用model更新其setValueAt()。您应该使用fireTableDataChanged()从编辑器更新模型。