I hope I'm not duplicating a question, but I couldn't find one specifically for my issue. I'm developing a small math flash card application, using JavaFX to create the GUI. The program should runs as follow:
The problems is getText()
from user textfield is processed as soon as start button is pressed, without giving the user a chance to enter an answer. How do I make the program wait for X amount of seconds or for the next button to be clicked before processing the user's answer? Here's my code:
//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();
});
Here is the problem code... at least how I see it.
//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));
}
I've tried using Thread.sleep(X)
but that freezes the gui for however long I specify and then goes through the addAsk()
method and the loop before going to the test screen. (I know because I had the program set up to print the questions and answer input to the console). It shows the last question and that's all.
I didn't include the next button code because I can't get the gui to go to the test page anyway.
Any help on any of the code is appreciated.
This can be achieved by various methods.
PauseTransition is one of the many apt solution present. It waits for X time interval
and then performs a Task
. It can start
, restart
, stop at any moment
.
Here is an example of how it can used to achieve a similar result.
Complete Code
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.stream.IntStream;
public class Main extends Application {
int questionIndex = 0;
int noOfQuestions = 10;
@Override
public void start(Stage stage) {
VBox box = new VBox(10);
box.setPadding(new Insets(10));
Scene scene = new Scene(new ScrollPane(box), 500, 200);
ObservableList<String> questions =
FXCollections.observableArrayList("1) Whats your (full) name?",
"2) How old are you?",
"3) Whats your Birthday?",
"4) What starsign does that make it?",
"5) Whats your favourite colour?",
"6) Whats your lucky number?",
"7) Do you have any pets?",
"8) Where are you from?",
"9) How tall are you?",
"10) What shoe size are you?");
ObservableList<String> answers = FXCollections.observableArrayList();
final PauseTransition pt = new PauseTransition(Duration.millis(5000));
Label questionLabel = new Label(questions.get(questionIndex));
Label timerLabel = new Label("Time Remaining : ");
Label time = new Label();
time.setStyle("-fx-text-fill: RED");
TextField answerField = new TextField();
Button nextQuestion = new Button("Next");
pt.currentTimeProperty().addListener(new ChangeListener<Duration>() {
@Override
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
time.setText(String.valueOf(5 - (int)newValue.toSeconds()));
}
});
box.getChildren().addAll(questionLabel, answerField, new HBox(timerLabel, time), nextQuestion);
nextQuestion.setOnAction( (ActionEvent event) -> {
answers.add(questionIndex, answerField.getText());
//Check if it is the last question
if(questionIndex == noOfQuestions-1) {
pt.stop();
box.getChildren().clear();
IntStream.range(0, noOfQuestions).forEach(i -> {
Label question = new Label("Question : " + questions.get(i));
question.setStyle("-fx-text-fill: RED");
Label answer = new Label("Answer : " + answers.get(i));
answer.setStyle("-fx-text-fill: GREEN");
box.getChildren().addAll(question, answer);
});
}
// All other time
else {
//Set new question
questionLabel.setText(questions.get(++questionIndex));
answerField.clear();
pt.playFromStart();
}
});
pt.setOnFinished( ( ActionEvent event ) -> {
nextQuestion.fire();
});
pt.play();
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With