简体   繁体   English

完成对JTextField的条形码扫描后执行操作

[英]Perform action upon completion of barcode scanning to JTextField

I have a JTextField barcodeTextField which accepts characters from the scanned barcode using a barcode scanner. 我有一个JTextField barcodeTextField ,它可以使用条形码扫描仪从扫描的条形码中接收字符。 From what I know, barcode scanning is like typing the characters very fast or copy-pasting the characters on the text field. 据我所知,条形码扫描就像非常快速地键入字符或将字符复制粘贴到文本字段上。 barcodeTextField is also used to show suggestions and fill up others fields with information (just like searching in Google where suggestions are shown as you type). barcodeTextField位也可用于显示建议,并在其他栏位中填入资讯(就像在Google中搜寻时, barcodeTextField会显示建议)。

So far I implemented this using DocumentListener : 到目前为止,我已经使用DocumentListener实现了这一点:

barcodeTextField.getDocument().addDocumentListener(new DocumentListener() {
  public void set() {
    System.out.println("Pass");
    // Do a lot of things here like DB CRUD operations.
  }

  @Override
  public void removeUpdate(DocumentEvent arg0) {
    set();
  }

  @Override
  public void insertUpdate(DocumentEvent arg0) {
    set();
  }

  @Override
  public void changedUpdate(DocumentEvent arg0) {
    set();
  }
});

The problem is: If the barcode scanned has 13 characters, set() is executed 13 times, and so with DB operations. 问题是:如果扫描的条形码包含13个字符,则set()将执行13次,以此类推。 Same goes when I type "123" to show suggestion list, set() is executed 3 times. 当我键入“ 123”以显示建议列表时, set()被执行3次,同样如此。

I wanted set() to get executed when the user stops typing on barcodeTextField . 我希望当用户停止在barcodeTextField键入内容时执行set() In Javascript/JQuery , this can be done using the keyup() event and having setTimeout() method inside, clearTimeout() when user is still typing. Javascript/JQuery ,可以使用keyup()事件并在用户仍在键入时在其中包含setTimeout()方法clearTimeout()来完成此操作。

How to implement this behavior for JTextField in Java? 如何在Java中为JTextField实现此行为?

"Is there any way to obtain the string entered on JTextField when the user stops typing" “当用户停止键入时,有什么方法可以获取在JTextField上输入的字符串”

The same way, Javascript has the timeout, Swing has a Timer. 同样,Javascript有超时,Swing有Timer。 So if what you are looking for is achieved in Javscript using its "timer" fucntionality, you can see if you can get it working with a Swing Timers 因此,如果您正在使用Javscript的“计时器”功能实现所需的功能,则可以查看是否可以使其与Swing计时器一起使用

For example Timer has a restart . 例如Timer restart So you can set a delay on the timer for say 1000 milliseconds. 因此,您可以在计时器上设置一个1000毫秒的延迟。 Once text is being typed (first change in the document), check if (timer.isRunning()) , and timer.restart() if it is, else timer.start() (meaning first change in document). 键入文本后(文档中的第一次更改),请检查if (timer.isRunning())timer.restart()如果是),否则timer.start() (意味着文档中的第一次更改)。 The action for the timer will only occur if one second passes after any document change. 仅在任何文档更改后经过一秒钟后,计时器操作才会发生。 Any further changes occurring before the second is up, will cause the timer to reset. 在秒表计时结束之前发生的任何进一步变化都会使定时器复位。 And set timer.setRepeats(false) so the action only occurs once 并设置timer.setRepeats(false)以便该操作仅发生一次

Your document listener might look something like 您的文档侦听器可能看起来像

class TimerDocumentListener implements DocumentListener {

    private Document doc;
    private Timer timer;

    public TimerDocumentListener() {
        timer = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (doc != null) {
                    try {
                        String text = doc.getText(0, doc.getLength());
                        statusLabel.setText(text);
                    } catch (BadLocationException ex) {
                        Logger.getLogger(TimerDemo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        });
        timer.setRepeats(false);
    }

    public void insertUpdate(DocumentEvent e) { set(e); }
    public void removeUpdate(DocumentEvent e) { set(e); }
    public void changedUpdate(DocumentEvent e) { set(e); }

    private void set(DocumentEvent e) {
        if (timer.isRunning()) {
            timer.restart();
        } else {
            this.doc = e.getDocument();
            timer.start();
        }
    }
}

Here's a complete example, where I "mock" typing, by explicitly inserting into the document (nine numbers) of the text field at a controlled interval of 500 milliseconds. 这是一个完整的示例,其中我以500毫秒的受控间隔显式插入文本字段的文档(九个数字)中,以“模拟”键入内容。 You can see in the Timer owned by the DocumentListener that the delay is 1000 milliseconds. 您可以在DocumentListener拥有的Timer中看到延迟为1000毫秒。 So as long as the typing occurs, the DocumentListener timer will not perform its action as the delay is longer than 500 milliseconds. 因此,只要发生键入,由于延迟时间超过500毫秒,DocumentListener计时器将不会执行其操作。 For every change in the document, the timer restarts. 对于文档中的每个更改,计时器都会重新启动。

在此处输入图片说明

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class TimerDemo {

    private JTextField field;
    private JLabel statusLabel;

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            public void run() {
                new TimerDemo();
            }
        };
        SwingUtilities.invokeLater(runnable);
    }

    public TimerDemo() {
        JFrame frame = new JFrame();
        frame.setLayout(new GridLayout(0, 1));

        field = new JTextField(20);
        field.getDocument().addDocumentListener(new TimerDocumentListener());
        statusLabel = new JLabel(" ");

        JButton start = new JButton("Start Fake Typing");
        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                startInsertTimer();
            }
        });

        frame.add(field);
        frame.add(statusLabel);
        frame.add(start);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void startInsertTimer() {
        Timer timer = new Timer(500, new ActionListener() {
            private int count = 9;

            public void actionPerformed(ActionEvent e) {
                if (count == 0) {
                    ((Timer) e.getSource()).stop();
                } else {
                    Document doc = field.getDocument();
                    int length = doc.getLength();
                    try {
                        doc.insertString(length, Integer.toString(count), null);
                    } catch (BadLocationException ex) {
                        Logger.getLogger(TimerDemo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    count--;
                }
            }
        });
        timer.start();
    }

    class TimerDocumentListener implements DocumentListener {

        private Document doc;
        private Timer timer;

        public TimerDocumentListener() {
            timer = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (doc != null) {
                        try {
                            String text = doc.getText(0, doc.getLength());
                            statusLabel.setText(text);
                        } catch (BadLocationException ex) {
                            Logger.getLogger(TimerDemo.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            });
            timer.setRepeats(false);
        }

        public void insertUpdate(DocumentEvent e) { set(e); }
        public void removeUpdate(DocumentEvent e) { set(e); }
        public void changedUpdate(DocumentEvent e) { set(e); }

        private void set(DocumentEvent e) {
            if (timer.isRunning()) {
                timer.restart();
            } else {
                this.doc = e.getDocument();
                timer.start();
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM