2009-07-24 84 views
33

我有一個使用Swing的小型Java桌面應用程序。有一個數據輸入對話框,其中包含一些不同類型的輸入字段(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的默認行爲,至少在通過表單標籤時。

回答

65

纏上SwingUtilities.invokeLater您的通話因此將所有掛起的AWT事件被處理後才發生:因爲JFormattedTextField上覆蓋processFocusEvent對焦點上漲/聚焦丟失格式化

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

謝謝,僅此而已。我只能猜測NumberFormatter正在做一些解除selectAll()的事情? – 2009-07-24 16:26:34

+3

是的。它格式化值並重置文本。 – 2009-07-24 16:47:04

6

那。

一個確保拍攝方法是擴展JFormattedTextField上並覆蓋processFocusEvent方法,而:

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

使用focusListener的可能並不總是work..since這將取決於在它被稱爲相對的processFocusEvent時間。

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

} 
相關問題