2009-07-24 49 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(); 
     } 
    } 

} 
相关问题