【问题标题】:JTable Cell Isn't Updated On Enter Click输入单击时未更新 JTable 单元格
【发布时间】:2015-04-09 13:22:23
【问题描述】:

我有一个包含一些数据的 JTable 的应用程序。所以我添加了数据,它看起来很好。但是当我尝试编辑一个单元格时,我可以编辑它,但是当我点击 enter 或 tab 来保存它反映了以前的新内容..我不知道为什么会这样..我在网上搜索但没有希望..:(

这是表模型类:

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;
}


}

问题是:我是否需要添加任何自定义方法或代码来执行我提到的操作?

【问题讨论】:

    标签: java swing jtable abstracttablemodel


    【解决方案1】:

    但是当我点击 enter 或 tab 来保存新内容时,它会像以前一样反映..

    您的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();,这可能会产生令人讨厌的连锁反应,这可能会使您的程序陷入无限循环,最好避免

      p>

      更新

      你知道,起初,我虽然你没有覆盖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 的来源,我需要猜测它的数据类型和功能

      【讨论】:

      • 感谢您的解释,但此代码仅在聚焦时选择要编辑的单元格。当我在编辑后点击输入时,没有任何反应。有什么想法吗?
      • 你能解释一下“点击进入”吗?
      • 我的意思是:我点击单元格进行编辑..现在我可以编辑它..我输入我需要的内容,现在我想保存新数据..我想点击回车这样做的关键,但现在没有效果
      猜你喜欢
      • 2012-09-24
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      相关资源
      最近更新 更多