如何在Java JTextArea中读取FNC1字符

时间:2018-11-11 12:06:09

标签: java gs1-datamatrix

我有一台手持扫描器,可以读取GS1-DataMatrix代码(例如超市中的代码)。我可以在Notepad ++中扫描代码,并且可以看到FNC1字符已传输( GS 在2210之前,十六进制为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为十六进制十六进制:

enter image description here

稍后修改 我认为我的原始帖子引起了混乱:我不解析图像,扫描仪具有内置的硬件可以为我完成此操作,并且我仅收到文本和一些特殊字符(FNC1)。

1 个答案:

答案 0 :(得分:2)

一些阅读后的猜测:

  • FNC1没有标准表示。 This stackoverflow answer建议您无法直接使用默认的用于传输的Latin-1编码对FNC1进行编码。 解决方法是,大多数读者似乎默认使用ASCII控制字符“ Group Separator”(GS,29、0x1d)。

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

考虑到您对扫描仪如何精确地传输数据并不十分明确,但是您提到“它更像键盘”,我假设扫描仪通过假装为键盘来传输数据。 您将选择输入,然后按下扫描仪上的按钮,它将以按键形式发送数据。

现在是这种情况,您将无法使用Swing的DocumentListener/Document来解决此问题。 以下堆栈溢出问题基本上是指您遇到的相同问题(区别在于他们使用的是qrcode而不是条形码):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