gpt4 book ai didi

java - 让 ActionListener 在完成执行整个 ActionListener 之前提交对 JButton 的更改

转载 作者:行者123 更新时间:2023-11-30 09:06:28 26 4
gpt4 key购买 nike

在 Java 中,我对 JButton 数组使用 ActionListener。我希望 ActionListener 的较早部分将新的 ImageIcon 设置为 JButton,该更改将立即显示,然后在 ActionListener 的末尾附近在第二个长时间延迟后将 JButton 的 ImageIcon 设置回 null。

我的问题是,在 ActionListener 完全完成之前,JButton 发生的任何更改都不会显示在设置它的 GUI 窗口中,这使得 JButton 的 ImageIcon 中的更改不明显。有没有什么方法可以让 ActionListener 在完成整个 ActionListener 的执行之前提交对 JButton 的更改,或者我应该以不同的方式处理这个问题吗?

最佳答案

发生这种情况的原因:

Swing 在与 ActionListener 相同的线程 (EDT) 上重新绘制按钮运行。因此,如果它正在处决你 ActionListener它无法重新绘制,因为线程很忙——就这么简单。您可能已经注意到,当您的 Action 监听器正在执行时,您也无法正确移动框架等(GUI 卡住)。

解决方法:

将繁重的处理移到 EDT 之外。反正它不属于那里。正如您可能已经猜到的那样——为此使用后台线程/线程池。一个很好的指南是 Swing tutorial for concurrency

注意事项:

如指南中所述,您不想在 EDT 之外修改组件。因此,最简单的策略是制作一个 Runnable在后台线程上执行,启动它,更改按钮上的图片并返回而不等待任务完成。

public void actionPerformed(ActionEvent ae) {
Runnable task = new Runnable() {..};
executor.execute(task);
button.setIcon(newIcon);
return;
}

请注意,这不会锁定任务的 EDT,因此允许 Swing 立即更改图片。

这当然意味着用户不知道任务是否完成(如果有任何异常)!毕竟它在后台!因此,您的执行有一个额外的状态:GUI 是响应式的且未卡住,按钮已更改,但任务仍在运行。在大多数应用程序中,这可能是一个问题(用户将向按钮发送垃圾邮件,或者您的后台任务可能会交错)。在这种情况下,您可能需要使用 SwingWorker也有一个“处理”状态。

public void actionPerformed(ActionEvent ae) {
new TaskWorker().execute();
button.setIcon(loadingIcon); //Shows loading. Maybe on button, maybe somewhere else.
return;
}

private class TaskWorker extends SwingWorker<Void, T> {
public Void doInBackground() {
//Do your task in the background here
}
protected void done() {
try {
get();
button.setIcon(doneIcon);
catch (<relevant exceptions>) {
button.setIcon(failedIcon);
}
}
}

在这里done()doInBackground() 时,在 EDT 上被调用完成了。

关于java - 让 ActionListener 在完成执行整个 ActionListener 之前提交对 JButton 的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24435661/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com