等到按下任何按钮?

Wait until any button is pressed?

我正在用 JavaFX 编写 TicTacToe 游戏。我决定将一个面板制作成 9 (3x3) 个按钮,并更改文本:“”(如果为空)或 "X" 或 "O"。除了一件事,一切都很好......我被困在这里:

public void game() {

        while(keepPlaying) {
            if(computerTurn) {;
                computerMove();
            }else {
                while(waitForUser) {
                    //wait until any of 9 buttons is pushed!
                }
            }

            if (checkResult()) {
                keepPlaying = false;
            }
            computerTurn = !computerTurn;
        }
    }

如何等待用户按下这 9 个按钮中的任何一个,然后继续计算机转动?

我需要在控制台应用程序中等待扫描仪输入,但此输入必须是 9 个按钮之一...

我知道很少"possible duplicates",但实际上那些问题是用我这里不能用的方法解决的,比如timer。如果我错了请纠正我。

不应在 JavaFX 中阻塞应用程序线程,因为它会冻结 UI。因此,这样的循环不太适合 JavaFX 应用程序。相反,您应该对用户输入做出反应:

public void game() {
    if (keepPlaying && computerTurn) {
        computerMove();
        if (checkResult()) {
            keepPlaying = false;
        }
        computerTurn = false;
    }
}

// button event handler
private void button(ActionEvent event) {
    if (keepPlaying) {
        Button source = (Button) event.getSource();

        // probably the following 2 coordinates are computed from GridPane indices
        int x = getX(source);
        int y = getY(source);

        // TODO: update state according to button pressed

        if (checkResult()) {
            keepPlaying = false;
        } else {
            computerMove();
            if (checkResult()) {
                keepPlaying = false;
            }
        }
    }

}

从 javafx 9 开始,在应用程序线程上有一个 public API for "pausing" 但是:

private static class GridCoordinates {
    int x,y;
    GridCoordinates (int x, int y) {
        this.x = x;
        this.y = y;
    }
}

private final Object loopKey = new Object();

public void game() {
    while(keepPlaying) {
        if(computerTurn) {
            computerMove();
        } else {
            // wait for call of Platform.exitNestedEventLoop​(loopKey, *)
            GridCoordinates coord = (GridCoordinates)  Platform.enterNestedEventLoop​(loopKey);

            // TODO: update state
        }

        if (checkResult()) {
            keepPlaying = false;
        }
        computerTurn = !computerTurn;
    }
}

private void button(ActionEvent event) {
    if (keepPlaying) {
        Button source = (Button) event.getSource();

        // probably the following 2 coordinates are computed from GridPane indices
        int x = getX(source);
        int y = getY(source);

        Platform.exitNestedEventLoop​(loopKey, new GridCoordinates(x, y));
    }
}