我正在尝试使用 JavaFX 创建一个客户端应用程序作为 UI 框架,与 Spring 集成以利用现代 UI、依赖注入(inject)、AOP 和丰富的 REST API。在我的 JavaFX Application
的 init()
方法中,创建了一个 SpringApplication
来 Autowiring 场景
。这些Node
beans 被@Component
注解注解,并且还被init()
方法和@PostConstruct
注解所注解初始化,并在构建后设计每个节点。现在我意识到大多数这些 init()
方法都需要 JavaFX Application Thread
。我如何强制 Spring 在初始化这些节点时使用 JavaFX Application Thread
?我可能需要在这里重构我的代码。
示例代码
@Configuration
@EnableAsync
@EnableScheduling
@EnableCaching
// Component scanning for JavaFX Nodes
@ComponentScan("path.to.view.nodes")
public class MyConfiguration {
// bean definitiions here
}
public class MyApplication extends Application {
private ConfigurableApplicationContext configurableApplicationContext;
@Autowired
private RootPane rootPane;
@Override
public void init() throws Exception {
SpringApplication application;
application = new SpringApplication();
application.getSources().add(MyConfiguration.class);
application.setWebEnvironment(false);
application.setShowBanner(false);
application.setRegisterShutdownHook(true);
configurableApplicationContext = application.run();
ConfigurableListableBeanFactory beanFactory;
beanFactory = configurableApplicationContext.getBeanFactory();
beanFactory.registerSingleton(getClass().getSimpleName(), this);
beanFactory.autowireBean(this);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(rootPane));
primaryStage.centerOnScreen();
primaryStage.show();
}
@Override
public void stop() throws Exception {
configurableApplicationContext.close();
}
public static void main(String... args) {
Application.launch(MyApplication.class, args);
}
}
@Component
public class RootPane extends BorderPane {
@PostConstruct
public void init() {
setRight(new Button("Click me"));
}
}
最佳答案
Now I realize that most of these init() methods need JavaFX Application Thread.
这个假设是错误的,您可以在 JavaFX 应用程序线程之外初始化节点。
您不能在 JavaFX 应用程序线程之外修改 Activity 场景图中的节点。但是,一旦 Application start() 方法被调用,您只有一个 Activity 场景图,直到 init() 方法完成后才会发生。阅读 JavaFX Application javadoc 获取更多信息。
在 Application init() 方法中,没有 Activity 场景图,无论您在哪个线程上对节点做什么都没有关系,只要所有工作都不会违反任何 JavaFX 线程规则在将场景附加到 start() 方法中提供的舞台之前完成。
据我所知,此规则(对于 JavaFX 8)的唯一异常(exception)是 WebView ,必须仅从 FX 线程创建和访问。
所以,我不是在回答你原来的问题,但也许不需要回答。
关于java - 如何让 Spring 在初始化 Node bean 时使用 JavaFX Application Thread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33865390/