如何在焦点上选择JFormattedTextField中的所有文本?

Rob*_*ier 33 java user-interface swing

我有一个使用Swing的小型Java桌面应用程序.有一个数据输入对话框,其中包含一些不同类型的输入字段(JTextField,JComboBox,JSpinner,JFormattedTextField).当我通过在表单中​​进行选项卡或通过鼠标单击来激活JFormattedTextField时,我希望它选择它当前包含的所有文本.这样,用户就可以开始输入并覆盖默认值.

我怎样才能做到这一点?我确实使用了一个在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();
    }
});
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?有趣的是,选择它的所有文本显然是JTextField和JSpinner的默认行为,至少在表格中选项时是这样.

Eug*_*kov 66

使用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();
            }
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,就是这样.我只能猜测NumberFormatter正在做一些撤消selectAll()的事情? (3认同)
  • 是的,它确实.它格式化值并重置文本. (3认同)
  • +1 需要这个,我自己无法立即记住如何做到这一点,用谷歌搜索并立即找到了这个答案。谢谢! (2认同)
  • 因为 `invokeLater` 确保所有挂起的 AWT 事件都已处理 (2认同)

cam*_*ckr 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();
                }
            });

        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Adr*_*erc 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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)


pav*_*van 6

那是因为JFormattedTextfield重写了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();  
                }   
            });  
        }  
    };
Run Code Online (Sandbox Code Playgroud)

使用focusListener可能并不总是有效..因为它取决于相对于processFocusEvent调用它的时间.