[英]Barcode scanning using DocumentFilter in Java
My barcode include "1039723170303CC15-78"
The reason I used DocumentFilter is I want to limit the number as 7 digit
only. 我的条形码包括"1039723170303CC15-78"
我使用DocumentFilter的原因是我想将7 digit
限制为仅7 digit
。 And the rest of the number goes to 2nd textField automatically. 其余的数字自动转到第二个textField。
My code only working set 7 digit only and not all the rest of the number goes to next textfield. 我的代码只能设置7位数而不是所有其余的数字都转到下一个文本字段。 (ie, "1039723"
go 1st textField and "70303CC15-78"
go 2nd textFiled. "1"
is missing in the 2nd textFiled. (即"1039723"
转到第一个textField和"70303CC15-78"
转到第二个textFiled。第二个textFiled中缺少"1"
。
How can i solve this? 我怎么解决这个问题?
lblTest = new JLabel("Testing : ");
panel.add(lblText, "cell 0 1,alignx trailing");
txtTest = new JTextField(7);
AbstractDocument d = (AbstractDocument) txtTest.getDocument();
d.setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException
{
if(fb.getDocument().getLength()+string.length()>7)
{
return;
}
fb.insertString(offset, string, attr);
}
@Override
public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException
{
fb.remove(offset, length);
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs)throws BadLocationException
{
if(fb.getDocument().getLength()+text.length()>7)
{
txtTest.transferFocus();
System.out.println("print.." +txtTest.getText());
return;
}
fb.insertString(offset, text, attrs);
}
});
print out put: 打印输出:
print Mo No.:1039723
print Mo No.:1039723
print Mo No.:1039723
The basic problem you have, is the text
you're checking is been discard and never applied to anything. 您遇到的基本问题是,您正在检查的text
已被丢弃,并且从未应用于任何内容。
For example, if the text been entered is (assuming one character at a time) 123456789
, then 8
will be ignored, as 9
will be send to the other field. 例如,如果输入的文本是(假设一次一个字符) 123456789
,那么将忽略8
,因为9
将被发送到另一个字段。
What you need to do, is manually set the text of the next field with the text you are going to ignore. 您需要做的是,使用您要忽略的文本手动设置下一个字段的文本。
Now, your current has a two fundamental flaws. 现在,你的当前有两个根本缺陷。
replace
should remove any selected characters 它没有考虑到replace
应删除任何选定字符的事实 This example attempts to answer all of those questions 此示例尝试回答所有这些问题
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTextField field1 = new JTextField(7);
JTextField field2 = new JTextField(7);
((AbstractDocument) field1.getDocument()).setDocumentFilter(new LimitDocumentFilter(field2));
add(field1);
add(field2);
}
}
public class LimitDocumentFilter extends DocumentFilter {
private JTextField next;
public LimitDocumentFilter(JTextField next) {
this.next = next;
}
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
super.insertString(fb, offset, text, attr);
String textValue = fb.getDocument().getText(0, fb.getDocument().getLength());
if (textValue.length() > 7) {
remove(fb, 7, fb.getDocument().getLength() - 7);
String overflow = textValue.substring(7);
next.requestFocusInWindow();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
next.setText(overflow);
next.setCaretPosition(overflow.length());
}
});
}
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
fb.remove(offset, length);
insertString(fb, offset, text, attrs);
}
}
}
What this really needs is a delegate model, where by instead of the DocumentFilter
changing field focus, it delegates that responsibility to some other observer, passing it the overflow text 这真正需要的是委托模型,而不是DocumentFilter
更改字段焦点,它将该责任委托给其他观察者,并将溢出文本传递给它
Okay, so this is an updated version which provides three ways that the text can be set: 好的,这是一个更新版本,它提供了三种可以设置文本的方法:
setText
直接通过setText
Robot
通过Robot
将键击注入键盘缓冲区 This provides the best possible example of how a barcode scanner "might" work 这提供了条码扫描器“可能”如何工作的最佳示例
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JTextField field1 = new JTextField(7);
JTextField field2 = new JTextField(7);
LimitDocumentFilter filter = new LimitDocumentFilter();
filter.add(new LimitListener() {
@Override
public void limitReached(LimitDocumentFilter filter, String overflow) {
// This is to overcome the issue of MacOS autoselecting the
// text when it gets focus ... dumb
FocusListener[] listeners = field2.getFocusListeners();
for (FocusListener listener : listeners) {
field2.removeFocusListener(listener);
}
field2.setText(overflow);
field2.requestFocusInWindow();
field2.setCaretPosition(overflow.length());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (FocusListener listener : listeners) {
field2.addFocusListener(listener);
}
}
});
}
});
((AbstractDocument) field1.getDocument()).setDocumentFilter(filter);
add(field1);
add(field2);
JButton sim = new JButton("Simulate");
sim.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
field1.setText(null);
field2.setText(null);
field1.requestFocusInWindow();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Thread t = new Thread(new Simulator());
t.start();
}
});
}
});
JButton paste = new JButton("Paste");
paste.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
field1.setText(null);
field2.setText(null);
String text = "1234567abcdefg";
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(text), null);
field1.requestFocusInWindow();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
field1.paste();
}
});
}
});
JButton set = new JButton("Set");
set.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
field1.setText(null);
field2.setText(null);
field1.setText("1234567abcdefghijklmnopqrstuvwxyz");
}
});
add(sim);
add(paste);
add(set);
}
}
public class Simulator implements Runnable {
@Override
public void run() {
try {
Robot bot = new Robot();
type(KeyEvent.VK_1, bot);
type(KeyEvent.VK_2, bot);
type(KeyEvent.VK_3, bot);
type(KeyEvent.VK_4, bot);
type(KeyEvent.VK_5, bot);
type(KeyEvent.VK_6, bot);
type(KeyEvent.VK_7, bot);
type(KeyEvent.VK_A, bot);
type(KeyEvent.VK_B, bot);
type(KeyEvent.VK_C, bot);
type(KeyEvent.VK_D, bot);
type(KeyEvent.VK_E, bot);
type(KeyEvent.VK_F, bot);
type(KeyEvent.VK_G, bot);
} catch (AWTException ex) {
ex.printStackTrace();
}
}
protected void type(int keyStoke, Robot bot) {
bot.keyPress(keyStoke);
bot.keyRelease(keyStoke);
}
}
public interface LimitListener {
public void limitReached(LimitDocumentFilter filter, String overflow);
}
public class LimitDocumentFilter extends DocumentFilter {
private List<LimitListener> listeners = new ArrayList<>(25);
public LimitDocumentFilter() {
}
public void add(LimitListener listener) {
listeners.add(listener);
}
public void remove(LimitListener listener) {
listeners.remove(listener);
}
protected void limitReached(String overflow) {
for (LimitListener listener : listeners) {
listener.limitReached(this, overflow);
}
}
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
super.insertString(fb, offset, text, attr);
String textValue = fb.getDocument().getText(0, fb.getDocument().getLength());
if (textValue.length() > 7) {
remove(fb, 7, fb.getDocument().getLength() - 7);
String overflow = textValue.substring(7);
limitReached(overflow);
}
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
fb.remove(offset, length);
insertString(fb, offset, text, attrs);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.