1

非常に単純なJFrameにいくつかのJTextFieldがあります。フィールド1が最初にフォーカスを取得します。ユーザーが数字を入力してEnterキーを押すと、フォーカスをフィールド2に切り替えます。これを実現するには、フィールド1にActionListenerをアタッチします。また、フィールド1にドキュメントリスナーをアタッチして、整数のみを入力できるようにします。このフィールドに。

ドキュメントリスナーが最初に配置され、希望どおりに機能しています。次に、ActionListenerを追加しましたが、コードがこれに適していると思います(ただし、よくわかりません)。しかし、コードをテストすると、Enterキーはまったく効果がないようです。ActionListenerがそれに反応する前に、Document ListenerがEnterキーを「飲み込んでいる」可能性があるという意味で、問題は2つのリスナー間の競合であると思われます。

私のコードは次のとおりです。私は正しいですか?どうすればこれを修正できますか?ありがとう!

        txtNum1.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                setAnswer(e);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                setAnswer(e);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                setAnswer(e);
            }

            private void setAnswer(DocumentEvent e) {
                if (txtNum1.getText().equals("")) {
                    num1 = 0;
                } else {
                    num1 = Integer.parseInt(txtNum1.getText());
                }
                calcAnswer(o);
            }
        });

        /* If the user hits the Enter key, we want the focus to shift to
         * the next text field */
        txtNum1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("here"); //never ouputs
                txtNum2.requestFocusInWindow();
            }
        });
4

2 に答える 2

2

実際の例がなければ、問題を正確に診断することは不可能です。

ただし、あなたの説明から、 Focus SubSystemActionListenerの使用を優先してドロップすることをお勧めします。

次の例は、フォーカス転送キーを変更する方法を示しています(ただし、計算方法を実行するには、またはDocumentFilterのいずれかで十分だと思います)DocumentListenerFocusListener

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class TestDocumentFilter03 {

    public static void main(String[] args) {
        new TestDocumentFilter03();
    }

    public TestDocumentFilter03() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public static class TestPane extends JPanel {

        private JTextField field1 = createTextField("1");
        private JTextField field2 = createTextField("2");
        private JTextField field3 = createTextField("3");
        private JTextField field4 = createTextField("4");
        private JTextField field5 = createTextField("5");
        private JTextField field6 = createTextField("6");
        private JTextField field7 = createTextField("7");
        private JTextField field8 = createTextField("8");
        private JTextField field9 = createTextField("9");

        public TestPane() {
            // Set up enter for focus transfer...
            Set forwardKeys = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
            Set newForwardKeys = new HashSet(forwardKeys);
            newForwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
            setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
                            newForwardKeys);

            setLayout(new GridBagLayout());

            add("Field #1: ", field1, 0, 0);
            add("Field #2: ", field2, 2, 0);
            add("Field #3: ", field3, 4, 0);
            add("Field #4: ", field4, 6, 0);
            add("Field #5: ", field5, 8, 0);
            add("Field #6: ", field6, 2, 1);
            add("Field #7: ", field7, 4, 1);
            add("Field #8: ", field8, 6, 1);
            add("Field #9: ", field9, 8, 1);
        }

        protected static JTextField createTextField(String text) {
            JTextField field = new JTextField(text, 10);
            ((AbstractDocument)field.getDocument()).setDocumentFilter(new IntegerFilter());
            return field;
        }

        protected void add(String label, JTextField field, int x, int y) {
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridy = y;
            gbc.gridx = x;
            gbc.insets = new Insets(2, 2, 2, 2);
            gbc.anchor = GridBagConstraints.EAST;
            add(new JLabel(label), gbc);
            gbc.gridx++;
            add(field, gbc);
        }

    }

    public static class IntegerFilter extends DocumentFilter {

        @Override
        public void insertString(DocumentFilter.FilterBypass fb, int offset,
                                                         String string, AttributeSet attr)
                        throws BadLocationException {

            StringBuilder buffer = new StringBuilder(string);
            for (int i = buffer.length() - 1; i >= 0; i--) {
                char ch = buffer.charAt(i);
                if (!Character.isDigit(ch)) {
                    buffer.deleteCharAt(i);
                }
            }
            super.insertString(fb, offset, buffer.toString(), attr);
        }

        @Override
        public void replace(DocumentFilter.FilterBypass fb,
                                                int offset, int length, String string, AttributeSet attr) throws BadLocationException {
            if (length > 0) {
                fb.remove(offset, length);
            }
            insertString(fb, offset, string, attr);
        }

    }

}
于 2013-03-02T02:20:53.887 に答える
-1

あなたのコードの問題は、ENTER キーを押しても ActionEvent として登録されないことだと思います。むしろ、ENTER キーを押すことを KeyEvent として検出できます。その結果、次のようにイベント ハンドラを実装するよりもむしろ:

/* If the user hits the Enter key, we want the focus to shift to
         * the next text field */
        txtNum1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("here"); //never ouputs
                txtNum2.requestFocusInWindow();
            }

代わりに次のことを行います。

txtNum1.addKeyListener(new KeyListener() {
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_ENTER) {
            System.out.println("here");
            txtNum2.requestFocusInWindow();
        }
    }

もちろん、私の答えの一部は次のソースからのものです: http://www.rgagnon.com/javadetails/java-0253.html

于 2013-03-02T16:31:53.440 に答える