在Java纸牌游戏中,如果每张牌都发给一手牌,我会如何暂停?

时间:2014-04-19 21:17:13

标签: java user-interface sleep wait

我正在使用swbe in netbeans在java中创建一个blackJack游戏。卡片按顺序发给玩家的多手牌和经销商。每张卡发行时,带有卡片图像的JLabel都是jLayerdPanes。我想在每张牌发出后暂停一下。目前你只是看到他们一次被处理。这是前四张牌的代码。

    if(hand1.handIsInPlay()==true){
       dealCard(jLPaneHand1,hand1);
       pause();
    }
    if(hand2.handIsInPlay()==true){
       dealCard(jLPaneHand2,hand2);
       pause();
    }
    if(hand3.handIsInPlay()==true){
       dealCard(jLPaneHand3,hand3);
       pause();
    }
    dealCard(jLPaneDealerHand,dealerHand);

这是我尝试的暂停方法:

public void pause(){
    try {
      Thread.sleep(1000);
    } 
    catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }
}

这是我尝试的第二种暂停方法:

public void pause(){
    try {
        TimeUnit.MILLISECONDS.sleep(1000);
    } 
    catch (InterruptedException e) {
        //Handle exception
    }
}

既没有按预期工作。看起来发生的事情是,如果三只手在场,那么节目总计3x1000ms并等待那个长度,然后立即处理所有牌。

如何在每张卡发出后暂停程序?

1 个答案:

答案 0 :(得分:2)

您需要记住在当前线程中调用Thread.sleep。在使用Swing的Java中,通常至少有2个线程 - 主线程和Swing线程 - 当你触发一个动作时,调用适当的监听器并执行它的方法 - 只要这个方法仍在运行,它就不能转移到其他任务上。例如重新绘制卡片。

所以基本上你需要将这个暂停动作移动到某个其他线程,该线程将命令用例如SwingUtilities.invokeLater,然后等待一段时间,然后重新订购重绘等等。

基本上你需要确保GUI线程没有被阻止并且可以一直工作,并且命令来自其他一些线程 - 它们可以在不打扰用户的情况下睡眠。

在你的情况下,所有事情都发生在1个线程中,所以当你在睡眠时调用GUI线程休眠并且无法执行任何操作,比如绘制你想要绘制的内容 - 耐心地等待直到你在Swing线程中的代码停止执行。

编辑:

快速示例 - 了解确切的要求和代码会使其更好......

在监听者呼叫中,例如:

new Thread(new CardDealing()).start(); // delegates task to the new thread

虽然任务看起来像:

public CardDealing extends Runnable {
    // inner data, methods and so on

    public void run() {
        if(hand1.handIsInPlay()==true){
            dealCard(jLPaneHand1,hand1);
            pause();
        }
        if(hand2.handIsInPlay()==true){
            dealCard(jLPaneHand2,hand2);
            pause();
        }
        if(hand3.handIsInPlay()==true){
            dealCard(jLPaneHand3,hand3);
            pause();
        }
        dealCard(jLPaneDealerHand,dealerHand);
    }

    public void dealCards(...) {
         // this part will be run in a non-gui thread - make sure that
         // all calculations and changes in model are made here
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 // this will be run in a swing thread
                 // - make sure that only code dealing directly
                 // with GUI is called here
                 guiDealCards(jPane,hand);
             }
         });
    }
}

当然,根据您的要求CardDealing类可能需要参数,包含对某些数据的引用等等 - 但这是整体设计的问题。 GUI和工作线程之间的通信应该或多或少地像这样工作。在这种特殊情况下,您也可以尝试invokeAndWait - 只需确保未在GUI线程内调用pause()(您委派的自定义Swing组件,Runnablespaint方法等)。

编辑2:

您可能会发现this link有用 - 它可以帮助您了解Swing的工作原理,以及为什么要将逻辑划分为至少两部分:GUI和非GUI。无论如何 与dealCards方法中的GUI无关,而guiDealCards中的所有GUI相关内容 - 我不知道你在那里做了什么,所以我不能为你做这个。