2011-11-17 141 views
10

JTable的默认行为是当您开始键入时追加到内容,并在点击时将插入符号放在单击的位置。我希望这些事情的行为都能改变,所以当我编辑单元格时,内容被替换,无论是通过键入还是通过单击然后键入。然而,当我点击一个单元格然后改变插入位置时,我希望内容保留下来,以便我可以更改它。如何在编辑时选择JTable单元格中的所有文本,而不是在输入时选择?

我知道如何在单元格编辑时选择所有单元格,方法是用一个单元格编辑器替换SwingUtilities.invokeLater中的所有单元格(请参阅elsewhere),但这会导致打字行为中断。当我这样做并开始在单元格中输入时,首先将类型化字符附加到字符串中,然后选择它(但该选择是不可见的!),而当键入另一个字符时,内容将被替换。

有没有办法在突出显示(但不是编辑)单元格中键入内容时立即替换内容,但在单击单元格时全选?

这里是我使用的CellEditor的代码:

public class TextFieldCellEditor extends JTextField implements TableCellEditor 
{ 
    private CellEditorListener cellEditorListener = null; 

    private boolean    isInteger   = false; 
    private Object    oldValue; 

    // Start editing 
    @Override 
    public Component getTableCellEditorComponent(JTable table, Object obj, boolean isSelected, int row, int column) 
    { 
     Color color2 = DefaultLookup.getColor(this, ui, "Table.alternateRowColor"); 
     super.setBackground(color2 != null && (row & 1) == 1? color2 : table.getBackground()); 
     super.setForeground(table.getForeground()); 
     super.setBorder(DefaultLookup.getBorder(this, ui, "Table.focusCellHighlightBorder")); 

     super.setText(obj.toString()); 

     isInteger = obj instanceof Integer; 
     if (isInteger) 
     { 
      super.setHorizontalAlignment(SwingConstants.RIGHT); 
      oldValue = obj; 
     } 

     // SwingUtilities.invokeLater(new Runnable() 
     // { 
     // public void run() 
     // { 
     // TextFieldCellEditor.this.selectAll(); 
     // } 
     // }); 

     return this; 
    } 

    // Retrieve e dited value 
    @Override 
    public Object getCellEditorValue() 
    { 
     if (isInteger) 
     { 
      // Try to convert to integer. If input is invalid, revert. 
      try 
      { 
       return new Integer(super.getText()); 
      } 
      catch (NumberFormatException e) 
      { 
       return oldValue; 
      } 
     } 
     return super.getText(); 
    } 

    @Override 
    public boolean isCellEditable(EventObject e) 
    { 
     return true; 
    } 

    @Override 
    public boolean shouldSelectCell(EventObject e) 
    { 
     return true; 
    } 

    @Override 
    public boolean stopCellEditing() 
    { 
     cellEditorListener.editingStopped(new ChangeEvent(this)); 
     return true; 
    } 

    @Override 
    public void cancelCellEditing() 
    { 
     cellEditorListener.editingCanceled(new ChangeEvent(this)); 
    } 

    @Override 
    public void addCellEditorListener(CellEditorListener celleditorlistener) 
    { 
     cellEditorListener = celleditorlistener; 
    } 

    @Override 
    public void removeCellEditorListener(CellEditorListener celleditorlistener) 
    { 
     if (cellEditorListener == cellEditorListener) cellEditorListener = null; 
    } 
} 
+0

这个实现是无效的:a)不支持添加多个监听器b)当_internal_原因停止/取消时,它不会通知它的监听器(如fi按Enter)查看DefaultCellEditor的来源以了解需要什么 – kleopatra

+0

比KS。修复。 –

回答

2

在你getTableCellEditorComponent()实现,添加以下内容:

if (isSelected) { 
    this.selectAll(); 
} 

顺便说一句,为什么不延长AbstractCellEditorDefaultCellEditor(JTextField textField)?另见How to Use Tables: Using Other Editors

附录:另请参阅Table Select All RendererTable Select All Editor

+0

谢谢。我认为这是选择将永远是真实的,因为我导航到单元格,无论是用键盘或鼠标,所以我忽略了它。 –

+0

我尝试过扩展AbstractCellEditor,但最终解决了这个问题。不知道为什么了。 –

+0

由于监听器(见上面的注释),我再次交换了它,并且字段'ui'在'JTextField'内被保护,所以这就是我为什么这样做的原因。地狱,我甚至不知道为什么我用(现在我发现)阻止了'DefaultLookup'类而不是'UIManager'(可能从互联网上复制了一些noob代码) –

0

我能找到的这种情况下,干净的解决方案是要覆盖JTable中的editCellAt并告知编辑是如何引发的CellEditor的:

@Override 
public boolean editCellAt(int row, int column, EventObject e) { 
    cellEditor.setKeyTriggered(e instanceof KeyEvent); 
    return super.editCellAt(row, column, e); 
} 

而且这里是有关CellEditor的代码:

public class MyCellEditor extends DefaultCellEditor { 

    private boolean keyTriggered; 

    public MyCellEditor() { 
     super(new JTextField()); 
     final JTextField textField = (JTextField) getComponent(); 
     textField.addFocusListener(new FocusAdapter() { 
      @Override 
      public void focusGained(FocusEvent e) { 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         if (!keyTriggered) { 
          textField.selectAll(); 
         } 
        } 
       }); 
      } 
     }); 
    } 

    public void setKeyTriggered(boolean keyTriggered) { 
     this.keyTriggered = keyTriggered; 
    } 

    @Override 
    public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) { 
     final JTextField textField = (JTextField) 
       super.getTableCellEditorComponent(table, value, isSelected, row, column); 
     textField.selectAll(); 
     return textField; 
    } 
} 
相关问题