【问题标题】:Why is cancelCellEditing() not called when pressing escape while editing a JTable cell?为什么在编辑 JTable 单元格时按转义键不调用取消单元格编辑()?
【发布时间】:2011-05-28 07:12:49
【问题描述】:

我有一个可编辑的 JTable 并设置了一个 DefaultCellEditor,如下所示:

    colModel.getColumn( 1 ).setCellEditor( new DefaultCellEditor( txtEditBox ) {
        // ...
        @Override
        public void cancelCellEditing() {
            super.cancelCellEditing();
            // handling the event
        }
        // ...
    }

但是,在编辑该列中的单元格时按下escape,虽然编辑模式已经结束,但不会调用该方法。任何想法为什么?难道我做错了什么?有没有办法处理这个问题(除了手动添加 KeyListener 之外)?

【问题讨论】:

    标签: java jtable tablecelleditor


    【解决方案1】:

    官方方式:可以注册一个CellEditorListener:AbstractCellEditor.addCellEditorListener(...)。如果编辑被取消,应该调用editingCanceled(ChangeEvent e)。 由于一个 SUN 错误 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788481editingCanceled 未被调用 :(

    作为解决方法,您可以为 ESCAPE 键注册自己的操作并自行处理。但它不适用于调整事件大小。

    另一种解决方案(又快又脏;-)):覆盖方法 JTable.removeEditor() 并在 super 调用之后插入您的代码。

    【讨论】:

      【解决方案2】:

      我也有这个问题。我写了另一个涉及 ActionListener 和 FocusListener 的解决方法。就是这样:

      public class TableEditorListenerHelper {
      
      // dealing with events
      private final EventListenerList listeners = new EventListenerList();
      private ChangeEvent changeEvent;
      
      // cell editor that we're helping
      private CellEditor editor;
      
      // transient state
      private boolean editing = false;
      private JTable table;
      
      public TableEditorListenerHelper(CellEditor editor, JTextField field) {
          this.editor = editor;
          field.addActionListener(new ActionListener() {
              @Override public void actionPerformed(ActionEvent e) {
                  fireEditingStopped();
              }
          });
          field.addFocusListener(new FocusListener() {
      
              @Override public void focusGained(FocusEvent e) {
                  editing = true;
              }
      
              @Override public void focusLost(FocusEvent e) {
                  JTable table = TableEditorListenerHelper.this.table;
                  if (editing && isEditing(table)) {
                      fireEditingCanceled();
                  }
              }
      
              private boolean isEditing(JTable table) { // a hack necessary to deal with focuslist vs table repaint
                  return table != null && table.isEditing();
              }
      
          });
      }
      
      public void setTable(JTable table) {
          this.table = table;
      }
      
      public void addCellEditorListener(CellEditorListener l) {
          listeners.add(CellEditorListener.class, l);
      }
      
      public void removeCellEditorListener(CellEditorListener l) {
          listeners.remove(CellEditorListener.class, l);
      }
      
      public CellEditorListener[] getCellEditorListeners() {
          return listeners.getListeners(CellEditorListener.class);
      }
      
      protected void fireEditingCanceled() {
          for (CellEditorListener l : getCellEditorListeners()) {
              l.editingCanceled(getOrCreateEvent());
          }
          resetEditingState();
      }
      
      protected void fireEditingStopped() {
          for (CellEditorListener l : getCellEditorListeners()) {
              l.editingStopped(getOrCreateEvent());
          }
          resetEditingState();
      }
      
      private void resetEditingState() {
          table = null;
          editing = false;
      }
      
      private ChangeEvent getOrCreateEvent() {
          return changeEvent = changeEvent == null ? new ChangeEvent(editor) : changeEvent;
      }
      

      Here你可以找到更完整的解决方案。

      【讨论】:

        【解决方案3】:

        另一种方法修复这个bug

        jTable.addPropertyChangeListener("tableCellEditor", e -> {
            Object o = e.getOldValue();
            if (o instanceof DefaultCellEditor) {
                ((DefaultCellEditor) o).cancelCellEditing();
            }
        });
        

        【讨论】:

          猜你喜欢
          • 2014-05-27
          • 2011-09-27
          • 2019-04-30
          • 1970-01-01
          • 1970-01-01
          • 2023-03-23
          • 2013-05-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多