Выполните действие после завершения сканирования штрих-кода в JTextField

У меня есть JTextFieldbarcodeTextField который принимает символы отсканированного штрих-кода, используя сканер штрих-кода. Из того, что я знаю, сканирование штрих-кода похоже на очень быстрый набор символов или копирование символов в текстовое поле. 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 раз, и так с операциями с БД. То же самое происходит, когда я набираю "123", чтобы показать список предложений, set() выполняется 3 раза.

я хотел set() чтобы выполнить, когда пользователь перестает набирать на barcodeTextField, В Javascript/JQueryэто можно сделать с помощью keyup() событие и наличие setTimeout() метод внутри, clearTimeout() когда пользователь все еще печатает.

Как реализовать это поведение для JTextField на яве?

1 ответ

Решение

"Есть ли способ получить строку, введенную в JTextField, когда пользователь перестает печатать"

Точно так же, у Javascript есть тайм-аут, у Swing есть таймер. Поэтому, если то, что вы ищете, достигнуто в Javscript с использованием его функции "таймера", вы можете посмотреть, сможете ли вы заставить его работать с таймерами Swing.

Например 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 миллисекунд. Вы можете видеть в Таймере, принадлежащем DocumentListener, что задержка составляет 1000 миллисекунд. Поэтому до тех пор, пока происходит ввод, таймер DocumentListener не будет выполнять свое действие, поскольку задержка превышает 500 миллисекунд. Для каждого изменения в документе таймер перезапускается.

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();
            }
        }
    }
}
Другие вопросы по тегам