У меня есть приложение, которое имеет JTable для некоторых данных. Поэтому я добавляю данные, и это выглядит хорошо. Но когда я пытаюсь редактировать ячейку, я могу ее редактировать, но когда я нажимаю кнопку ввода или вкладку, чтобы сохранить новый контент, как это было раньше.. Я не знаю, почему это происходит.. Я искал в Интернете, но без надежды.. :(
Вот класс Table Model:
public class TableModel extends AbstractTableModel {
String[] columnNames = { "Col1", "Col2", "Col3", "Col4", "Col5", "Col6" };
private List<Entry> db;
JTable table;
public TableModel(JTable table) {
this.table = table;
}
public void addRow(Entry entry) {
db.add(entry);
fireTableRowsInserted(db.size() - 1, db.size() - 1);
table.editCellAt(db.size() -1, 0);
}
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
public void setData(List<Entry> db) {
this.db = db;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public int getColumnCount() {
return 6;
}
@Override
public int getRowCount() {
return db.size();
}
@Override
public Object getValueAt(int row, int col) {
Entry entry = db.get(row);
try {
switch (col) {
case 0:
return entry.getItem();
case 1:
return entry.getTransPayment();
case 2:
return entry.getEquipPayment();
case 3:
return entry.getGasPayment();
case 4:
return entry.getEquipSparePayment();
case 5:
return entry.getTransSparePayment();
case 6:
return entry.getTotal();
}
} catch (Exception e) {
fireTableDataChanged();
}
return null;
}
}
Возникает вопрос: нужно ли добавлять какие-либо пользовательские методы или код, чтобы делать то, что я упоминал?
но когда я нажимаю кнопку ввода или вкладку, чтобы сохранить новый контент, который он отражает, как это было раньше.
Ваша TableModel
не реализует метод setValueAt(...)
поэтому данные из редактора никогда не сохраняются.
@Override
public void setValueAt(Object value, int row, int column)
{
Entry entry = db.get(row);
switch (column)
{
case 0: entry.setItem(value); break;
case 1: entry.setTransPayment(value); break;
...
}
fireTableCellUpdated(row, column);
}
Я надеялся, что вы сможете сделать это с помощью специального TableCellEditor
, но это оказалось не так.
Вам необходимо предоставить привязку ключа для ключа Enter, который позволит вам связать подходящее действие для ключа, например...
public class EditSelectedCellAction extends AbstractAction {
private JTable table;
public EditSelectedCellAction(JTable table) {
this.table = table;
}
@Override
public void actionPerformed(ActionEvent e) {
int col = table.getSelectedColumn();
int row = table.getSelectedRow();
if (col >= 0 && row >= 0) {
table.editCellAt(row, col);
}
}
}
Затем вам необходимо связать EditSelectedCellAction
с ключом Enter, например...
InputMap im = table.getInputMap(JTable.WHEN_FOCUSED);
ActionMap am = table.getActionMap();
KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
im.put(enterKey, "Action.enter");
am.put("Action.enter", new EditSelectedCellAction(table));
Обратная связь
Никогда не было причин, почему модель должна когда-либо иметь ссылку на любой компонент вида. Модель должна просто не заботиться. Модель может быть связана с несколькими представлениями (в данном случае, с таблицами), что позволяет практически поддерживать ссылку на любой компонент вида.
Вместо этого то, что когда-либо вызывает ваш метод addRow
должно принимать решения об изменении ячейки. Возможно, ваш метод addRow
мог бы вернуть индекс строки.
Кроме того, в методе getValueAt
вы вызываете fireTableDataChanged();
если по какой-то причине что-то пойдет не так, это может создать неприятную цепную реакцию, которая может помещать вашу программу в бесконечную петлю, и ее лучше избегать
обновленный
Вы знаете, во-первых, я, хотя вы не переоценили isCellEditable
, но, как оказалось, вы не переопределяете setValueAt
@Override
public void setValueAt(Object aValue, int rowIndex, int colIndex) {
Entry entry = db.get(rowIndex);
switch (colIndex) {
case 0:
entry.getItem();
break;
case 1:
entry.setTransPayment(aValue);
break;
case 2:
entry.setEquipPayment(aValue);
break;
case 3:
entry.setGasPayment(aValue);
break;
case 4:
entry.setEquipSparePayment(aValue);
break;
case 5:
entry.setTransSparePayment(aValue);
break;
case 6:
entry.setTotal(aValue);
break;
}
fireTableCellUpdated(rowIndex, colIndex);
}
Теперь, поскольку вы не предоставили источник для Entry
, мне нужно угадать его типы данных и функциональность