Ячейка JTable не обновляется при нажатии Enter

1

У меня есть приложение, которое имеет 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;
}


}

Возникает вопрос: нужно ли добавлять какие-либо пользовательские методы или код, чтобы делать то, что я упоминал?

Теги:
swing
jtable
abstracttablemodel

2 ответа

2
Лучший ответ

но когда я нажимаю кнопку ввода или вкладку, чтобы сохранить новый контент, который он отражает, как это было раньше.

Ваша 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);
}
2

Я надеялся, что вы сможете сделать это с помощью специального 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, мне нужно угадать его типы данных и функциональность

  • 0
    Спасибо за объяснение, но этот код выбирает только ячейку для редактирования, когда она находится в фокусе. И когда я нажимаю клавишу ввода после редактирования, ничего не происходит .. Есть идеи?
  • 0
    Можете ли вы объяснить «нажмите ввод»?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню