等待然后接收文本字段输入而不冻结GUI

gab*_*390 5 java user-interface multithreading javafx freeze

我希望我不会重复一个问题,但我找不到专门针对我的问题.我正在开发一个小型数学闪存卡应用程序,使用JavaFX创建GUI.该计划应如下运行:

  1. 用户选择设置,然后按开始按钮.
  2. gui显示用户输入的问题和文本字段.
  3. 用户在X秒内输入答案或gui自动移动到下一个问题 - 或者,用户可以通过按下一个按钮立即转到下一个问题.
  4. GUI显示得分和平均值.

问题getText()来自用户文本字段,只要按下开始按钮就会处理,而不会给用户输入答案的机会.在处理用户的答案之前,如何让程序等待X秒或者单击下一个按钮?这是我的代码:

//start button changes view and then runs startTest()
start.setOnAction(e -> {

        setLeft(null);
        setRight(null);

        setCenter(test_container);
        running_program_title.setText(getDifficulty().name() + " Test");
        buttons_container.getChildren().clear();
        buttons_container.getChildren().addAll(next, quit, submit);

        startTest();
    });
Run Code Online (Sandbox Code Playgroud)

这是问题代码......至少我是怎么看的.

//startTest method calls askAdd() to ask an addition question
void startTest() {

    int asked = 0;
    int correct = 0;

    while (asked < numberOfQuestions) {
        if(askAdd()){
        correct++;
        asked++;
    }
}

boolean askAdd() {

    int a = (int) (Math.random() * getMultiplier());
    int b = (int) (Math.random() * getMultiplier());

     //ask question
     question.setText("What is " + a + " + " + b + "?");

     //code needed to pause method and wait for user input for X seconds

     //retrieve user answer and return if its correct
     return answer.getText().equalsIgnoreCase(String.valueOf(a+b));
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用Thread.sleep(X)但是冻结gui,无论我指定多久,然后addAsk()在进入测试屏幕之前完成方法和循环.(我知道,因为我已经设置了程序来打印问题并回答控制台的输入).它显示了最后一个问题,就是这样.

我没有包含下一个按钮代码,因为无论如何我都无法让gui进入测试页面.

任何代码的任何帮助表示赞赏.

J A*_*kin 0

对于计时器,您应该(IMO)使用Timeline. 这是一个例子:

public class MultiGame extends Application {
    ProgressBar progressBar;

    final int allowedTime = 5; //seconds
    final DoubleProperty percentOfTimeUsed = new SimpleDoubleProperty(0);
    final Timeline timer =
            new Timeline(
                new KeyFrame(
                        Duration.ZERO, new KeyValue(percentOfTimeUsed, 0)),
                new KeyFrame(
                        Duration.seconds(allowedTime), new KeyValue(percentOfTimeUsed, 1))
            );

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        BorderPane root = new BorderPane();

        progressBar = new ProgressBar();
        progressBar.progressProperty().bindBidirectional(percentOfTimeUsed);
        root.setTop(progressBar);

        Button answer = new Button("Answer");
        answer.setOnAction(ae -> restart());// the on answer handler

        Button skip = new Button("Skip");
        skip.setOnAction(ae -> restart());// the skip question handler

        HBox mainContent = new HBox(15,
                new Label("Your Question"), new TextField("The answer"),  answer, skip);
        root.setCenter(mainContent);

        timer.setOnFinished(ae -> restart());// the end of timer handler

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

        restart();
    }

    void restart() { timer.stop(); timer.playFromStart(); }

    void pause() { timer.pause(); }

    void resume() { timer.play(); }
}
Run Code Online (Sandbox Code Playgroud)

您只需要从时间线开始和restart方法之间的输入中捕获文本。