我想从对象';在java中5秒后的s函数
我正在做一个基本的纸牌游戏,人类用户可以用电脑玩,或者用java电脑玩。我想从Computer Player类中的选择函数中选择一个随机数,该函数扩展了我的Player类。但我想在5秒钟后从调用选择函数获取答案。我还必须从人类玩家类中的选择函数中得到一个答案,并使用鼠标侦听器 我创建了一个服务员计时器,在调用我的选择函数时启动我想从对象';在java中5秒后的s函数,java,swing,timer,actionlistener,Java,Swing,Timer,Actionlistener,我正在做一个基本的纸牌游戏,人类用户可以用电脑玩,或者用java电脑玩。我想从Computer Player类中的选择函数中选择一个随机数,该函数扩展了我的Player类。但我想在5秒钟后从调用选择函数获取答案。我还必须从人类玩家类中的选择函数中得到一个答案,并使用鼠标侦听器 我创建了一个服务员计时器,在调用我的选择函数时启动 Timer waterer=新定时器(5000,这个); 布尔在等待; public int select_cart(){ 服务员,开始吧; 等待=真; 随机r=新随机(
Timer waterer=新定时器(5000,这个);
布尔在等待;
public int select_cart(){
服务员,开始吧;
等待=真;
随机r=新随机();
int random=r.nextInt(getCartNumber())+1;
整数选择=随机;
(你在等吗){
System.out.println(“计算机正在选择…”);
}
返回选择;
}
@凌驾
已执行的公共无效操作(操作事件e){
如果(例如getSource()==服务员){
is_waiting=false;
服务员,停下;
}
}
我希望select_cart函数在5秒后返回一个值,但此代码打印“Computer is selecting…”以无休止的循环方式控制台。如果从事件调度线程调用了select_cart
然后您需要更改方法,因为while循环
正在阻塞事件调度线程,这意味着将永远不会调用计时器
的actionPerformed
方法
在这种情况下,更好的方法是允许actionPerformed
方法实际触发结果,但是,您需要使用观察者模式使其工作
首先定义一个回调接口
,类似于
public interface CartSelection {
public void cartSelection(int value);
}
select_cart(new CartSelection() {
@Override
public void cartSelection(int value) {
// Carry on...
}
});
然后您需要更改代码以使用此回调,并将核心功能移动到actionPerformed
,例如
Timer waiter = new Timer(5000,this);
CartSelection callback;
public void select_cart(CartSelection callback) {
this.callback = callback;
waiter.start();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == waiter){
waiter.stop();
Random r = new Random();
int random = r.nextInt(getCartNumber()) + 1;
int selection = random;
callback(selection)
}
}
然后你可以调用select\u cart
类似于
public interface CartSelection {
public void cartSelection(int value);
}
select_cart(new CartSelection() {
@Override
public void cartSelection(int value) {
// Carry on...
}
});
举个例子
如果CART已被其他进程填充,那么您可能会考虑使用不同的方法,例如使用对象“等待”直到填充过程完成。 同样,您可以使用
SwingWorker
来填充购物车,当购物车完成后,发布
通过其他机制消费的结果
如果从另一个线程调用了select\u cart
现在,如果您从不同的线程(EDT除外)调用select\u cart
,那么您实际上根本不需要计时器,只需执行以下操作即可
public int select_cart() {
Random r = new Random();
int random = r.nextInt(getCartNumber()) + 1;
int selection = random;
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
return selection;
}
select_cart()永远不会停止运行,因为它会卡住。你需要开发一种方法,可以在不阻塞的情况下检查状态,而不是等待。卡住了?为什么它没有进入actionPerformed并且没有使is_waiting为false?如何防止它在不等待的情况下发送?如果select_cart()处于“运行”状态,表示有焦点。它永远不会屈服。它卡住了。您需要将等待逻辑移出该方法,创建一个触发事件的计时器,当事件触发时,您检查该值是否已更新。这发生在后台线程上,不会阻塞。您可能正在阻塞事件调度线程。您应该让操作执行
方法,而不是“等待”,只需根据需要执行操作即可。如果<代码>选择tCART/<代码>在一个不同的线程上执行,那么我会考虑使用一个对象监视器或一个或事件A<代码> CurtDutLaCH < /C>。您应该始终避免使用“空闲”循环(在可能的情况下),它们效率低下,导致的问题比它们解决的问题多。这可能需要您稍微改变您的方法。当值变为AvailableThread.sleep()时,您可能需要使用回调来通知相关方,而不是直接返回值;他对我很有帮助。我已经解决了退货延迟的问题。但我仍然不能在我的人类玩家卡拉斯中使用mouseListener。我不明白你的第一个解决方案。当调用select_cart函数时,我怎么能在人类玩家类中等待,该函数是从父玩家类抽象函数传递到鼠标单击返回值的?这就是我要说的,你不能。如果不阻止EDT,然后将整个应用程序置于静止状态,这是不可能的。这就是为什么您应该使用观察者模式。为了让它发挥作用,你必须改变你的思维方式