2

フォーム(フォーム)にが含まれている場合、フォームのデフォルトボタンを使用すると問題が発生しますJFormattedTextField。このようなフィールドがあるフォームで、フォーカスがある(そして変更された)場合は、[OK ]を2回押して、デフォルトのボタンを「押す」必要があります。なぜそれが起こるのか私は知っていると思います-それは最初のEnterがコミット処理で消費されるからです。

また、回避策を作成することもできました。Formatter有効な編集ごとにコミットするように変更すると、適切な動作が得られますが、これにより、a)フォーマッターを明示的に指定する必要があり、b)「古い」値に戻すことはできません。 (例:Escapeを使用する、またはプログラムで)。

以下のコードは次のことを示しています。上部のフィールドを実行すると、各編集でコミットされ、単一のEnterで機能します(ただし、元に戻すことはできません)。下部のフィールドでは元に戻すことができますが、編集する場合は2つのEnterが必要です。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.text.DateFormatter;

public class ExFrame extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ExFrame frame = new ExFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    /**
     * Create the frame.
     */
    public ExFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JFormattedTextField ff_1, ff_2;

        //ff_1 has modified behavior of commit on each (valid) edit
        DateFormatter f=new DateFormatter();
        f.setCommitsOnValidEdit(true);

        ff_1 = new JFormattedTextField(f);
        ff_1.setValue(new Date());

        //ff_2 has default behavior 
        ff_2 = new JFormattedTextField(new Date());

        contentPane.add(ff_1, BorderLayout.NORTH);
        contentPane.add(ff_2, BorderLayout.SOUTH);

        JButton btnDefault = new JButton("I am default button");
        contentPane.add(btnDefault, BorderLayout.CENTER);
        getRootPane().setDefaultButton(btnDefault);
    }
}

したがって、質問は次のとおりです。Enterでコミットする方法(入力JFormattedTextField 1回だけ検証されます)と、検証に成功した場合、デフォルトのボタンをアクティブにする方法(1回押す)はありますか?

4

4 に答える 4

2

基本的なトリックは、keyBindingメカニズムをだまして、keyStrokeがtextFieldによって処理されなかったと信じ込ませることです。これを実現するには、JFormattedTextFieldをサブクラス化し、そのprocessKeyBindingsをオーバーライドしてfalseを返す必要があります(つまり、「使用できませんでした」)。

何かのようなもの:

JFormattedTextField multiplex = new JFormattedTextField() {
    KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
    @Override
    protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
                                        int condition, boolean pressed) {
        boolean processed = super.processKeyBinding(ks, e, condition,
                                                    pressed);

        if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW
                && enter.equals(ks)) {
            // Returning false will allow further processing
            // of the bindings, eg our parent Containers will get a
            // crack at them and f.i. route to a default button.
            return !isEditValid();
        }
        return processed;
    }

};
multiplex.setValue(new Date());
于 2012-08-15T09:56:25.473 に答える
1

Date / Numberインスタンスの場合、(ほとんどの場合)JFormattedTextFieldよりもJSpinnerを使用する方が適切です。その場合、または、を使用してDateSpinnerModelに設定することしかできません。LocaleSimpleDateFormat

インスタンスの場合(有効な場合) JSpinner不要な文字を削除/フィルタリングするためのドキュメントを追加する必要がありますNumberJTextField

于 2012-02-01T19:19:39.587 に答える
0

Enterは通常、現在の値を受け入れるために使用されるため、JFTFでのEnterもこれを行います。次のようにして無効にすることができます。

ff_1.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), new Object());
ff_2.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), new Object());

さようならそしてクールになりなさい;)

于 2012-08-15T08:31:43.230 に答える
0

あなたの答えはどちらも私のアプリケーションの問題を解決しませんでした。ただし、私の場合、問題の解決策ははるかに簡単であるように見えました。

private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
   add(jTextField1);          //this reacts after the "ENTER" gets pressed
   jButton1.doClick();        //this activates the button with Enter
   jTextField1.setText("");   //this removes the text from a text-field
  jTextField1.grabFocus();    //this sets a cursor within a text-field

//Whenever the Enter is pressed, after the typed text, the action is performed again.
    }
于 2012-11-12T16:33:38.037 に答える