Как выбрать весь текст в JFormattedTextField, когда он получает фокус?
У меня есть небольшое настольное приложение для Java, которое использует Swing. Существует диалог ввода данных с некоторыми полями ввода разных типов (JTextField, JComboBox, JSpinner, JFormattedTextField). Когда я активирую JFormattedTextFields либо путем табуляции по форме, либо путем щелчка мышью, я бы хотел, чтобы он отобразил весь текст, который он в настоящее время содержит. Таким образом, пользователи могут просто начать вводить и перезаписывать значения по умолчанию.
Как я могу это сделать? Я использовал FocusListener/FocusAdapter, который вызывает selectAll() на JFormattedTextField, но он ничего не выбирает, хотя вызван метод focusAction Focus() (см. Пример кода ниже).
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, по крайней мере, при табуляции через форму.
Ответы
Ответ 1
Оберните свой вызов с помощью 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();
}
});
}
});
Ответ 2
В дополнение к вышесказанному, если вы хотите это для всех текстовых полей, которые вы можете просто сделать:
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();
}
});
}
}
});
Ответ 3
Я знаю, что это довольно старый, но я придумал более чистое решение, без 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();
}
}
}
Ответ 4
Это потому, что поле JFormattedText переопределяет processFocusEvent для форматирования фокуса, полученного/потерянного фокуса.
Один верный способ - расширить 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 может не всегда работать. Поскольку это будет зависеть от времени, в течение которого оно вызывается относительно processFocusEvent.
Ответ 5
Код 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();
}
});
}
}
});