我有一个条形码扫描器,当我在文本框上聚焦时,我可以像键盘一样读取输入,没有任何问题。
我的问题是,如果我不在文本框上聚焦,我如何读取条形码输入,换句话说,如何添加事件监听器以监听条形码扫描器。
我希望它能够类似于Java Swing解决方案 在这里介绍。
我假设来自条形码扫描器的最后一个字符是ENTER。如果不是,您必须检查如何知道何时完成条形码,例如通过预期长度或通过测试键事件之间的累加时间等。
来自您的条形码扫描器的KeyEvents应该很快,因此两个事件之间的时间应该相当短。为了过滤手动输入,如果事件传递得太慢,则StringBuffer将被重置。
在您的KeyListener中,现在可以实现此方法:
private final StringBuffer barcode = new StringBuffer();
private long lastEventTimeStamp = 0L;
// ...
public void keyTyped(KeyEvent keyEvent) {
long now = Instant.now().toEpochMilli();
// events must come fast enough to separate from manual input
if (now - this.lastEventTimeStamp > this.threshold) {
barcode.delete(0, barcode.length());
}
this.lastEventTimeStamp = now;
// ENTER comes as 0x000d
if (keyEvent.getCharacter().charAt(0) == (char) 0x000d) {
if (barcode.length() >= this.minBarcodeLength) {
System.out.println("barcode: " + barcode);
}
barcode.delete(0, barcode.length());
} else {
barcode.append(keyEvent.getCharacter());
}
keyEvent.consume();
}
if (event.getCode().equals(KeyCode.ENTER)) {
//...
}
我根据 @l00tr 的答案写了更好的解决方案
public final class BarcodeAccumulator {
public interface OnBarcodeListener {
void onBarcodeScanned(String barcode);
}
private static final char BACKSPACE = '\b';
private static final char CONTROL_V = 0x0016;
private static final char CONTROL_Z = 0x001A;
private static final char CARRIAGE_RETURN = 0x000d;
private final StringBuffer buffer = new StringBuffer();
private OnBarcodeListener barcodeListener;
public void setBarcodeListener(OnBarcodeListener barcodeListener) {
this.barcodeListener = barcodeListener;
}
public void accumulate(final TextField textField) {
if (Objects.nonNull(textField)) {
textField.setOnKeyTyped(event -> {
for (char character : event.getCharacter().toCharArray()) {
if (Character.isISOControl(character)) {
if (textField.isFocused()) {
if (character == BACKSPACE) {
if (buffer.length() > textField.getCaretPosition()) {
remove(textField.getCaretPosition());
}
break;
}
if (character == CONTROL_V) {
add(textField.getText());
break;
}
if (character == CONTROL_Z) {
clear();
add(textField.getText());
break;
}
if (character == CARRIAGE_RETURN) {
notifyListener(buffer.toString());
clear();
break;
}
}
continue;
}
add(String.valueOf(character));
}
});
}
}
public void add(String character) {
buffer.append(character);
}
public void remove(int position) {
buffer.deleteCharAt(position);
}
public void clear() {
buffer.delete(0, buffer.length());
}
private void notifyListener(String barcode) {
if (Objects.nonNull(barcodeListener)) barcodeListener.onBarcodeScanned(barcode);
}