在 ActionEvent 期间更改标签

Changing a label during ActionEvent

我正在尝试 enable/disable 按下按钮时的标签,我想在活动期间而不是之后这样做。正如您在下面看到的,我尝试 enable/disable 两个标签:lblKeyboard 和 lblGamepad。

它们在 "RemoteControl.run();" 执行后结束 运行,但我希望它在此之前发生。我有什么办法可以做到吗?

谢谢!

JButton btnGamepad = new JButton("Gamepad");
        btnGamepad.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                    if(cont_state == 0){
                        if(RemoteControl.findGamePad() == true){
                            cont_state = 1;
                            game_status = "on";
                        }
                        else{
                            game_status = "off";
                            key_status = "on";
                            JOptionPane.showMessageDialog(null, "Controller not found!");
                            cont_state = 0;
                        }
                    }

                    if(cont_state == 1){    

                        System.out.println("CONNECTED GAMEPAD!");
                        lblKeyboard.disable();
                        lblGamepad.enable();
                        frame.repaint();
                        RemoteControl.run();

                        cont_state = 0;
                    }

            }
        });

事件侦听器中的代码在事件调度线程 (EDT) 上执行,并且在所有代码执行完毕之前 GUI 无法重绘自身。阅读有关 Concurrency 的 Swing 教程部分,了解有关 EDT 的更多信息。

尝试将您的 RemoteControl.run() 代码包装在 SwingUtilities.invokeLater(...). 这会将代码放在 EDT 的末尾,这可能会给 Swing 带来改变以重新绘制两个标签的状态。

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        RemoteControl.run()
    }
});

这假设您的代码更新了 GUI。如果没有,那么就使用一个单独的线程。

ActionEvents是EDT上的运行,也是负责绘画的。更改标签状态后,Swing 会发出重新发送 Label 的请求。问题是这个请求被发布到一个队列上,一旦 EDT 空闲就会执行,正如您所看到的,EDT 正忙于 运行 处理您的代码,因此无需为您重新绘制!根据代码的性质,您应该考虑使用 SwingWorker 或简单地将 RemoteControl.run() 移动到另一个线程,如

new Thread(new Runnable() {
     @override
     public void run() {
          RemoteControl.run();
     }
}).start();