【问题标题】:How to fixed keylistener on JTextField?如何在 JTextField 上修复 keylistener?
【发布时间】:2015-04-15 07:40:00
【问题描述】:

我有一个 Java swing 应用程序,所以我有一个带有 KeyListener 的简单文本框,我有一个条形码阅读器 (USB),当条形码阅读器在这个文本框上写下数字时,我检查代码并处理它。但我遇到的问题是代码可以有 4 到 13 位数字。所以我有这个代码

public class KeyListenerCodice implements KeyListener{
    public void keyPressed(KeyEvent click) {

    }

    public void keyReleased(KeyEvent keyEvent) {
        printIt("Released", keyEvent);
    }

    public void keyTyped(KeyEvent keyEvent) {
        printIt("Typed", keyEvent);
    }

    private void printIt(String title, KeyEvent keyEvent) {
        if(textCodice.getText().length()>=4 && textCodice.getText().length()<=13)
        {
            if(mappaArticoliScontrini.get(textCodice.getText().toUpperCase())!=null){
                inserisciProdotto();
            }
        }
    }
}

但有时代码有 13 位,但如果条形码阅读器不是很快,keylistener 只能处理 4 或 5 或 6 位,这是一个问题。

我该如何解决?

【问题讨论】:

    标签: java swing barcode keylistener


    【解决方案1】:

    简短的回答是不要。如果您想知道字段内容何时更改,请使用 DocumentFilter 更改输入到 JTextComponentDocumentListener 中的内容。

    KeyListener 不会考虑用户将文本粘贴到字段中或以编程方式修改字段时会发生什么

    有关详细信息,请参阅 DocumentFilter ExamplesImplementing a Document FilterListening for Changes on a Document

    如果您的条码扫描器将关键事件注入事件队列,您可能希望在DocumentFilter 中注入人为延迟,因为在输入所有击键之前您不希望处理该字段。

    例如...

    这基本上使用了一个设置为短延迟(在这种情况下为 250 毫秒)的 Swing Timer,每次更新该字段(并通知 DocumentListener),它都会重新启动 Timer。这意味着在Timer 可以触发注册的ActionListener 并更新标签之前,必须有至少 250 毫秒的延迟。

    public class TestPane extends JPanel {
    
        private Timer updateTimer;
        private JTextField field;
        private JLabel label;
    
        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
    
            updateTimer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setText(field.getText());
                }
            });
            updateTimer.setRepeats(false);
    
            label = new JLabel("...");
            field = new JTextField(14);
            field.getDocument().addDocumentListener(new DocumentListener() {
    
                @Override
                public void insertUpdate(DocumentEvent e) {
                    processUpdate();
                }
    
                @Override
                public void removeUpdate(DocumentEvent e) {
                    processUpdate();
                }
    
                @Override
                public void changedUpdate(DocumentEvent e) {
                    processUpdate();
                }
    
            });
    
            add(field, gbc);
            add(label, gbc);
        }
    
        protected void processUpdate() {
            updateTimer.restart();
        }
    
    }
    

    您可能想稍微考虑一下延迟。

    条形码扫描仪也可能将 Enter 键插入事件队列,因此可能值得通过注册 ActionListener 来测试该字段

    【讨论】:

    • 我不明白 KeyListener 和 DocumentListener 有什么区别
    • @bircastri A DocumentListener 会在Document 的内容发生变化时通知您,而KeyListener 只会通知您关键事件。尝试将KeyListener 添加到JTextField 并调用setText 或将文本粘贴到字段中,KeyListener 将不会收到通知。作为一般经验法则,不要在文本组件上使用 KeyListener
    • 但是当条码写在JTextField上时,我不调用setText,条码阅读器就像一个键盘,你可以写
    • DocumentListener 是监控文本组件更改的首选方式...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    相关资源
    最近更新 更多