我正在为大学项目编程二十一点(单线程),而发牌者是计算机(例如,没有玩家动作)...

有人知道我该如何用Java编写如下代码:

while (dealerpoints < 17)
    open card and repaint frame
    wait 1 sec (to run again the condition test for while)


事情是,我不想一次涂完所有的发牌人...

提前致谢,
加布里埃尔·索特罗(Gabriel Sotero)

更新:这是我的代码(不起作用)

        while (Dealer.getInstance().dealerPoints < 17){

            Dealer.getInstance().openCard();
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e){ }
        }


openCard声明:

    private void openCard(){

        Card temp;

        temp = Deck.getInstance().myPop();
        Dealer.getInstance().cards.add(temp);
        Dealer.getInstance().dealerPoints += temp.getValue();
        MainPanel.getInstance().updateDealerLabel(Dealer.getInstance().dealerPoints);
        MainPanel.getInstance().repaint();

    }

最佳答案

您不能阻止事件调度线程,因为它负责(除其他事项外)处理重画请求。因此,在您一直等待的所有时间中,UI不会开始更新。这包括使用循环和Thread#sleep

一种解决方案是使用SwingWorker,但是就何时将更新调用回UI而言,这是不可靠的。

另一种解决方案是使用javax.swing.Timer,它将每n个周期触发一次回调,并在事件调度线程中执行...

就像是...

Timer dealerTimer= new Timer(1000, new ActionListener() {
    public void actionListener(ActionEvent evt) {
        if (Dealer.getInstance().dealerPoints < 17) {
            Dealer.getInstance().openCard();
        } else {
            ((Timer)evt.getSource()).stop();
        }
    }
});
dealerTimer.setRepeats(true);
dealerTimer.start();


我要做的是将dealerTimer声明为类字段。需要时,我只需调用dealerTimer.restart()即可使计时器重新启动。您可能还需要检查dealerTimer.isRunning()以确保计时器尚未运行;)

您可能希望通读Concurrency in Swing以获得更多信息

10-04 10:06