java - 具有 ActionListener 和 DocumentListener 的 JTextField

标签 java swing actionlistener jtextcomponent documentlistener

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

文档监听器首先就位,并且它正在按照我的意愿工作。然后我添加了 ActionListener,我认为(但我不确定)我的代码对此是正确的。但是,当我测试代码时,回车键似乎根本没有任何作用。我怀疑问题是两个监听器之间的冲突,因为文档监听器可能会在 ActionListener 对其使用react之前“吞噬”回车键。

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

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

最佳答案

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

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

以下示例演示了如何更改焦点转移键以及 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);
        }

    }

}

关于java - 具有 ActionListener 和 DocumentListener 的 JTextField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15169674/

相关文章:

java - Spring Boot 管理页面

java - 如何在处理结束时显示 "Loading..."消息自动关闭(类似于Progress Bar)?

java - 使用 Swing 的 JTextField 在 Java 中打印屏幕

java-me - PopupChoiceGroup Action 监听器不适用于 Asha 501

java - JTree、setUserObject()、toString()

java - 泰勒级数。程序迭代次数更少

java - 如何在 JFrame 中获取事件监听器外部的变量?

java - 奇怪现象: Java/Swing-operations cause access violation in native library (JNA)

java - 我怎么知道java中当前的classLoader

java - 在 swing 1.5 中的指定时间后自动关闭非模态对话框