swing Java:在等待另一个线程完成时更新UI
我有一些Java Swing登录面板。当用户单击“登录”按钮时,会发生广泛的数据库通信。我有一个想法,把db通信放到另一个线程中(db通信用于填充一些散列映射和单例)。在将该通信放入单独的线程后,当用户键入其uname和密码时,数据库将发生重载。当用户单击“登录”按钮时,代码将等待“重载”线程加入,然后继续
问题是,当我的代码等待db线程加入时,似乎无法进行UI更新。我不认为我可以使用SwingWorker进行db通信,因为用户可以随时单击“登录”按钮,即使在软件完成之前,我也无法加入SwingWorker(db通信必须在实际登录之前进行)
在等待另一个线程加入时,是否有办法启用Swing ui更新?我错过什么了吗
# 1 楼答案
最简单的解决方案之一是在初始DB通信完成之前禁用登录按钮。但这将需要一些额外的进度条或消息,以确保初始化不会混淆用户。在这种情况下,您可以使用
SwingWorker
,它在完成时启用登录按钮另一个解决方案是,当用户按下登录按钮时,处理应该再次委托给(另一个)后台线程,该线程等待初始DB通信线程加入。这样EDT(和GUI)就不会被阻止。实际上,连接到DB也是一个漫长的操作,因此无论如何,它都应该在后台线程中完成,即使在禁用1中所述的登录按钮时也是如此
另一个解决方案是创建一个固定大小为1(例如
java.util.concurrent.Executors.newSingleThreadExecutor()
)的线程池,并将所有后台任务传递给该线程池。对于单线程,执行器任务将按顺序执行。第一个任务是初始数据库通信,另一个任务是登录任务# 2 楼答案
只需放置两个标志,在两个操作(DB通信和用户单击)结束时,调用相同的方法并在那里验证两个标志的状态。如果要阻止用户输入,可能会在模式对话框中显示进度条:
# 3 楼答案
使用执行器服务。调用
executorService.submit(runnable)
,其中“runnable”执行数据库工作。submit
方法将返回一个Future
。然后在登录之后,您可以调用future.get()
,它将等待完成(或者如果runnable已经完成,则立即返回)# 4 楼答案
我真的认为你应该尝试一下SwingWorker,比如:
这样你就不会冻结EDT
另一个选择是运行您自己的“迷你swingworker”:
希望对你有帮助,谢谢
# 5 楼答案
这可以使用SwingWorker完成。 将此ActionListener添加到JButton。还为“标签”提供JLabel字段&;“progressbar”的JProgressBar字段
由于数据库工作可能无法量化(可测量),请进行以下更改: