Выполните действие после завершения сканирования штрих-кода в JTextField
У меня есть 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 раз, и так с операциями с БД. То же самое происходит, когда я набираю "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();
}
}
}
}