【问题标题】:Handle barcode scan in Java在 Java 中处理条形码扫描
【发布时间】:2012-08-30 13:50:10
【问题描述】:

我想让我的应用程序对正在扫描的条形码做出反应以触发按钮按下。例如,用户可以扫描 ((PRINT)) 条码来激活打印按钮。

条形码将被视为用户输入了一些文本。我不确定扫描仪是否会设置为在末尾附加输入或选项卡或什么都没有,所以我不想在此基础上做出假设。

应用程序是 Java/Swing 应用程序。

我看过键绑定/动作映射等,但它们似乎专注于键和弦/单键条目。我需要它在输入整个字符串之前不触发绑定。

棘手的一点是,这应该在用户专注于屏幕的任何地方都有效。他们通常不会输入 ( 字符,因此某种触发器可能会起作用。不过我不确定如何处理字符串的其余部分。

编辑:抱歉,如果问题不清楚,但条形码扫描仪对应用程序来说并不是什么“特殊”的东西,它就像另一个键盘。因此,用户不会输入(打印),但实际上这就是条形码扫描仪所做的,如果这有意义的话。

所以只有两种方法可以触发打印:按下按钮,或“键入”字符串(打印)。棘手的部分是用户可以将注意力集中在应用程序的任何位置。我只担心应用程序是否具有整体焦点,而不是用户关注的领域。有问题的特定屏幕上有复选按钮和左/右选择器,因此用户不一定会在字段中输入内容。

【问题讨论】:

标签: java swing barcode-scanner


【解决方案1】:

我遇到了和你一样的问题,并创建了一个项目(目前存在一些问题的概念证明),以使摇摆中的条形码处理更容易。

这是基于条形码阅读器模拟键盘但与人类不同的事实,它们以恒定的时间“键入”。它基本上可以让您收听“条形码读取”事件。

项目地点:https://github.com/hablutzel1/swingbarcodelistener

演示用法:

public class SimpleTest extends JFrame {
    public SimpleTest() throws HeadlessException {

        // start of listening for barcode events
        Toolkit.getDefaultToolkit().addAWTEventListener(new BarcodeAwareAWTEventListener(new BarcodeCapturedListener() {
            @Override
            public void barcodeCaptured(String barcode) {
                JOptionPane.showMessageDialog(SimpleTest.this, "barcode captured: " + barcode);
            }
        }), AWTEvent.KEY_EVENT_MASK);
        // end of listening for barcode events


        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(new JLabel("Capture barcode demo"));
        getContentPane().add(new JTextField(25));
    }

    public static void main(String[] args) {
        SimpleTest simpleTest = new SimpleTest();
        simpleTest.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        simpleTest.setVisible(true);
        simpleTest.pack();
    }
}

它现在有一些问题,但作为一个起点,我认为还可以,如果你有时间改进它会很棒。

【讨论】:

    【解决方案2】:

    如果我理解错了,请纠正我,但听起来您有一个条形码扫描仪,可以将文本输入到字段中。但是您希望在字段中的文本等于某个值时(因此可以执行操作)得到提醒,而不管它是如何输入的(通过条形码扫描仪或按键)。

    我建议使用 DocumentListener 来提醒您文本字段的更改 - 这应该满足您的两个要求。

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class TempProject extends Box{
    
        public TempProject(){
            super(BoxLayout.Y_AXIS);
            final JTextArea ta = new JTextArea();
            ta.getDocument().addDocumentListener(new DocumentListener(){
    
                @Override
                public void changedUpdate(DocumentEvent arg0) {
                    doSomething();
                }
    
                @Override
                public void insertUpdate(DocumentEvent arg0) {
                    doSomething();
                }
    
                @Override
                public void removeUpdate(DocumentEvent arg0) {
                    doSomething();
                }
    
                public void doSomething(){
                    if(ta.getText().equalsIgnoreCase("print")){
                            System.out.println("Printing...");
                            //Need to clear text in a separate swing thread
                            SwingUtilities.invokeLater(new Runnable(){
                                @Override
                                public void run() {
                                    ta.setText("");
                                }});
                    }
                }
    
            });
    
            add(ta);
        }
    
    
        public static void main(String args[])
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                    frame.setContentPane(new TempProject());
                    frame.setPreferredSize(new Dimension(500, 400));
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }   
    
    
    }
    

    【讨论】:

    • 假设他被允许有一个文本字段,这是一个+1
    • 不幸的是,用户不会在文本字段中编辑文本,他们可能会单击复选框或组合框等,所以我不能真正依赖这个解决方案。无论如何,谢谢。
    • 你不能让文本框总是被选中。 EG 当他们单击一个复选框或组合框后光标返回到文本框?!不知道您的应用程序,所以不知道这是否会!
    【解决方案3】:

    我不完全理解这个问题,这有点太长了,无法发表评论。据我了解,您有一个 Swing 应用程序和一个条形码扫描仪,它有 3 种不同的方式来触发相同的操作

    • 用户在 UI 中输入一些文本(“打印”),这会触发打印操作
    • UI 有一个打印按钮,用户可以按下该按钮并触发打印操作
    • 用户可以扫描“打印”条形码并触发打印操作

    我不明白的部分是为什么应该触发打印操作的条形码扫描与用户可以输入文本的 UI 部分有任何关系。

    我假设条形码的扫描发生在另一个线程上,然后是事件调度线程。扫描条形码并对其进行解析后,您需要触发“打印”操作。您可以直接执行此操作,而无需通过 UI。

    【讨论】:

    • 想想商店里的某个人,而不是不得不点击“打印”按钮,他们可以使用预定义的“条形码”卡来执行操作 - 你在店员登录时经常看到这一点。我想这是相同的过程......不过+1
    • @MadProgrammer 但是为什么还要费心去从barcode->text->action,而不仅仅是barcode->action(其中action可能有一个关于它正在做什么/打算做什么的UI指示)
    • 我认为这就是他想要做的......条形码->动作就是这样。我会亲自为AWTEventQueue 附加一个听众,但是您如何区分键入“PRINT”和条形码的人??
    • @MadPrgrammer - 几乎正如您所描述的那样,此应用程序适用于仓库中的打包台,因此用户希望尽可能扫描条形码,而不是使用鼠标。关于 AWTEventQueue 的建议看起来像是指向正确方向的指针,因为我实际上并不关心用户输入字符串是否会触发打印。条码上会有用户在“普通”条码中不会遇到的初始字符,因此应该不会发生冲突。
    【解决方案4】:

    这是我的方法。它正在工作。只需获取毫秒以确保不会读取两次。只需添加一个 Key Listener(在同一个 JFrame 中实现)。

      @Override
        public void keyTyped(KeyEvent e) {
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            logger().info("keytyped" + e.getKeyChar() + " code "+e.getKeyCode());
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                logger().info("all keys " + keyspressed);
                return;
            }
            // will not last more than a second...
            if (keyspressed == null || System.currentTimeMillis() - currentTimeMillis > 1000) {
                keyspressed = e.getKeyChar()+"";
                currentTimeMillis = System.currentTimeMillis();
            } else {
                keyspressed = keyspressed + e.getKeyChar();
                currentTimeMillis = System.currentTimeMillis();
            }
        }
    
        private String keyspressed = null;
        private long currentTimeMillis = System.currentTimeMillis();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 2016-09-16
      • 1970-01-01
      相关资源
      最近更新 更多