【问题标题】:Why is thread.sleep crashing my JavaFX app?为什么 thread.sleep 会使我的 JavaFX 应用程序崩溃?
【发布时间】:2017-02-01 17:49:13
【问题描述】:

我有一个循环遍历我游戏中的所有玩家。在下一次迭代之前,我想让当前玩家有 3 分钟的时间进行选择(这是画布鼠标点击事件)。我尝试过的所有操作都会使我的应用程序崩溃而没有错误。我一直在这几个小时不知道发生了什么。我做错了什么?

    startGame.addEventHandler(MouseEvent.MOUSE_CLICKED,
                new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {

                gameStatus = "Started";
                players.add(new Player(0, "Amrit"));
                players.add(new Player(1, "Tyler"));
                players.add(new Player(2, "Scott"));
                players.add(new Player(3, "Ryker"));

                //Select first two settlements with one road extending from each
                for (int s = 0; s < 2; s++) {

                    for (int p = 0; p < players.size(); p++) {

                        phase = "Pick Settlements";
                        playerTurn = p;

                        //Loop through all tiles
                        for (int t = 0; t < tiles.length; t++) {

                            //Loop through the vertices of the current tile
                            for (int v = 0; v < tiles[t].vertices.length; v++) {

                                drawCircle(gc, new Point(tiles[t].vertices[v].x, tiles[t].vertices[v].y), (int) (windowHeight * .05), true, true, "rgba(255, 238, 144, .3)", 0);

                            }

                        }

                        gc.setFill(Color.web("0xFFEB8A"));
                        gc.strokeText(players.get(p).name + ", please place your first settlement!", windowHeight * .95, windowWidth * .85);
                        selected = false;
                        canvas.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                            // @Override
                            @Override
                            public void handle(final MouseEvent event) {
                                if (!pointClicked().equals(0)) {
                                    players.get(playerTurn).settlementsAvail--;
                                    selected = true;
                                }
                            }

                        });

                        try 
                        {
                            Thread.sleep(1000 * 60 * 3);
                        } 
                        catch(InterruptedException er)
                        {
                             // this part is executed when an exception (in this example InterruptedException) occurs
                        }
                    }

                }

                gameStatus = "Ended";

            }

        });

【问题讨论】:

  • 您确定要在实际的点击处理程序中休眠吗?这可能会在相当长的一段时间内锁定您的整个程序(或至少是用户交互)。并请发布实际的异常和错误消息。
  • 对不起,我不清楚这一点,但 startGame 处理程序与我想留出时间的点击处理程序(画布)是分开的。画布点击处理程序位于代码下方。

标签: java javafx thread-sleep


【解决方案1】:

您正在 FX 应用程序线程上睡觉。这将冻结您的整个 GUI,使其无法处理用户输入。而是使用TimeLine:

Timeline timer = new Timeline(            
      new KeyFrame(Duration.seconds(60 * 3), event -> finishedSleeping())
);
timer.play();

或 javafx Task:

Task<Void> timer = new Task<Void>() {
    @Override
    protected Void call() throws Exception {
       try {
            Thread.sleep(1000 * 60 * 3);
       } catch (InterruptedException e) {}
       return null;    
    }
};
timer.setOnSucceeded(event -> finishedSleeping());
new Thread(timer).start();

在此示例中,睡眠发生在与 FX 应用程序线程不同的线程上。 3 分钟结束后,将在 FX 应用程序线程上调用 finishedSleeping()

【讨论】:

  • 使用第一种方法,应用程序不再崩溃,但计时器不做任何事情。一切照常进行。至于第二种方法,我得到了错误。具体来说:类型 Task 不带参数,方法不覆盖或实现超类型中的方法
  • @ShoeLace1291 对于第二种方法,您必须导入 javafx.concurrent.Task。两种方法都应该可以正常工作。从您调用timer.play()/new Thread(timer).start(); 的那一点开始,在调用示例中的finishedSleeping() 之前大约需要3 分钟。当然,您需要实现一个事件处理程序 (event -&gt; finishedSleeping()),而不是当前在代码中的循环,以处理 3 分钟等待结束。
  • 好的,所以我最初使用第一种方法导入了错误的 Task 类。但是上面的方法都没有做任何事情。一切都会立即执行。
  • @ShoeLace1291 当你插入两个方法之一的代码时,timer.play();/new Thread(timer).start(); 之后的所有内容都会立即执行,因为休眠发生在另一个线程上。这就是为什么你必须放弃两个封闭的 for 循环。替换 finishedSleeping() 的代码将在 3*60 秒后执行。
猜你喜欢
  • 1970-01-01
  • 2017-04-07
  • 2014-01-24
  • 2017-08-21
  • 2012-01-24
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多