2009-07-24 18 views
33

Swing'i kullanan küçük bir Java masaüstü uygulamasına sahibim. Farklı tiplerdeki bazı giriş alanlarına (JTextField, JComboBox, JSpinner, JFormattedTextField) sahip bir veri girişi diyaloğu vardır. JFormattedTextFields'ı formda sekme yaparak veya fareyle tıklatarak etkinleştirdiğimde, içerdiği tüm metni seçmesini isterim. Bu şekilde, kullanıcılar sadece yazmaya başlayıp varsayılan değerlerin üzerine yazabilir.Odaklandığı zaman JFormattedTextField'taki tüm metinler nasıl seçilir?

Bunu nasıl yapabilirim? Ben FocusAdapter'ın focusGalined() yöntemi çağrılsa da (aşağıdaki kod örneğine bakın), JFormattedTextField üzerinde selectAll() çağıran bir FocusListener/FocusAdapter kullanmıştım.

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

Herhangi bir fikir? Komik olan şey, metnin tümünün seçilmesi, en azından formda sekmelerken hem JTextField hem de JSpinner için varsayılan davranıştır.

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

cevap

65

SwingUtilities.invokeLater ile çağrı sarın. o processFocusEvent göreli olarak adlandırılır oluş saatine bağlı olacağını hep work..since olmayabilir bir focusListener kullanma

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

:

Bir emin atış yol JFormattedTextField genişletmek ve processFocusEvent yöntemini geçersiz etmektir . Eğer tıpkı tüm metin alanları için bu isterseniz Yukarıdakilere ek olarak

+3

sayesinde o kadar. Ben sadece NumberFormatter selectAll()? –

+3

Evet öyle. Değeri biçimlendirir ve metni sıfırlar. –

+1

+1 Buna ihtiyacım vardı, bunu nasıl yapamayacağımı anında hatırlayamadım, kendim googled ve hemen bu cevabı buldum. Teşekkürler! –

6

sne JFormattedTextField kayıp odak kazanmıştır/odakta biçimlendirmek için processFocusEvent kıldığından: beklemede olan tüm AWT olayları işlendikten sonra ne olacak, böylece

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 kodu hafifçe geliştirilebilir. Odaklama bir JTextField öğesinden başka bir tür bileşene (böyle bir tuşa) geçtiğinde, son otomatik seçim silinmez. Bu şekilde düzeltilebilir:

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

Bu tür eski biliyorum ama invokeLater olmadan, daha temiz bir çözüm geldi:

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

tüm durumlarda benim için çalışır +1 – mKorbel

İlgili konular