Подтвердить что ты не робот

Как выбрать весь текст в 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, по крайней мере, при табуляции через форму.

4b9b3361

Ответ 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();
                            }
                    });

            }
        }
    });