等待任务完成而不阻塞javafx中的UI
我试图使用JavaFX创建一个测验应用程序,因为我使用等待任务完成而不阻塞javafx中的UI,java,multithreading,asynchronous,javafx,ui-thread,Java,Multithreading,Asynchronous,Javafx,Ui Thread,我试图使用JavaFX创建一个测验应用程序,因为我使用 Q1.invoke(); Q2.invoke(); 这些问题将显示在UI线程上 public void display(McqQuestion mcqQuestion) { resourceAsStream = getClass().getResourceAsStream("/mcqview.fxml"); fxmlLoader = new FXMLLoader(); if (execut
Q1.invoke();
Q2.invoke();
这些问题将显示在UI线程上
public void display(McqQuestion mcqQuestion) {
resourceAsStream = getClass().getResourceAsStream("/mcqview.fxml");
fxmlLoader = new FXMLLoader();
if (executorService==null) executorService =Executors.newSingleThreadExecutor();
Parent root = null;
try {
root = fxmlLoader.load(resourceAsStream);
Mcqview controller = fxmlLoader.getController();
controller.setAnswer1(mcqQuestion.getAnswers().get(0));
//controller class has setters to accept question properties.
controller.multipleChoiceQuestionType = this;
this.view.getBorderPane().setCenter(root);
}
显示问题后,我需要等待直到得到答案,如果没有得到答案,则应调用下一个问题。因此,我在display方法中引入了一个线程来等待超时
submit = executorService.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
submit.get(20,TimeUnit.SECONDS);
System.out.println("waiting finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
自从
future.get()之后
是一个阻塞调用,它也会阻塞UI线程,如何在不阻塞UI线程的情况下实现这一点。对于UI中的更改,您应该使用
Platform.runLater(() -> {
});
对于线程,您应该使用:
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
return null;
}
};
希望它对您应该使用的UI的更改有所帮助
Platform.runLater(() -> {
});
对于线程,您应该使用:
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
return null;
}
};
希望这会有帮助不要为此使用单独的线程。这只会让事情变得更难。JavaFX提供的等待方式不需要您处理并发性问题 在这种情况下,可以使用
onFinished
处理程序从PauseTransition
执行等待。为用户输入处理来自事件处理程序的应答
private static class Question {
private final String questionText;
private final String answers[];
private final int correctAnswerIndex;
public Question(String questionText, String[] answers, int correctAnswerIndex) {
if (answers.length != 3) {
// for simplicity's sake allow only exactly 3 answers
throw new IllegalArgumentException();
}
this.questionText = questionText;
this.answers = answers;
this.correctAnswerIndex = correctAnswerIndex;
}
}
private VBox questionPane;
private Label questionText;
private Button[] answerButtons;
private PauseTransition pauseTransition;
private Question currentQuestion;
private void answer(int index) {
pauseTransition.stop(); // no longer wait for timeout
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText((index == currentQuestion.correctAnswerIndex)
? "correct answer"
: "incorrect answer");
// show result and exit
alert.showAndWait();
Platform.exit();
}
private void ask(Question question) {
questionText.setText(question.questionText);
for (int i = 0; i < 3; i++) {
answerButtons[i].setText(question.answers[i]);
}
currentQuestion = question;
pauseTransition.playFromStart(); // start timeout timer
}
private void timeout() {
pauseTransition.stop();
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText("your time ran out");
// cannot use showAndWait form animation directly
Platform.runLater(() -> {
// show result and exit
alert.showAndWait();
Platform.exit();
});
}
@Override
public void start(Stage stage) {
pauseTransition = new PauseTransition(Duration.seconds(10));
pauseTransition.setOnFinished(evt -> timeout());
questionText = new Label();
questionText.setWrapText(true);
questionPane = new VBox(questionText);
questionPane.setPrefSize(400, 400);
answerButtons = new Button[3];
for (int i = 0; i < 3; i++) {
final int answerIndex = i;
Button button = new Button();
button.setOnAction(evt -> answer(answerIndex));
answerButtons[i] = button;
questionPane.getChildren().add(button);
}
Scene scene = new Scene(questionPane);
stage.setScene(scene);
stage.show();
Question question = new Question(
"What is the answer to the ultimate question of life, the universe, and everything?",
new String[]{"Mew", "42", "Peanut butter"},
1
);
ask(question);
}
私有静态类问题{
私有最终字符串文本;
私有最终字符串答案[];
私人最终int correctAnswerIndex;
公共问题(字符串questionText,字符串[]答案,int correctAnswerIndex){
if(answers.length!=3){
//为了简单起见,只允许3个答案
抛出新的IllegalArgumentException();
}
this.questionText=questionText;
这个。答案=答案;
this.correctAnswerIndex=correctAnswerIndex;
}
}
专用VBox问题窗格;
自有标签文本;
专用按钮[]应答按钮;
专用暂停转换暂停转换;
私人问题;
专用无效答案(整数索引){
pauseTransition.stop();//不再等待超时
Alert Alert=新警报(Alert.AlertType.INFORMATION);
alert.setContentText((索引==currentQuestion.correctAnswerIndex)
?“正确答案”
:“回答不正确”);
//显示结果并退出
alert.showAndWait();
Platform.exit();
}
私人提问(问题){
questionText.setText(question.questionText);
对于(int i=0;i<3;i++){
答案按钮[i].setText(问题.答案[i]);
}
当前问题=问题;
pauseTransition.playFromStart();//启动超时计时器
}
私有无效超时(){
pauseTransition.stop();
Alert Alert=新警报(Alert.AlertType.INFORMATION);
setContentText(“您的时间用完了”);
//无法直接使用showAndWait表单动画
Platform.runLater(()->{
//显示结果并退出
alert.showAndWait();
Platform.exit();
});
}
@凌驾
公众假期开始(阶段){
pauseTransition=新的pauseTransition(持续时间.秒(10));
setOnFinished(evt->timeout());
questionText=新标签();
questionText.setWrapText(true);
questionPane=新的VBox(questionText);
问题窗格。setPrefSize(400400);
应答按钮=新按钮[3];
对于(int i=0;i<3;i++){
最终综合回答指数=i;
按钮按钮=新按钮();
按钮设置操作(evt->应答(应答索引));
应答按钮[i]=按钮;
questionPane.getChildren().add(按钮);
}
场景=新场景(问题窗格);
舞台场景;
stage.show();
问题=新问题(
“生命、宇宙和一切的终极问题的答案是什么?”,
新字符串[]{“Mew”、“42”、“花生酱”},
1.
);
问(问题);
}
您可以通过不同的方式轻松实现超时或回答问题的结果,例如,通过询问下一个问题或在最后一个问题完成时显示结果。不要为此使用单独的线程。这只会让事情变得更难。JavaFX提供的等待方式不需要您处理并发性问题 在这种情况下,可以使用
onFinished
处理程序从PauseTransition
执行等待。为用户输入处理来自事件处理程序的应答
private static class Question {
private final String questionText;
private final String answers[];
private final int correctAnswerIndex;
public Question(String questionText, String[] answers, int correctAnswerIndex) {
if (answers.length != 3) {
// for simplicity's sake allow only exactly 3 answers
throw new IllegalArgumentException();
}
this.questionText = questionText;
this.answers = answers;
this.correctAnswerIndex = correctAnswerIndex;
}
}
private VBox questionPane;
private Label questionText;
private Button[] answerButtons;
private PauseTransition pauseTransition;
private Question currentQuestion;
private void answer(int index) {
pauseTransition.stop(); // no longer wait for timeout
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText((index == currentQuestion.correctAnswerIndex)
? "correct answer"
: "incorrect answer");
// show result and exit
alert.showAndWait();
Platform.exit();
}
private void ask(Question question) {
questionText.setText(question.questionText);
for (int i = 0; i < 3; i++) {
answerButtons[i].setText(question.answers[i]);
}
currentQuestion = question;
pauseTransition.playFromStart(); // start timeout timer
}
private void timeout() {
pauseTransition.stop();
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText("your time ran out");
// cannot use showAndWait form animation directly
Platform.runLater(() -> {
// show result and exit
alert.showAndWait();
Platform.exit();
});
}
@Override
public void start(Stage stage) {
pauseTransition = new PauseTransition(Duration.seconds(10));
pauseTransition.setOnFinished(evt -> timeout());
questionText = new Label();
questionText.setWrapText(true);
questionPane = new VBox(questionText);
questionPane.setPrefSize(400, 400);
answerButtons = new Button[3];
for (int i = 0; i < 3; i++) {
final int answerIndex = i;
Button button = new Button();
button.setOnAction(evt -> answer(answerIndex));
answerButtons[i] = button;
questionPane.getChildren().add(button);
}
Scene scene = new Scene(questionPane);
stage.setScene(scene);
stage.show();
Question question = new Question(
"What is the answer to the ultimate question of life, the universe, and everything?",
new String[]{"Mew", "42", "Peanut butter"},
1
);
ask(question);
}
私有静态类问题{
私有最终字符串文本;
私有最终字符串答案[];
私人最终int correctAnswerIndex;
公共问题(字符串questionText,字符串[]答案,int correctAnswerIndex){
if(answers.length!=3){
//为了简单起见,只允许3个答案
抛出新的IllegalArgumentException();
}
this.questionText=questionText;
这个。答案=答案;
this.correctAnswerIndex=correctAnswerIndex;
}
}
专用VBox问题窗格;
自有标签文本;
专用按钮[]应答按钮;
专用暂停转换暂停转换;
私人问题;
专用无效答案(整数索引){
pauseTransition.stop();//不再等待超时
Alert Alert=新警报(Alert.AlertType.INFORMATION);
alert.setContentText((索引==currentQuestion.correctAnswerIndex)
?“正确答案”
:“回答不正确”);
//显示结果并退出
alert.showAndWait();
Platform.exit();
}
私人提问(问题){
questionText.setText(question.questionText);
对于(int i=0;i<3;i++){
答案按钮[i].setText(问题.答案[i]);
}
当前问题=问题;
pauseTransition.playFromStart();//启动超时计时器
}
私有无效超时(){
pauseTransition.stop();
Alert Alert=新警报(Alert.AlertType.INFORMATION);
setContentText(“您的时间用完了”);
//无法直接使用showAndWait表单动画
Platform.runLater(()->{
//显示结果并退出
alert.showAndWait();
Platform.exit();
});
}
@凌驾
公众假期开始(阶段)