1

我在一个非常简单的 JFrame 上有几个 JTextField。字段 1 首先获得焦点。当用户输入一个数字并按 Enter 键时,我希望焦点切换到字段 2。为此,我将一个 ActionListener 附加到字段 1。我还有一个附加到字段 1 的文档侦听器,它只允许输入整数进入这个领域。

文档侦听器首先就位,它可以按我的意愿工作。然后我添加了 ActionListener,我认为(但我不确定)我的代码对此是否正确。但是,当我测试代码时,回车键似乎根本没有效果。我怀疑问题是两个侦听器之间的冲突,因为文档侦听器可能在 ActionListener 对它做出反应之前“吞下”了 enter 键。

我的代码如下。我对吗?我该如何纠正?谢谢!

        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

如果没有工作示例,就不可能准确诊断您的问题。

但是,根据您的描述,我建议您放弃ActionListener使用Focus SubSystem

以下示例演示了如何更改焦点转移键以及DocumentFilter(但我认为 a DocumentListenerorFocusListener就足以执行您的计算方法)

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 回答