我正在使用自定义单元格编辑器编写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();
}
}
}
答案 0 :(得分:2)
您的问题提到了两个表,但只显示了DefaultTableModel
的一个子类。要更新table
中的SizeClassEditor
,您应该使用model
更新其setValueAt()
。您应该不使用fireTableDataChanged()
从编辑器更新模型。