Java 获得焦点时如何选择 JFormattedTextField 中的所有文本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1178312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to select all text in a JFormattedTextField when it gets focus?
提问by Robert Petermeier
I have a small Java desktop app that uses Swing. There is a data entry dialog with some input fields of different types (JTextField, JComboBox, JSpinner, JFormattedTextField). When I activate the JFormattedTextFields either by tabbing through the form or by clicking it with the mouse, I would like it to select all the text that it currently contains. That way, users could just start typing and overwrite the default values.
我有一个使用 Swing 的小型 Java 桌面应用程序。有一个数据输入对话框,其中包含一些不同类型的输入字段(JTextField、JComboBox、JSpinner、JFormattedTextField)。当我通过切换表单或用鼠标单击它来激活 JFormattedTextFields 时,我希望它选择它当前包含的所有文本。这样,用户就可以开始输入并覆盖默认值。
How can I do that? I did use a FocusListener/FocusAdapter that calls selectAll() on the JFormattedTextField, but it doesn't select anything, although the FocusAdapter's focusGained() method is called (see code sample below).
我怎样才能做到这一点?我确实使用了在 JFormattedTextField 上调用 selectAll() 的 FocusListener/FocusAdapter,但它没有选择任何内容,尽管调用了 FocusAdapter 的 focusGained() 方法(请参阅下面的代码示例)。
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();
}
});
Any ideas? The funny thing is that selecting all of its text apparently is the default behavior for both JTextField and JSpinner, at least when tabbing through the form.
有任何想法吗?有趣的是,选择其所有文本显然是 JTextField 和 JSpinner 的默认行为,至少在通过选项卡浏览表单时是这样。
采纳答案by Eugene Ryzhikov
Wrap your call with SwingUtilities.invokeLater so it will happen after all pending AWT events have been processed :
用 SwingUtilities.invokeLater 包装您的调用,以便在处理完所有挂起的 AWT 事件后发生:
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();
}
});
}
});
回答by pavan
Thats because the JFormattedTextfield overrides processFocusEvent to format on focus gained/focus lost.
那是因为 JFormattedTextfield 覆盖 processFocusEvent 以格式化获得焦点/失去焦点。
One sure shot way is to extend JFormattedTextField and override the processFocusEvent method :
一种可靠的方法是扩展 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();
}
});
}
};
Using a focusListener might not always work..since it would depend on the time at which it is called relative to the processFocusEvent.
使用 focusListener 可能并不总是有效..因为它取决于相对于 processFocusEvent 调用它的时间。
回答by camickr
In addition to the above, if you want this for all text fields you can just do:
除了上述内容,如果您希望所有文本字段都使用此功能,您可以执行以下操作:
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();
}
});
}
}
});
回答by user231765
The code of camickr can be slightly improved. When the focus passes from a JTextField to another kind of component (such a button), the last automatic selection does not get cleared. It can be fixed this way:
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();
}
});
}
}
});
回答by Adrien Clerc
I know this is kind of old, but I came up with a cleaner solution, without invokeLater:
我知道这有点旧,但我想出了一个更干净的解决方案,没有 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();
}
}
}