问题描述
这就是我试图实现这一目标的方式:
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
是这里的方法。