How to wait for user's action in JavaFX (in the same stage)

↘锁芯ラ 提交于 2019-12-31 05:41:07

问题


Do you know how to wait for the user's input in a for loop? I don't mean the showAndWait() method, because I am not opening a new dialogue stage for the user. So for example, each round of the for loop should be waiting for the user to push a button before going ahead with the next round.

How is it possible? Many thanks!

UPDATE:

Now it came to my mind, that it would work with a while(buttonNotPressed){} but is it a good solution? I mean the while loop is running in this case as crazy until the user won't push the button. Or doest it work somehow similarly with wait methods?

Imagine it as a session: User starts session with handleStart() You give the user 5 questions, one after one. In every iteration, the user can answer the upcoming question and he can save or submit the answer by handleSaveButton() You process the answer as you want, and go ahead with the next iteration. The point is, that the iteration must stop, until the save button hasn't been pressed.


回答1:


Don't do it like that. The FX toolkit, like any event-driven GUI toolkit, already implements a loop for the purposes of rendering the scene graph and processing user input each iteration.

Just register a listener with the button, and do whatever you need to do when the button is pressed:

button.setOnAction(event -> {
    // your code here...
});

If you want the action to change, just change the state of some variable each time the action is performed:

private int round = 0 ;

// ...

button.setOnAction(event -> {
    if (round < 5) {
        System.out.println("Round "+round);
        System.out.println("User's input: "+textArea.getText());
        round++ ;
    }
});



回答2:


I recently ran into a similar problem where I wanted something to be executed with an interval (if that's what you mean), until the user fired an event. I found 3 ways to do this:

UPDATE

You should use the stop/cancel method for the custom runnable and timer or else the thread will still be running when you exit the application. Timeline seems do it by itself.

Using a Timer:

Timer timer = new Timer();
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        System.out.println("Printed every second.");
    }
};
timer.scheduleAtFixedRate(task, 0, 1000);
//timer.cancel();

With a TimeLine:

Timeline tl = new Timeline(new KeyFrame(Duration.millis(1000), e -> {
    System.out.println("Timeline");
}));

tl.setCycleCount(Timeline.INDEFINITE);
tl.play();
//tl.stop();

Or making your own runnable class:

public class Runner implements Runnable {
    private final Thread thread = new Thread(this);
    private boolean run;

    @Override
    public void run() {
        while(run) {
            try {
                System.out.println("Printed from loop");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                run = false;
            }
        }
    }

    public void start() {
        run = true;
        thread.start();
    }

    public void stop() {
        if(run) {
            thread.interrupt();
            System.out.print("Thread has stopped.");
        }
    }
}

And then when a person clicks fx. a button the event would stop using the example James_D posted:

Button btn = new Button("Button");

btn.setOnAction(e -> {
    timer.cancel();
    tl.stop();
    runner.stop();
});


来源:https://stackoverflow.com/questions/29374129/how-to-wait-for-users-action-in-javafx-in-the-same-stage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!