2009-07-24 3 views
33

스윙을 사용하는 작은 자바 데스크톱 앱이 있습니다. 서로 다른 유형의 입력 필드가있는 데이터 입력 대화 상자가 있습니다 (JTextField, JComboBox, JSpinner, JFormattedTextField). 폼을 탭 이동하거나 마우스로 클릭하여 JFormattedTextFields를 활성화하면 현재 포함 된 모든 텍스트를 선택하고 싶습니다. 그렇게하면 사용자는 입력을 시작하고 기본값을 덮어 쓸 수 있습니다.JFormattedTextField가 포커스를 얻었을 때 모든 텍스트를 선택하는 방법은 무엇입니까?

어떻게하면됩니까? FocusAdapter의 focusGained() 메서드가 호출되었지만 (아래 코드 예제 참조) JFormattedTextField에서 selectAll()을 호출하는 FocusListener/FocusAdapter를 사용했지만 아무 것도 선택하지 않았습니다.

private javax.swing.JFormattedTextField pricePerLiter; 
// ... 
pricePerLiter.setFormatterFactory(
    new JFormattedTextField.AbstractFormatterFactory() { 
    private NumberFormatter formatter = null; 
    public JFormattedTextField.AbstractFormatter 
     getFormatter(JFormattedTextField jft) { 
     if (formatter == null) { 
      formatter = new NumberFormatter(new DecimalFormat("#0.000")); 
      formatter.setValueClass(Double.class); 
     } 
     return formatter; 
    } 
}); 
// ... 
pricePerLiter.addFocusListener(new java.awt.event.FocusAdapter() { 
    public void focusGained(java.awt.event.FocusEvent evt) { 
     pricePerLiter.selectAll(); 
    } 
}); 

아이디어가 있으십니까? 재미있는 점은 적어도 모든 텍스트를 선택하는 것이 적어도 폼을 탭 이동할 때 JTextField와 JSpinner의 기본 동작이라는 것입니다.

pricePerLiter.addFocusListener(new java.awt.event.FocusAdapter() { 
    public void focusGained(java.awt.event.FocusEvent evt) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       pricePerLiter.selectAll(); 
      } 
     }); 
    } 
}); 

답변

65

은 SwingUtilities.invokeLater에 전화를 감 쌉니다. 는 processFocusEvent에 상대적으로 호출되는 시점에 따라 달라 항상을 work..since하지 수있는 focusListener를 사용

new JFormattedTextField("...") { 
     protected void processFocusEvent(FocusEvent e) { 
      super.processFocusEvent(e); 
      if (e.isTemporary()) 
       return; 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        selectAll(); 
       } 
      }); 
     } 
    }; 

:

하나 확실 촬영 방법의 JFormattedTextField를 확장하고 processFocusEvent 메소드를 오버라이드 (override)하는 것입니다 . 당신은 당신이 단지 수있는 모든 텍스트 필드에 대해이 작업을하려면 위의 외에도

+3

덕분에, 그것 뿐이다. NumberFormatter가 selectAll()을 실행 취소하는 작업을 수행하고있는 것으로 추측 할 수 있습니까? –

+3

예. 값을 형식화하고 텍스트를 다시 설정합니다. –

+1

+1 필요, 즉시 내 자신을 수행하는 방법을 기억하지 못했습니다, 봤 거든 즉시이 대답을 발견. 감사! –

6

그게 전부를 JFormattedTextField의 분실 포커스를 얻은/초점 포맷을 processFocusEvent을 무시하기 때문에 : 그것은 보류중인 모든 AWT 이벤트가 처리 된 후 일어날 수 있도록

14

는 :

KeyboardFocusManager.getCurrentKeyboardFocusManager() 
    .addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() 
{ 
    public void propertyChange(final PropertyChangeEvent e) 
    { 
     if (e.getNewValue() instanceof JTextField) 
     { 
      SwingUtilities.invokeLater(new Runnable() 
      { 
       public void run() 
       { 
        JTextField textField = (JTextField)e.getNewValue(); 
        textField.selectAll(); 
       } 
      }); 

     } 
    } 
}); 
2

camickr의 코드를 약간 향상시킬 수있다. 포커스가 JTextField에서 다른 종류의 구성 요소 (예 : 버튼)로 전달되면 마지막 자동 선택이 지워지지 않습니다. 그것은이 방법으로 해결할 수 있습니다 :

KeyboardFocusManager.getCurrentKeyboardFocusManager() 
     .addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() 
    { 
     @Override 
     public void propertyChange(final PropertyChangeEvent e) 
     { 

      if (e.getOldValue() instanceof JTextField) 
      { 
        SwingUtilities.invokeLater(new Runnable() 
        { 
          @Override 
          public void run() 
          { 
            JTextField oldTextField = (JTextField)e.getOldValue(); 
            oldTextField.setSelectionStart(0); 
            oldTextField.setSelectionEnd(0); 
          } 
        }); 

      } 

      if (e.getNewValue() instanceof JTextField) 
      { 
        SwingUtilities.invokeLater(new Runnable() 
        { 
          @Override 
          public void run() 
          { 
            JTextField textField = (JTextField)e.getNewValue(); 
            textField.selectAll(); 
          } 
        }); 

      } 
     } 
    }); 
7

나는이 세 종류의 알고,하지만 난 invokeLater없이 청소기 솔루션을 내놓았다 :

private class SelectAllOfFocus extends FocusAdapter { 

    @Override 
    public void focusGained(FocusEvent e) { 
     if (! e.isTemporary()) { 
      JFormattedTextField textField = (JFormattedTextField)e.getComponent(); 
      // This is needed to put the text field in edited mode, so that its processFocusEvent doesn't 
      // do anything. Otherwise, it calls setValue, and the selection is lost. 
      textField.setText(textField.getText()); 
      textField.selectAll(); 
     } 
    } 

} 
+0

이 작동합니다 +1 – mKorbel

관련 문제