Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Swing中创建延迟_Java_Swing_Sleep_Delay_Thread Sleep - Fatal编程技术网

Java 如何在Swing中创建延迟

Java 如何在Swing中创建延迟,java,swing,sleep,delay,thread-sleep,Java,Swing,Sleep,Delay,Thread Sleep,我做了一个21点游戏,我希望AI玩家在拿牌之间暂停。我试着简单地使用Thread.sleep(x),但这会使它冻结,直到AI玩家拿走所有的牌。我知道Swing不是线程安全的,所以我查看了计时器,但我不明白如何使用它。这是我目前的代码: while (JB.total < 21) { try { Thread.sleep(1000); } catch (InterruptedException ex) {

我做了一个21点游戏,我希望AI玩家在拿牌之间暂停。我试着简单地使用Thread.sleep(x),但这会使它冻结,直到AI玩家拿走所有的牌。我知道Swing不是线程安全的,所以我查看了计时器,但我不明白如何使用它。这是我目前的代码:

while (JB.total < 21) {

          try {
            Thread.sleep(1000);
          } catch (InterruptedException ex) {
            System.out.println("Oh noes!");
          }

          switch (getJBTable(JB.total, JB.aces > 0)) {
            case 0:
              JB.hit();
              break;
            case 1:
              break done;
            case 2:
              JB.hit();
              JB.bet *= 2;
              break done;
          }
        }
while(JB.total<21){
试一试{
睡眠(1000);
}捕获(中断异常例外){
System.out.println(“噢,不!”);
}
开关(getJBTable(JB.total,JB.aces>0)){
案例0:
JB.hit();
打破
案例1:
打破僵局;
案例2:
JB.hit();
JB.bet*=2;
打破僵局;
}
}
顺便说一句,击中();方法更新GUI

所以我看了看计时器,但我不明白我怎么能用它来做这个

计时器是解决方案,因为正如您所说,您正在更新GUI,这应该在EDT上完成


我不知道你担心什么。你发一张牌,然后开始计时。当计时器启动时,你决定再拿一张牌或持有。当你按住按钮时,停止计时器。

我认为在中,很清楚如何使用计时器来实现你想要的,而不必处理线程。

好吧,快速解释一下计时器

首先,在类中需要一个java.util.Timer变量,在项目中需要另一个从java.util.TimerTask扩展而来的类(我们称之为Tasker)

定时器变量的初始化非常简单:

Timer timer = new Timer();
现在是Tasker类:

public class Tasker extends TimerTask {
    @Override
    public void run() {
        actionToDo(); // For example take cards 
    }

    // More functions if they are needed
}
最后,安装计时器及其相关Tasker:

long delay = 0L;
long period = pauseTime;
timer.schedule(new Tasker(),delay,period);
计划功能指示以下内容: First param:每个周期毫秒执行的操作(执行TimerTask类或其扩展名的run函数) 第二个参数:计时器必须启动的时间。在这种情况下,它在调用schedule函数时启动。下面的示例表示调用调度函数后1秒开始的时间:
timer.schedule(new Tasker(),1000,period)
第三个参数:一次调用Tasker.run()函数和下一次调用之间的毫秒数

我希望您理解这个微教程:)。如果您有任何问题,请询问更多详细信息


亲切的问候

下面的代码显示了一个带有JTextArea和JButton的JFrame。单击按钮时,计时器会将事件重复发送(两个按钮之间有第二个延迟)到与按钮相关的actionListener,该按钮会附加一行当前时间

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.Timer;


public class TimerTest extends JFrame implements ActionListener{

    private static final long serialVersionUID = 7416567620110237028L;
    JTextArea area;
    Timer timer;
    int count; // Counts the number of sendings done by the timer
    boolean running; // Indicates if the timer is started (true) or stopped (false)

    public TimerTest() {
        super("Test");
        setBounds(30,30,500,500);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(null);

        area = new JTextArea();
        area.setBounds(0, 0, 500, 400);
        add(area);

        JButton button = new JButton("Click Me!");
        button.addActionListener(this);
        button.setBounds(200, 400, 100, 40);
        add(button);

        // Initialization of the timer. 1 second delay and this class as ActionListener
        timer = new Timer(1000, this);
        timer.setRepeats(true); // Send events until someone stops it
        count = 0; // in the beginning, 0 events sended by timer
        running = false;
        System.out.println(timer.isRepeats());
        setVisible(true); // Shows the frame
    }

    public void actionPerformed(ActionEvent e) {
        if (! running) {
            timer.start();
            running = true;
        }
        // Writing the current time and increasing the cont times
        area.append(Calendar.getInstance().getTime().toString()+"\n");
        count++;
        if (count == 10) {
            timer.stop();
            count = 0;
            running = false;
        }
    }

    public static void main(String[] args) {
        // Executing the frame with its Timer
        new TimerTest();
    }
}
这段代码是如何使用javax.swig.Timer对象的示例。关于问题的具体情况。用于停止计时器的if语句必须更改,显然,操作的操作也必须更改。以下片段是执行的解决方案的框架:

public void actionPerformed(ActionEvent e) {
    if (e.getComponent() == myDealerComponent()) {
    // I do this if statement because the actionPerformed can treat more components
        if (! running) {
            timer.start();
            runnig = true;
        }
        // Hit a card if it must be hitted
        switch (getJBTable(JB.total, JB.aces > 0)) {
          case 0:
              JB.hit();
              break;
          case 1:
              break done;
          case 2:
              JB.hit();
              JB.bet *= 2;
              break done;
        }
        if (JB.total >= 21) { // In this case we don't need count the number of times, only check the JB.total 21 reached
            timer.stop()
            running = false;
        }

    }
}
无论这如何解决问题,现在@user920769必须考虑将actionListener和启动/停止条件放在哪里


@kleopatra:谢谢你告诉我这个定时器类的存在,我对它一无所知,而且它很神奇,可以将许多任务化的东西放到swing应用程序中:)

谢谢,但是你能给我一些示例代码来说明如何使用定时器吗?我以前尝试过,但它抛出了一个错误,我忘记了确切的错误。@user920769要再次查看(并仔细阅读;)错误,请重试(编辑以删除绝对性:-)实际上-您很少在Swing中使用util.Timer,而使用swingx.Timer或(用于更复杂的后台任务)SwingWorker@kleopatra
swingx.Timer
(划伤头部)DYM a
javax.swing.Timer
?不能说我遇到了另一个。我把代码和util.Timer放在一起,因为一年前我在一个项目中使用了util.Timer。我的项目是一个排球游戏,我们使用上面的结构来重新计算信息并每0,04秒刷新一次窗口。我不知道如何使用swingx.Timer,但我不知道他的代码在图形应用程序中正常工作。它不会冻结窗口,让用户做事情不会有任何问题。=)对不起,我的错误(潜意识的狭隘;-)@Andrew猜对了,我是说javax.swing.Timer和java.util.TimerWell,我一直在阅读swing.timerapi,我用一个计时器编写了一段代码,它可以帮助@user920769。由于答案的扩展,我把它放在了一个新的答案中。我不编辑这一行,因为尽管这不是最好的方法,但是util.Timer很容易做到这一点。非常感谢您提供的示例,但是我在这些行中遇到了一个错误:Timer=new Timer(1000,这个);timer.setRepeats(真);表示无法分别找到合适的构造函数或方法。它们是否已弃用?是否导入计时器类?即使在上一个版本中,这些方法也没有被弃用,因此这似乎是您的错误。代码中有很多东西需要清理:1)不要
实现ActionListener
!将Lambdas用于
按钮.addActionListener(e->xyButtonClicked())通过这种方式,您可以轻松地分离关注点,而无需检查操作的来源。特别是在需要手动调用它们的情况下。2) 在成员变量前面加上可见性(private)前缀,最后加上所有可以加的前缀!如果可能,在变量声明时初始化它们。3) 
myDealerComponent()
是你能给函数起的最糟糕的名字,因为它缺少
get
,而且可能有一些模糊的魔力