【问题标题】:JavaFX wait for user inputJavaFX 等待用户输入
【发布时间】:2017-05-02 21:53:57
【问题描述】:

我正在编写一个棋盘游戏,我需要在玩家移动时检查敌人并提示进行攻击。但是由于游戏的制作方式,在 JavaFX 应用程序线程上调用 move 方法,我希望能够提示用户是否要与敌人战斗。

我工作正常的对话框使用等待和通知哪个在主线程上不起作用而不会导致程序崩溃,有谁知道如何暂停该线程的执行,直到用户单击其中一个按钮。

我很抱歉描述得太晚了。

检查敌人的方法 此方法检查敌人并在用户选择是时返回敌人。它在 JavaFX 线程上运行。

private Ship pathBattle(Vector gridPosition){
  //Check if there are ships on the path to the destination
  for(Button cell : activeButtons){
     //Check the button position is not that of the current button, dont go past the current button
     Vector pixPosition = new Vector(cell.getLayoutX(), cell.getLayoutY());
     //Convert to a grid referance
     Vector gridPos = Vector.pixToGrid(pixPosition);
     if(!gridPos.equals(gridPosition)){
        //This button is not the destination

        //Check for any ships on that cell
        Ship collided = Ship.isOccupiedButton(cell);//Returns the ship if there is one on the cell
        if(collided != null){
           //There is a ship, prompt to battle
           boolean battle = UtilPopups.showConfirmationDialog("Do you want to battle " + collided.getName(), "YAR!", "NAY!");

           Game.printError("Ship collision");

           if(battle){
              return collided; //Return the ship to battle
           }
        }
     }

     //On to the next button
  }

  return null;
}

显示弹窗的代码 这确实适用于 porgram 的其他领域,没有问题

public static boolean showConfirmationDialog(String lblPrompt, String btnYes, String btnNo){
  //Check if the confirmation controller is not null
  if(confirmationDialog != null){
     confirmationDialog.lbl_prompt.setText(lblPrompt);
     confirmationDialog.btn_no.setText(btnNo);
     confirmationDialog.btn_yes.setText(btnYes);

     //Show the base
     show(confirmationDialog.base_pane);

     //Pause this thread until user input is given from GUI thread
     synchronized (confirmationDialog) {
        try{
           confirmationDialog.wait();
        } catch (Exception e) {
           e.printStackTrace();
        }
     }

     //Program resumed, user input given and stored in response
     if(confirmationDialog.response.equals("yes")){
        confirmationDialog.response = null; //Set back to null
        return true;
     } else {
        confirmationDialog.response = null; //Set back to null
        return false;
     }
  }

  //Class not initialized
  Game.printError("UtilPopups->showConfirmationDialog: Dialog NULL!");
  return false;
}

【问题讨论】:

    标签: java multithreading javafx


    【解决方案1】:

    用于在显示对话框期间阻塞任何调用者线程,例如:

    static private void showAndBlock(Dialog dialog) {
        if (Platform.isFxApplicationThread()) {
            dialog.showAndWait();
        } else {
            CountDownLatch lock = new CountDownLatch(1);
            Platform.runLater(() -> {
                dialog.showAndWait();
                lock.countDown();
            });
            try {
                lock.await();
            } catch (InterruptedException e) {
                // Just in case you call yourTherad.interrupt(),
                // the thread will be joined forcibly through here.
            }
        }
    }
    

    但我不确定它是否适用于您的线程设计。

    【讨论】:

      【解决方案2】:

      collided 方法实际上什么都没有,它不要求输入,所以它不能工作。

      我想,抱歉英语不好

      【讨论】:

      • 它不是一种方法,它是一个变量,具有 Ship(Enemy) 的值,如果正在测试的图块上没有 Ship,则为 null。