web-dev-qa-db-ja.com

フォーカスを得たときにJFormattedTextFieldのすべてのテキストを選択する方法は?

小さなJavaデスクトップアプリがあります。さまざまなタイプ(JTextField、JComboBox、JSpinner、JFormattedTextField)のいくつかの入力フィールドを持つデータ入力ダイアログがあります。JFormattedTextFieldsをアクティブにすると、フォームをタブで移動するか、フォームをマウスでクリックして、フォームに現在含まれているすべてのテキストを選択し、ユーザーが入力を開始してデフォルト値を上書きできるようにします。

どうやってやるの? 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の両方のデフォルトの動作であることです。

33

呼び出しを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();
            }
        });
    }
});
66
Eugene Ryzhikov

上記に加えて、すべてのテキストフィールドにこれが必要な場合は、次のようにすることができます:

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

        }
    }
});
14
camickr

私はこれが少し古いことを知っていますが、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();
        }
    }

}
7
Adrien Clerc

これは、JFormattedTextfieldがprocessFocusEventをオーバーライドして、フォーカス獲得/フォーカス喪失でフォーマットするためです。

確実な方法の1つは、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に関連して呼び出される時間に依存するためです。

6
pavan

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

            }
        }
    });
2
user231765