我想从对象';在java中5秒后的s函数

我想从对象';在java中5秒后的s函数,java,swing,timer,actionlistener,Java,Swing,Timer,Actionlistener,我正在做一个基本的纸牌游戏,人类用户可以用电脑玩,或者用java电脑玩。我想从Computer Player类中的选择函数中选择一个随机数,该函数扩展了我的Player类。但我想在5秒钟后从调用选择函数获取答案。我还必须从人类玩家类中的选择函数中得到一个答案,并使用鼠标侦听器 我创建了一个服务员计时器,在调用我的选择函数时启动 Timer waterer=新定时器(5000,这个); 布尔在等待; public int select_cart(){ 服务员,开始吧; 等待=真; 随机r=新随机(

我正在做一个基本的纸牌游戏,人类用户可以用电脑玩,或者用java电脑玩。我想从Computer Player类中的选择函数中选择一个随机数,该函数扩展了我的Player类。但我想在5秒钟后从调用选择函数获取答案。我还必须从人类玩家类中的选择函数中得到一个答案,并使用鼠标侦听器

我创建了一个服务员计时器,在调用我的选择函数时启动

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,然后将整个应用程序置于静止状态,这是不可能的。这就是为什么您应该使用观察者模式。为了让它发挥作用,你必须改变你的思维方式