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

时间:2014-10-30 10:51:26

标签: java swing timer jtextfield javax.swing.timer

我有一个JTextField barcodeTextField,可以使用条形码扫描仪接受扫描条形码中的字符。据我所知,条形码扫描就像快速键入字符或复制粘贴文本字段中的字符。 barcodeTextField也用于显示建议并在其他字段中填写信息(就像在Google中搜索您在输入时显示建议一样)。

到目前为止,我使用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();
  }
});

问题是:如果扫描的条形码有13个字符,则set()执行13次,因此使用DB操作。当我输入" 123"要显示建议清单,set()执行3次。

当用户停止在set()上输入时,我希望barcodeTextField执行。在Javascript/JQuery中,可以使用keyup()事件并在用户仍在键入时使用setTimeout()方法clearTimeout()来完成此操作。

如何在Java中为JTextField实现此行为?

1 个答案:

答案 0 :(得分:1)

  

"当用户停止输入时,有没有办法获取在JTextField上输入的字符串"

同样的方式,Javascript有超时,Swing有一个Timer。因此,如果您正在寻找的是使用其"计时器"在Javscript中实现的。功能,你可以看看你是否可以使用Swing Timers

例如Timer有一个restart。因此,您可以在计时器上设置延迟,例如1000毫秒。输入文本后(文档中的第一次更改),请检查if (timer.isRunning())timer.restart()(如果是),否则timer.start()(表示文档中的第一次更改)。只有在任何文档更改后经过一秒钟时,才会发生计时器的操作。在第二个启动之前发生的任何进一步更改将导致计时器重置。并设置timer.setRepeats(false),因此操作只发生一次

您的文档侦听器可能类似于

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

这是一个完整的例子,我在这里"模拟"通过以500毫秒的受控间隔明确地插入文本字段的文档(9个数字)来键入。您可以在DocumentListener拥有的Timer中看到延迟是1000毫秒。因此,只要键入发生,DocumentListener计时器就不会执行其操作,因为延迟超过500毫秒。对于文档中的每个更改,计时器都会重新启动。

enter image description here

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