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

时间:2009-07-24 15:09:52

标签: 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();
    }
});

有什么想法吗?有趣的是,选择它的所有文本显然是JTextField和JSpinner的默认行为,至少在表格中是否有标签。

5 个答案:

答案 0 :(得分: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();
            }
        });
    }
});

答案 1 :(得分: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 :(得分: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();
        }
    }

}

答案 3 :(得分: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();  
                }   
            });  
        }  
    };

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

答案 4 :(得分: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();
                            }
                    });

            }
        }
    });