java - 如何在 Java JTextArea 中读取 FNC1 字符

标签 java gs1-datamatrix

我有一个手持扫描仪,可以读取 GS1-DataMatrix 代码(就像超市里的那种)。我可以在 Notepad++ 中扫描代码,我可以看到传输了 FNC1 字符(2210 之前的 GS,十六进制中的 1D - 第一张图片)

现在我正在尝试从 Java 读取相同的 GS1 代码,但无法正常工作,Java 看不到 FNC1。 在 Java 中,我只看到“01095011010209171719050810ABCD12342110”。 我将字符串转换为十六进制,但结果是一样的,FNC1 也不在十六进制中(第二张图片)。

这是测试代码:

package gs1.datamatrix;

import java.awt.Font;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class GS1DataMatrix {
    public static void main(String[] args) {
        JFrame f=new JFrame();//creating instance of JFrame  
        Font font = new Font("Courier New", Font.PLAIN, 16);

        JTextArea jtf2 = new JTextArea(); // used to hold the HEX data
        jtf2.setBounds(10,250,900, 200);
        jtf2.setFont( font.deriveFont( 24.0f) );
        jtf2.setLineWrap(true);
        f.add(jtf2);//adding button in JFrame  

        JTextArea jtf1 = new JTextArea(); // scan area for the DataMatrix scanner
        jtf1.setBounds(10,10,900, 200);
        jtf1.setFont( font.deriveFont( 24.0f) );
        jtf1.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {                update(e);            }
            @Override
            public void removeUpdate(DocumentEvent e) {                update(e);            }
            @Override
            public void changedUpdate(DocumentEvent e) {                update(e);            }
            public void update(DocumentEvent e) {
                try {
                    Document doc = (Document)e.getDocument();
                    String hex = String.format("%040x", new BigInteger(1, doc.getText(0, doc.getLength()).getBytes("UTF8"))); // transform to HEX
                    jtf2.setText(java.util.Arrays.toString(hex.split("(?<=\\G..)"))); // split hex data by 2 characters
                    jtf1.selectAll();
                } catch (Exception ex) {
                    Logger.getLogger(GS1DataMatrix.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        f.add(jtf1);//adding button in JFrame  

        f.setSize(1000,500);
        f.setLayout(null);
        f.setVisible(true);
    }
}

第一张图:Notepad++ 是这样读取 FNC1(黑色背景上的GS 特殊字符)的:

n++

第二张图片:这是 Java 结果: enter image description here

第三张图片:Notepad++ 十六进制转储在每次扫描时显示 FNC1 为十六进制的 1D:

enter image description here

稍后编辑 我认为我的原始帖子引起了困惑:我不解析图像,扫描仪内置硬件为我做这件事,我只收到文本和一些特殊字符(FNC1)。

最佳答案

经过一番阅读后的一些猜测:

  • FNC1 没有标准表示。 This stackoverflow answer表明没有办法在用于传输的默认 Latin-1 编码中直接对 FNC1 进行编码。 作为解决方法,大多数读者似乎默认使用 ASCII 控制字符“组分隔符”(GS, 29, 0x1d)。

  • 您正在使用 Swing 控件来显示和处理数据。 Swing 主要用于显示目的,而不是用于正确的数据处理目的。
    我假设发生的情况是,当 swing 设置在 JTextArea 的内容中时,它会剥离不可打印的 GS 字符

考虑到您对扫描仪传输数据的确切方式并不是非常明确,但您提到“它更像是键盘”,我假设扫描仪通过假装是键盘来传输数据。 您将选择输入,按下扫描仪上的按钮,它会以按键的形式发送数据。

现在如果是这种情况,您将无法使用 Swing 的 DocumentListener/Document 来解决这个问题。 以下 Stack Overflow 问题基本上指的是您遇到的相同问题(不同之处在于他们使用的是二维码而不是条形码):ASCII Non printable characters in textcomponent

现在我链接的问题表明您可以使用KeyBinding 或KeyListener 来解决这个问题。请注意,如果您想打印不可打印的字符,这以某种方式破坏十六进制表示。

UTF-8 确实有一个用于 ASCII 不可打印字符表示的特殊代码点。 “组分隔符的符号”位于 \u241d。处理这个问题的一个选项是:

jtf1.getInputMap().put(KeyStroke.getKeyStroke(29), "handleGS");
jtf1.getActionMap().put("handleGS", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        jtf1.setText(jtf1.getText() + "\u241d");
    }
}

这样十六进制表示应该变成:

.. , 33, 34, e2, 90, 9d, 32, 31, 31, 30]

请注意,因为我们将 GS 重新映射到 Unicode 的“SYMBOL_FOR_GS”,所以我们得到 e2, 90, 9d 而不是 1d

关于java - 如何在 Java JTextArea 中读取 FNC1 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53248562/

相关文章:

java - 循环逻辑中的漏洞

java - Hadoop 's java environment-variables dosen'不能更改吗?

java - RxJava subscribeOn 和observeOn 以及阻塞w/flatMap。谁做了什么?

java - 继承的字段值不会改变

barcode - 使用 bwip-js gs1datamatrix 解析 FNC1 字符

barcode - GS1 标准条形码和通用条形码符号之间有什么关系?

parsing - GS1条码解析

java - 为 Play Framework 2.2.4 配置 HTTPS 信任存储