2011-11-17 3 views
10

JTable의 기본 동작은 입력을 시작할 때 내용에 추가하고 클릭 할 때 클릭 한 위치에 캐럿을 배치하는 것입니다. 이 두 가지의 동작이 변경되기를 원하기 때문에 셀을 편집 할 때 입력하거나 클릭 한 다음 입력하여 내용을 바꿉니다. 그러나 셀을 클릭 한 다음 캐럿 위치를 변경하면 콘텐츠를 유지할 수 있도록 변경할 수 있습니다.편집 할 때 JTable 셀의 모든 텍스트를 선택하지만 입력 할 때 텍스트를 선택하지 않는 방법은 무엇입니까?

세포 편집기가 셀 편집기를 SwingUtilities.invokeLater (elsewhere 참고) 내부를 모두 선택하는 것으로 바꾸지 만 셀을 편집 할 때 모두 선택하는 방법을 알고 있지만 입력 동작이 중단됩니다. 이 작업을 수행하고 셀에 입력을 시작하면 먼저 입력 된 문자가 문자열에 추가 된 다음 선택됩니다 (그러나 선택은 보이지 않습니다!). 다른 문자를 입력하면 내용이 해당 문자로 바뀝니다.

강조 표시된 (편집하는 것이 아닌) 셀을 입력 할 때 내용을 즉시 바꿀 수있는 방법이 있지만 셀을 클릭 할 때 모두 선택 하시겠습니까? 여담으로

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

, 왜 안 AbstractCellEditor 또는 DefaultCellEditor(JTextField textField)을 연장 : 당신의 getTableCellEditorComponent() 구현에서

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_ 이유로 중지되거나 취소 될 때 리스너에 알리지 않습니다 (예 : enter를 누르는 것과 같음). 필요한 항목을 보려면 DefaultCellEditor의 소스를 참조하십시오. – kleopatra

+0

보다 ks. 고쳤다. –

답변

2

, 다음과 같은 추가 : 여기

내가 cellEditor가 사용하는 코드입니다? How to Use Tables: Using Other Editors을 참조하십시오.

부록 : Table Select All RendererTable Select All Editor도 참조하십시오. 나는이 사건에 대한 찾을 수

+0

감사합니다. 저는 키보드 나 마우스로 셀을 탐색 한 이후로 항상 isSelected가 사실이라고 생각했습니다. 그래서 무시했습니다. –

+0

나는 과거에 AbstractCellEditor를 확장하면서 실험했지만, 결국이 점에 착수했다. 더 이상 왜 몰라. –

+0

나는 청취자 때문에 (위의 주석 참조) 주변을 다시 바꿔 놓았고'ui'는'JTextField' 내부에서 보호되어 있습니다. 그래서 이것이 내가 이런 식으로했던 이유입니다. Hell, 나는 (내가 지금 발견 한 것처럼) 왜 UIManager 대신에 DefaultLookup 클래스를 사용하지 않았는지 알지 못한다. (아마 internets의 놈 코드를 복사했을 것이다.) –

0

가장 깨끗한 해결책은 편집 트리거 된 방법의 cellEditor가 JTable로의 editCellAt을 덮어 쓰기 알려이었다

@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; 
    } 
} 
관련 문제