User interface 如何使用JavaFX中的后台工作在GUI中进行更改?
从所有的搜索和阅读中可以清楚地看到,我需要调用Platform.runLater()来更改GUI。似乎我还需要使用可运行的界面。也许我也应该使用任务 但我不知道该怎么使用它们。另外,我不确定该把它们放在哪一类。我是JavaFX的新手 我的试用版JavaFX项目只有一个标签和一个文本字段。标签包含一个问题,文本字段用于回答。很简单 我在这里遇到了问题: 答案检查方法在一个单独的类中。我不知道如何访问GUI/FXML的组件并对其进行更改。其他类中的方法是静态的,而GUI/FXML的组件是非静态的 因为我的实际项目会有很多测验,所以我热衷于使用单独的课程来检查答案 这里只有3个小班是相关的:User interface 如何使用JavaFX中的后台工作在GUI中进行更改?,user-interface,javafx,task,runnable,User Interface,Javafx,Task,Runnable,从所有的搜索和阅读中可以清楚地看到,我需要调用Platform.runLater()来更改GUI。似乎我还需要使用可运行的界面。也许我也应该使用任务 但我不知道该怎么使用它们。另外,我不确定该把它们放在哪一类。我是JavaFX的新手 我的试用版JavaFX项目只有一个标签和一个文本字段。标签包含一个问题,文本字段用于回答。很简单 我在这里遇到了问题: 答案检查方法在一个单独的类中。我不知道如何访问GUI/FXML的组件并对其进行更改。其他类中的方法是静态的,而GUI/FXML的组件是非静态的 因
package com.dan.view;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import com.dan.ans.Ans;
import com.dan.qn.Qn;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class ViewController implements Initializable {
private static String textFieldInput; // I don't know how to access the typed info in the textField from another class. So I store it here and get it from it.
// This is the getter I use for it. (See above)
public static String getTextFieldInput() {
return textFieldInput;
}
@FXML
private Label label;
@FXML
private TextField textField;
@Override
public void initialize(URL location, ResourceBundle resources) {
Qn.setQuestion(); // This method is in the Qn class. It retrieves data from the db file and keeps them in variables.
label.setText(Qn.getQn()); // This sets the label's text using the retrieved data. So you see the first question when the program opens.
}
// Event Listener on TextField[#textField].onAction
public void enter(ActionEvent event) throws IOException {
textFieldInput = textField.getText(); // Stores the typed info in the variable to be accessed from elsewhere.
Ans.checkAns(); // Runs the checkAns to check if the typed answer is correct or not.
}
}
“Launcher”方法看起来就像任何带有主类的方法,所以我没有在这里分享它的代码
有人能告诉我如何从其他类(如“Ans”)更新GUI中的组件吗?我很确定我应该使用Platform.runLater()和Runnable。也可能是Tasks。我看过几个例子,但不清楚如何在这个上下文中使用它
非常感谢!:)这里的问题不是特别清楚。自然的(无论如何,对我来说)方法就是将
checkAnswer(…)
方法简单地变成一个“按框上的说明做”的方法,即将答案作为参数,检查它,并向调用方返回一个值,指示它是否正确
这样,您还可以避免所有丑陋的静态黑客攻击
public class Ans {
public boolean checkAns(String answer) {
// not really sure what Qn is here, but you can also clean this up and
// get rid of the static methods
if (answer.equalsIgnoreCase(Qn.getAns()) {
// not sure if this really belongs here?
Qn.setQuestion(); // really takes no parameters? Sets it to what, then?
return true ;
} else {
return false ;
}
}
}
然后在你的控制器里,你可以
public class ViewController implements Initializable {
private Ans ans ;
@FXML
private Label label;
@FXML
private TextField textField;
@Override
public void initialize(URL location, ResourceBundle resources) {
ans = new Ans();
// ...
}
// ...
public void enter(ActionEvent event) {
if (ans.checkAns(textField.getText())) {
// update UI to show answer was correct, etc
} else {
// update UI to show answer was incorrect...
}
}
// ...
}
请注意,这如何允许您保持适当的关注点分离:Ans
类根本不需要知道关于UI的任何信息(它根本不应该知道),并且所有特定于UI的代码都封装在它所属的控制器类中
现在还不清楚您为什么询问Platform.runLater(…)
并使用Task
,因为您发布的代码似乎都不涉及任何后台线程(也就是说,这些代码似乎都没有花费相当长的运行时间)。例如,如果checkAns(…)
方法正在执行一些远程查找,并且确实需要时间运行,那么您将在任务中执行它,并从任务的onSucceeded
处理程序更新UI。参见,例如。你的问题似乎更多的是关于基本的OO设计以及如何定义不同对象之间的关系;我认为您实际上根本没有询问线程问题。本例中的背景工作在哪里?示例代码似乎根本不需要单独的线程。很抱歉没有说清楚。这是“Ans”类中的代码(第一个代码示例)。在评论中,我提到了我想做但不能做的事情。就像我想从那里设置标签文本,但我不能。因为我不知道怎么做,所以我就在那里放了一个系统。在它旁边的评论中,我提到了我真正想要做的事情。但是这些和线程有什么关系呢?您在任何地方都没有真正解释过这一点。不过,更一般地说,您应该使用一个模型类,并从控制器(或多个控制器)观察和更新它。请参见示例Still:“我想在GUI标签上放置另一个类的字符串”。这与线程有什么关系?为什么您要询问平台.runLater()
?静态或非静态与任何事情有什么关系?如果要调用非静态方法,需要将控制器实例的引用传递给Ans
类(尽管我也不会使该类中的方法成为静态的),非常感谢。你的解决方案很有意义。我决定把“Ans”中的所有代码都插入控制器。只需要多加几行。另外,感谢您解释Platform.runLater()的用途。现在它有意义了。我理解我的问题不够清楚,我真的很感谢你抽出时间回答我。:)
public class ViewController implements Initializable {
private Ans ans ;
@FXML
private Label label;
@FXML
private TextField textField;
@Override
public void initialize(URL location, ResourceBundle resources) {
ans = new Ans();
// ...
}
// ...
public void enter(ActionEvent event) {
if (ans.checkAns(textField.getText())) {
// update UI to show answer was correct, etc
} else {
// update UI to show answer was incorrect...
}
}
// ...
}