我有一个教程中的问题 MVP将Spring Boot与JavaFX集成
GitHub:https://github.com/mvpjava
Youtube:https://www.youtube.com/watch?v=hjeSOxi3uPg
其中有一个名为 initialization()的公共方法,我不知道在Spring启动应用程序启动后如何调用它。我在类和fxml文件中到处查看它可以引用它,我找不到。
我想知道如何调用此方法,因为我还想对JavaFX控件进行一些初始化。我尝试使用@PostConstruct,但这是错误的,因为所有bean都是在创建任何JavaFX控件之前创建的,因此我得到空指针异常。
如果有人能在这件事上给我启发,我将非常感激。
这是我提到的公共方法 initialization()的类。
@Component
public class ConsoleTabController {
@FXML private TextArea missionOverviewText;
@FXML private ListView<String> missionsList;
@Autowired @Qualifier("stringPrintWriter")
private PrintWriter stackTraceWriter;
@Autowired MissionsService service;
private TabPaneManger tabManager;
public void initialize() {
ObservableList<String> missions = FXCollections.observableArrayList("Apollo", "Shuttle", "Skylab");
missionsList.setItems(missions);
}
@FXML
private void onMouseClicked(MouseEvent event) {
missionOverviewText.clear();
final String selectedItem = missionsList.getSelectionModel().getSelectedItem();
missionOverviewText.positionCaret(0);
missionOverviewText.appendText(getInfo(selectedItem));
}
@Autowired
private void setTabManager(TabPaneManger tabManager){
this.tabManager = tabManager;
}
public String getInfo(String selectedItem) {
String missionInfo = null ;
try {
missionInfo = service.getMissionInfo(selectedItem);
getLog().appendText("Sucessfully retrieved mission info for " + selectedItem + "\n");
} catch (IOException exception) {
exception.printStackTrace (stackTraceWriter);
getLog().appendText(stackTraceWriter.toString() + "\n");
}
return missionInfo;
}
public TextArea getMissionOverviewText() {
return missionOverviewText;
}
public ListView<String> getMissionsList() {
return missionsList;
}
private TextArea getLog(){
return tabManager.getVisualLog();
}
}
答案 0 :(得分:4)
initialize()
调用FXMLLoader
方法(我认为你的意思)。通常,对于FXMLLoader
,执行顺序为:
FXMLLoader
加载FXML文件并解析它fx:controller
属性,则它会获得对该类实例的引用;它通过将控制器类传递给controllerFactory
(如果已设置)或者通过调用控制器类的默认构造函数来完成此操作。fx:id
属性的所有元素都会注入到匹配@FXML
注释的控制器字段中FXMLLoader
会调用控制器的initialize()
方法(如果有)。在您的情况下,我假设您将FXMLLoader
的控制器工厂设置为委托给Spring应用程序上下文,即我假设您有类似
ApplicationContext appContext = ... ; // Spring bean factory
FXMLLoader loader = new FXMLLoader();
loader.setLocation(...);
loader.setControllerFactory(appContext::getBean);
Parent ui = loader.load();
这意味着将通过将控制器类传递给Spring bean工厂的getBean(...)
方法来创建控制器实例。因此,如果FXML文件具有fx:controller="ConsoleTabController"
,则FXMLLoader
实质上会调用
Object controller = appContext.getBean(ConsoleTabController.class);
在上面的第2步中。 Spring应用程序上下文创建一个ConsoleTabController
实例(假设您已将控制器bean配置为具有原型范围,您应该这样做),注入任何@AutoWired
- 带注释的属性,调用任何@PostConstruct
- 注释方法,然后将控制器提供给FXMLLoader
。因此,当您将Spring bean工厂用作控制器工厂时,执行的总体顺序是
FXMLLoader
加载FXML文件并解析它
fx:controller
属性:
@Autowired
- 带注释的属性注入控制器实例
@PostConstruct
- 带注释的方法
FXMLLoader
fx:id
属性的所有元素都会被@FXML
注入到FXMLLoader
注释的控制器字段中
FXMLLoader
调用控制器的initialize()
方法(如果有)。
请注意,基本上有两种不同类型的注入字段,以及两种不同类型的&#34;初始化&#34;此方案中的方法。首先注入&#34; Spring注入字段&#34;,注释@Autowired
(或@Inject
),然后注入&#34; Spring初始化方法&#34; (带注释的@PostConstruct
)被调用。之后,&#34; FXML注入字段&#34; (注释@FXML
)被注入,然后&#34; FXML初始化方法&#34; (调用initialize()
的那个)被调用。您的示例代码中没有任何@PostConstruct
方法,但要注意的一点是,在<{em> @FXML
之前调用这些方法 - 注释字段已初始化。