运行 GUI 时关于线程的问题

亨利434

我目前正在为 Uni 编写一个程序,该程序使用 RFID 跟踪器来跟踪 RFID 标签通过它们时的移动。这是模仿钱包穿过房间时的运动。

我在我的 GUI 中添加了一个按钮,用于初始化跟踪器并在标签通过它们时更新我的​​数据库。他们在线保持 60 秒,并且一切正常。但是,一旦按下此按钮,我的 GUI 就会冻结,直到进程停止。这可以防止我的 GUI 上的表格更新。

我意识到我需要使用线程,我发现 SwingWorker 看起来不错,但是经过一段时间的尝试理解后,我似乎无法弄清楚。

我想知道是否有比我更有经验的人可以告诉我 SwingWorker 是否可以满足我的需要,并就如何使用它给我一些建议。

以下是我的一些代码片段:

跟踪 JButton:

JButton trackingButton = new JButton("Start Tracking");
trackingButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        try {
            RFIDHandler.openRFID(); //runs the RFID readers
        } catch (PhidgetException | SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
});

我的openRFID方法的开始:

public static void openRFID() throws PhidgetException, SQLException {   

    RFID phid1 = new RFID();
    RFID phid2 = new RFID();
    WalletDAO dao = new WalletDAO();

    // Open and start detecting rfid cards
    phid1.open(5000);  // wait 5 seconds for device to respond
    phid2.open(5000);  // wait 5 seconds for device to respond


    phid1.setAntennaEnabled(true);
    phid2.setAntennaEnabled(true);

    // Make the RFID Phidget able to detect loss or gain of an rfid card
    phid1.addTagListener(new RFIDTagListener() {
        public void onTag(RFIDTagEvent e) {
            try {
                Wallet w = dao.getWallet(e.getTag());                   
                String location = w.getLocation();
                System.out.println(location);

                if(Objects.equals(location, "Room A")) {
                    System.out.println(w.getName() + "'s Wallet read");
                    w.setLocation("Room B");
                    try {
                        dao.updateLocation(w);
                        WalletLocatorInterface.refreshTable(); // refreshes table on GUI
                        System.out.println("Currently in room B");
                    } catch (SQLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
                // ... else statement + another TagListener 

    System.out.println("Gathering data for 60 seconds\n\n");
    try {
        Thread.sleep(60000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    phid1.close();
    phid2.close();
    System.out.println("\nClosed RFIDs");
}

如果您需要我清除任何东西,请告诉我,谢谢。

左派速子

你的问题是Thread.sleep. 你可以完成你在这里做的事情ScheduledExecutorService只需将您的代码修改为:

...
    System.out.println("Gathering data for 60 seconds\n\n");
    try {
        Thread.sleep(60000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    Executors.newScheduledThreadPool(1).schedule(() -> {
        phid1.close();
        phid2.close();
        System.out.println("\nClosed RFIDs");
    }, 60, TimeUnit.SECONDS);
}

(顺便说一句,我使用了一个 lambda 表达式,可以在这里解释。)

关于SwingWorker,我没有太多经验。但是,使用SwingWorker,您可以在后台执行某些操作,而不会在更新时使您的 GUI 卡顿。但是,如果您没有像@MadProgrammer 所说的那样真正更新 GUI,那么使用SwingWorker.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章