我有一个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
实现此行为?
答案 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毫秒。对于文档中的每个更改,计时器都会重新启动。
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();
}
}
}
}