我正在使用Java.
我有这个线程,代理,探索一个房间来确定它的大小,并清理它,如果它是脏的.然后我有了界面,它在探索环境时绘制代理.Agent是Thread的子类,Java负责管理线程.我所做的就是创建线程并说出object.start().
这在正常情况下非常有效.但是,在此期间启用菜单,这意味着用户可以在代理正在探索时弄乱房间.这不应该发生.
因此,一旦用户单击告诉代理清理房间的选项,我想禁用所有菜单.除非它不能正常工作.这是问题所在:
... public void ActionPerformed(ActionEvent e) { //disable the menus with setEnabled(false); agent.start(); //enable the menus with setEnabled(true); }
问题是在代理程序线程执行其功能之前启用了菜单.我想过使用Thread.join() - 这可以保证启用菜单的代码只在代理程序线程结束后执行.但是,如果我使用Thread.join(),代理移动时接口不会自动更新,因为它正在等待代理完成!
我已经考虑过从代理中禁用接口,然后在代理完成后启用它,但我不确定它是否会起作用,这里最大的问题是代理不应该乱用菜单.
所以,总结一下,我需要一个执行更新接口的线程/绘制代理移动,但该线程不能与启用菜单相同.目前似乎有一个线程同时执行这两个操作.假设这是可能的而不是太复杂.
我已经考虑过从代理中禁用接口,然后在代理完成后启用它,但我不确定它是否会起作用,这里最大的问题是代理不应该乱用菜单.
您可以使代理程序调用GUI类中的一个方法,该方法在完成后重新启用菜单.当然,该方法将在EDT上调用适当的Swing方法.
class Agent extends Thread { @override public void run() { // run around the room // finally done gui.agentIsDone(); } } class GUI extends JFrame { ... void agentIsDone() { SwingUtilities.invokeLater(new Runnable() { @override public void run() { menus.setEnabled(true); } }); } }
如果多个代理可以同时运行,则在重新启用菜单之前,您需要检查是否所有代理都已完成.