我想设计这个JTable。
目标是用户能够通过双击来编辑单元格。任何更改都应该能够保存并稍后存储在数据库中。
我的代码如下:
public class BirthGUI extends JFrame implements TableModelListener {
//..//
//-------------------- BIRTH TABLE --------------------
table = new JTable();
table.setModel(myModel);
myModel.reloadBirthJTable();
table.getColumnModel().getColumn(0).setPreferredWidth(100);
table.getColumnModel().getColumn(1).setPreferredWidth(80);
table.getColumnModel().getColumn(2).setPreferredWidth(115);
table.setRowHeight(20);
JScrollPane scroller = new JScrollPane(table );
table.setBounds(49, 85, 295, 374);
table.getModel().addTableModelListener(this);
panel.add(scroller,BorderLayout.CENTER);
@Override
public void tableChanged(TableModelEvent e) {
System.out.println("TableModelEvent triggered!");
int row = e.getFirstRow();
int column = e.getColumn();
Object test = myModel.getValueAt(row, column);
System.out.println("row: " + row + " column: " + column);
System.out.println(test.toString());
}
和我的TableModel:
public class BirthTableModel extends DefaultTableModel {
private String[] columnNames = {"Date", "Children", "Complications/Comments"}; //column header labels
private Object[][] data = new Object[20][3];
private List<Birth> list;
public void reloadBirthJTable() {
System.out.println("loading birth table..");
for(int i=0; i<20; i++){
data[i][0] = "";
data[i][1] = "";
data[i][2] = "";
this.addRow(data);
}
}
public void clearJTable() {
this.setRowCount(0);
}
@Override
public void addRow(Object[] arg0) {
// TODO Auto-generated method stub
super.addRow(arg0);
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public Class getColumnClass(int c) {
for(int rowIndex = 0; rowIndex < getRowCount(); rowIndex++) {
Object[] row = data[rowIndex];
if (row[c] != null) {
return getValueAt(rowIndex, c).getClass();
}
}
return String.class;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
}
问题在于,当我双击它们并且触发tableChanged()后,单元格是可编辑的,但是当单元格失去焦点时,我对它们所做的任何更改都会被删除...
修改单元格时的输出是:
loading birth table..
TableModelEvent triggered!
row: 1 column: 0
TableModelEvent triggered!
row: 0 column: 0
所以test
似乎是空的..
答案 0 :(得分:5)
建议:
fire***(...)
通知方法。addRow(...)
方法。AbstractTableModel的一个例子:
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.*;
public class TestTableModel {
public static void main(String[] args) {
BirthTableModel2 dm2 = new BirthTableModel2();
JTable table = new JTable(dm2);
JOptionPane.showMessageDialog(null, new JScrollPane(table));
dm2.reloadBirthJTable();
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
}
// I had to guess at this class
class Birth {
private Date date;
private String children;
private String comments;
public Birth(Date date, String children, String comments) {
this.date = date;
this.children = children;
this.comments = comments;
}
public Date getDate() {
return date;
}
public String getChildren() {
return children;
}
public String getComments() {
return comments;
}
public void setDate(Date date) {
this.date = date;
}
public void setChildren(String children) {
this.children = children;
}
public void setComments(String comments) {
this.comments = comments;
}
}
@SuppressWarnings("serial")
class BirthTableModel2 extends AbstractTableModel {
public final static String[] COLUMN_NAMES = { "Date", "Children",
"Complications/Comments" }; // column header labels
private List<Birth> birthList = new ArrayList<>();
@Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 0) {
return Date.class;
}
return super.getColumnClass(columnIndex);
}
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
@Override
public String getColumnName(int column) {
return COLUMN_NAMES[column];
}
@Override
public int getRowCount() {
return birthList.size();
}
public void reloadBirthJTable() {
System.out.println("loading birth table..");
clearModel();
for (int i = 0; i < 20; i++) {
addRow();
}
}
public void clearModel() {
birthList.clear();
fireTableDataChanged();
}
public void addRow() {
birthList.add(new Birth(null, "", ""));
fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int colIndex) {
if (rowIndex < 0 || rowIndex >= getRowCount()) {
// throw exception
}
if (colIndex < 0 || colIndex >= getColumnCount()) {
// throw exception
}
Birth birth = birthList.get(rowIndex);
switch (colIndex) {
case 0:
return birth.getDate();
case 1:
return birth.getChildren();
case 2:
return birth.getComments();
}
return null;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int colIndex) {
if (rowIndex < 0 || rowIndex >= getRowCount()) {
// throw exception
}
if (colIndex < 0 || colIndex >= getColumnCount()) {
// throw exception
}
Birth birth = birthList.get(rowIndex);
switch (colIndex) {
case 0:
birth.setDate((Date)aValue);
break;
case 1:
birth.setChildren(aValue.toString());
break;
case 2:
birth.setComments(aValue.toString());
}
fireTableRowsUpdated(rowIndex, rowIndex);
}
}