用于nfc扫描仪的Java多线程

用于nfc扫描仪的Java多线程,java,multithreading,nfc,Java,Multithreading,Nfc,我已经开始研究java,为我的nfc扫描器创建java应用程序 到目前为止,当我按下按钮时,我能够扫描并读取uid中的标签。(它会锁定我的gui,直到找到标记为止) 我需要扫描器在我按下按钮时一直在扫描,而不锁定我的gui,然后在发现新标签时更新我的gui 然而,我从来没有尝试过多线程,所以我不知道如何让我的新线程告诉另一个当它找到一个新标记时,我该怎么做 NFC阅读器类 public class NFCCardReader { final protected static char[]

我已经开始研究java,为我的nfc扫描器创建java应用程序

到目前为止,当我按下按钮时,我能够扫描并读取uid中的标签。(它会锁定我的gui,直到找到标记为止)

我需要扫描器在我按下按钮时一直在扫描,而不锁定我的gui,然后在发现新标签时更新我的gui

然而,我从来没有尝试过多线程,所以我不知道如何让我的新线程告诉另一个当它找到一个新标记时,我该怎么做

NFC阅读器类

public class NFCCardReader {
    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
    private List<CardTerminal> terminals;

    private static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for (int j = 0; j < bytes.length; j++) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    protected NFCCardReader() {
        TerminalFactory factory = null;
        try {
            factory = TerminalFactory.getInstance("PC/SC", null);
            System.out.println(factory);
            terminals = factory.terminals().list();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (CardException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    protected String scan() {
        if (terminals.isEmpty()) {
            return "Ingen NFC terminaler tilgængelig";
        }
        CardTerminal terminal = terminals.get(0);
        boolean looking = true;
        String uid = "";
        while (looking) {
            try {
                terminal.waitForCardPresent(0);
                Card card = terminal.connect("*");
                CardChannel channel = card.getBasicChannel();

                CommandAPDU command = new CommandAPDU(new byte[] { (byte) 0xFF,
                        (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x04 });
                ResponseAPDU response = channel.transmit(command);

                byte[] byteArray = response.getBytes();
                uid = bytesToHex(byteArray);
                looking = false;
            } catch (CardException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return uid;
    }
}
程序类

public class Program {


    private Db db;
    private String currentUID = "", currentText = "";
    private NFCCardReader nfc;

    public Program() {
        db = new Db();
        nfc = new NFCCardReader();
    }

    public String nfcScan() {
        currentUID = nfc.scan();
        currentText = db.getTag(currentUID);
        return currentUID;
    }

    public String getTagText() {
        return currentText;
    }

    public void setTag(String text) {
        db.setTag(currentUID, text);
        currentText = text;
    }
}
MainGui类

public class MainGui extends JPanel {
    private static final long serialVersionUID = -6698282232100136737L;
    private Controller controller = new Controller(this);
    private JFrame prg;
    private SimpleDateFormat sdf = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss.SSS");
    private Date date;
    private String formattedDate;
    protected JLabel lblUID;
    protected JButton btnScan, btnSave;
    protected JTextArea txaText;

    public MainGui(JFrame prg) {
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\tStarting program...");
        this.setLayout(null);
        this.prg = prg;
        initialize();
    }

    public void closeProgram() {
        prg.dispose();
    }

    private void initialize() {
        // initialize SETUP
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\tInitializing...");
        // initialize txaTEXT
        lblUID = new JLabel();
        lblUID.setText("Tag UID: ");
        lblUID.setSize(160, 30);
        lblUID.setLocation(30, 30);
        lblUID.setVisible(true);
        this.add(lblUID);
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\t\tlblUID been initialized at: "
                + lblUID.getX() + "," + lblUID.getY() + "\tSize: "
                + lblUID.getWidth() + "," + lblUID.getHeight());
        txaText = new JTextArea();
        txaText.setSize(370, 300);
        txaText.setLineWrap(true);
        txaText.setWrapStyleWord(true);
        txaText.setDragEnabled(false);
        txaText.setLocation(30, 70);
        txaText.setMargin(new Insets(5, 5, 5, 5));
        txaText.setVisible(true);
        this.add(txaText);
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\t\ttxaText been initialized at: "
                + txaText.getX() + "," + txaText.getY() + "\tSize: "
                + txaText.getWidth() + "," + txaText.getHeight());
        btnScan = new JButton();
        btnScan.setText("Scan");
        btnScan.setLocation(330, 30);
        btnScan.setSize(70, 30);
        btnScan.setMargin(new Insets(1, 1, 1, 1));
        this.add(btnScan);
        btnScan.addActionListener(controller);
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\t\tbtnScan been initialized at: "
                + btnScan.getX() + "," + btnScan.getY() + "\tSize: "
                + btnScan.getWidth() + "," + btnScan.getHeight());
        btnSave = new JButton();
        btnSave.setText("Gem");
        btnSave.setLocation(330, 380);
        btnSave.setSize(70, 30);
        btnSave.setMargin(new Insets(1, 1, 1, 1));
        btnSave.addActionListener(controller);
        this.add(btnSave);
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\t\tbtnSave been initialized at: "
                + btnSave.getX() + "," + btnSave.getY() + "\tSize: "
                + btnSave.getWidth() + "," + btnSave.getHeight());
        date = new Date();
        formattedDate = sdf.format(date);
        System.out.println(formattedDate + "\tInitializing...COMPLETE");
    }
}

创建用于运行线程的新类。然后从要运行线程的位置调用thread的
.start
方法

package test;

public class MultiThreadApp {
    BackgroundThread bt = new BackgroundThread();

    public MultiThreadApp() {
        // TODO Auto-generated constructor stub
        bt.start();
    }

    public static void main(String[] args) {
        new MultiThreadApp();
    }

    private class BackgroundThread extends Thread {
        @Override
        public void run() {
            while (true) {
                System.out.println("BackgroundThreadRunning");

            }
        }

    }
}

1/请让您的条形码阅读器类实现Runnable

2/例如,使用前面提到的Runnable启动后台线程 通过Executors.newSingleThreadExecutor().execute(…)。或者正如另一个答案所暗示的那样

3/您的UI是Swing。从条形码阅读器内部,您需要触发功能 根据SwingUtilities.invokeLater(…)更新每个读取条形码的UI。为了进行测试,您可以简单地将SwingUtilities.invokeLater(…)放入条形码读取器中。对于真正的实时解决方案,您可能希望将此逻辑放入控制器中,或者让条形码读取器触发一个动作。重要的是,条形码读取器会触发,但触发的代码在SwingUtilities.invokeLater(…)中

您还需要提供有序关闭应用程序的功能。例如,这可能是一个例子 通过使变量看起来易变并将其按setter公开给外部(UI、controller)代码来完成。UI/控制器随后可能会使用setter向后台线程发出停止读取条形码的信号


Swing教程中有关于此类编程问题的示例和解释。

我认为您需要更精确地表述您的问题。我错过了以下信息:0/您需要将条形码传送到的“其他”线程是什么?UI线程?如果是,您计划使用什么用户界面?摆动1/您是否计划在循环中读取新条形码?这是您所说的,但当前您的while循环只读取一个条形码,然后结束。或者你是在寻找一种方法,一次只读取一个条形码,而不阻塞用户界面?@Michal很抱歉,我试图让它更清楚地知道我现在想要它做什么这只是简单的部分。他正在寻找传递信息的方法。然后我如何让它将找到的标记发送到我的主线程?我关于关闭应用程序的评论有一个问题-在读取条形码后首先检查looking变量。因此,在设置looking=false后,可能需要首先读取一个条形码。不幸的是,没有干净的处理方法。如果waitForCardPresent(..)接受超时,则会有所帮助。否则,您可能不得不执行System.exit(..),这不是结束应用程序的干净方法。非常感谢
package test;

public class MultiThreadApp {
    BackgroundThread bt = new BackgroundThread();

    public MultiThreadApp() {
        // TODO Auto-generated constructor stub
        bt.start();
    }

    public static void main(String[] args) {
        new MultiThreadApp();
    }

    private class BackgroundThread extends Thread {
        @Override
        public void run() {
            while (true) {
                System.out.println("BackgroundThreadRunning");

            }
        }

    }
}