Java中使用DocumentFilter进行条码扫描

Java中使用DocumentFilter进行条码扫描,java,swing,barcode-scanner,documentfilter,Java,Swing,Barcode Scanner,Documentfilter,我的条形码包括“1039723170303CC15-78” 我使用DocumentFilter的原因是我想将数字限制为仅7位。 数字的其余部分自动转到第二个文本字段 我的代码仅工作集仅7位,而不是数字的所有其余部分进入下一个文本字段。(即,“1039723”转到第一个文本字段和“70303CC15-78”转到第二个文本字段。“1”在第二个文本字段中缺失 我怎样才能解决这个问题 lblTest = new JLabel("Testing : "); panel.add(lblText, "cell

我的条形码包括
“1039723170303CC15-78”
我使用DocumentFilter的原因是我想将数字限制为仅7位。 数字的其余部分自动转到第二个文本字段

我的代码仅工作集仅7位,而不是数字的所有其余部分进入下一个文本字段。(即,
“1039723”
转到第一个文本字段和
“70303CC15-78”
转到第二个文本字段。
“1”
在第二个文本字段中缺失

我怎样才能解决这个问题

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 Mo No.:1039723
print Mo No.:1039723
print Mo No.:1039723

您面临的基本问题是,您正在检查的
文本已被丢弃,并且从未应用于任何内容

例如,如果输入的文本是(假设一次只有一个字符)
123456789
,则
8
将被忽略,因为
9
将被发送到另一个字段

您需要做的是手动设置下一个字段的文本和要忽略的文本

现在,你的电流有两个基本缺陷

  • 它没有考虑到
    replace
    应删除任何选定字符这一事实
  • 不考虑将文本追加到字段时会发生的情况
  • 不考虑是否在字段末尾以外的偏移处插入了文本
  • 这个例子试图回答所有这些问题

    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);
            }
        }
    
    }
    
    这真正需要的是一个委托模型,它不是通过
    DocumentFilter
    更改字段焦点,而是将该职责委托给其他观察者,并将溢出文本传递给它

    更新 好的,这是一个更新版本,它提供了三种文本设置方式:

  • 直接通过
    setText
  • 从剪贴板粘贴
  • 通过
    Robot
  • 这提供了条形码扫描仪“可能”工作方式的最佳示例

    import java.awt.AWTException;
    导入java.awt.Robot;
    导入java.awt.Toolkit;
    导入java.awt.datatransfer.Clipboard;
    导入java.awt.datatransfer.StringSelection;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.event.FocusListener;
    导入java.awt.event.KeyEvent;
    导入java.util.ArrayList;
    导入java.util.List;
    导入java.util.Map;
    导入java.util.Set;
    导入java.util.logging.Level;
    导入java.util.logging.Logger;
    导入javax.swing.JButton;
    导入javax.swing.JFrame;
    导入javax.swing.JPanel;
    导入javax.swing.JTextField;
    导入javax.swing.SwingUtilities;
    导入javax.swing.ui默认值;
    导入javax.swing.UIManager;
    导入javax.swing.text.AbstractDocument;
    导入javax.swing.text.AttributeSet;
    导入javax.swing.text.BadLocationException;
    导入javax.swing.text.DocumentFilter;
    导入javax.swing.text.DocumentFilter.FilterBypass;
    公开课考试{
    公共静态void main(字符串[]args){
    新测试();
    }
    公开考试(){
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    JFrame=新JFrame(“测试”);
    frame.add(newtestpane());
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    }
    });
    }
    公共类TestPane扩展了JPanel{
    公共测试窗格(){
    JTextfield1=新的JTextField(7);
    JTextfield2=新的JTextField(7);
    LimitDocumentFilter=新的LimitDocumentFilter();
    添加(新的LimitListener(){
    @凌驾
    达到公共无效限制(LimitDocumentFilter筛选器,字符串溢出){
    //这是为了克服MacOS自动选择
    //当它获得焦点时的文本…哑
    FocusListener[]listeners=field2.getFocusListeners();
    for(焦点侦听器:侦听器){
    字段2.removeFocusListener(监听器);
    }
    field2.setText(溢出);
    字段2.requestFocusInWindow();
    field2.setCaretPosition(overflow.length());
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    for(焦点侦听器:侦听器){
    字段2.addFocusListener(listener);
    }
    }
    });
    }
    });
    ((AbstractDocument)field1.getDocument()).setDocumentFilter(filter);
    添加(字段1);
    添加(字段2);
    JButton sim=新JButton(“模拟”);
    sim.addActionListener(新ActionListener(){
    @凌驾
    已执行的公共无效操作(操作事件e){
    field1.setText(空);
    field2.setText(空);
    字段1.requestFocusInWindow();
    SwingUtilities.invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    线程t=新线程(新模拟器());
    t、 start();
    }
    });
    }
    });
    JButton粘贴=新JButton(“粘贴”);
    paste.addActionListener(新ActionListener(){
    @凌驾
    已执行的公共无效操作(操作事件e){
    field1.setText(空);
    field2.setText(空);
    String text=“1234567abcdefg”;
    剪贴板剪贴板=Toolkit.getDefaultToolkit().getSystemClipboard();
    剪贴板.setContents(新字符串选择(文本),null);
    字段1.requestFocusInWindow();
    
    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);
            }
        }
    
    }