为什么在按下 Jbutton 并在 Java 中执行其定义的功能时,我的应用程序中无法执行任何操作?

问题描述

这就是我试图实现这一目标的方式:

btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Hello there");
                Thread.sleep(1000);
                panel.updateUI();
            }
});             

我将 Enter 按钮设置为认按钮,因此当我一直按下它时,该按钮可能会按下 100 次或更多,但因为我使用的是 Thread.sleep(1000),所以需要一些时间,所以我有时间输入我的 JtextField 或甚至关上窗户却什么也做不了。

此外,我尝试将 btnNewButton.addActionListener() 放在线程的 run 方法中,但没有区别。

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                btnNewButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                         System.out.println("Hello there");
                        Thread.sleep(1000);
                        panel.updateUI();
                    }
                });
            }
        });
thread.start();
// I used try catch block in real code

谁能帮我解决这个问题?

**我正在使用 windowsBuilder 在 Eclipse 中创建这个应用程序。

解决方法

不完全确定您的代码应该做什么,但是如果您想按下按钮,然后 1000 毫秒后它会检查您的字段,您应该执行以下操作:

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("before 1000ms");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("after 1000ms");
                System.out.println("Reading the text field ...");
            }
        });
        thread.start();
        System.out.println("after the thread");

输出:

after the thread
before 1000ms
after 1000ms
Reading the text field ...
,

这是因为所谓的 EDT - 事件调度线程。

这个特殊用途的线程负责 GUI 中的所有事件 - 包括绘图(刷新)和交互(按钮单击)。这意味着,绘制应用程序的线程与用于执行 actionPerformed 代码的线程完全相同。由于您实际上是在一段时间内暂停该线程,因此您的应用程序将在该确切时间段内无响应。

在用户交互中执行的任何内容都应该简短且快速,因为不会阻塞应用程序。如果你需要做一些繁重的事情,有一个名为 SwingWorker 的工具可以让你轻松地在后台线程(池)中进行一些处理并在执行期间安排 UI 更新(例如进度条的更新)

在您的第二个“线程”片段中,您的线程除了向按钮添加 actionListener 之外没有做任何事情,然后它终止(可能在不到 1 毫秒后;))-动作回调仍然由 EDT 执行.如果您从 start 方法内部 run 那个自定义线程 - 那么它确实是并行的并且 GUI 不会被冻结 - 但同样,SwingWorker 是这里的方法。