spring启动javafx

s71maibg  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(351)

我正在使用springboot和javafx开发一个java桌面应用程序。它是一个crud应用程序,所以我正在使用mysql数据库,我希望控制器同时是spring引导和javafx控制器,为此我使用了 setControllerFactory() .
这是我的申请表
应用程序:

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {

        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

测验应用:

package com.gi.quizui;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;

public class QuizApplication extends Application {

    private ConfigurableApplicationContext applicationContext;

    @Override
    public void init() {
        applicationContext = new SpringApplicationBuilder(com.gi.quizui.Application.class).run();
    }

    @Override
    public void start(Stage stage) {
        applicationContext.publishEvent(new StageReadyEvent(stage));
    }

    @Override
    public void stop() {
        applicationContext.close();
        Platform.exit();
    }

    class StageReadyEvent extends ApplicationEvent {
        public StageReadyEvent(Stage stage) {
            super(stage);
        }

        public ConfigurableApplicationContext getAppContext() {

            return applicationContext;
        }

        public Stage getStage() {

            return ((Stage) getSource());
        }
    }
}

和阶段初始值设定项:

package com.gi.quizui;
import com.gi.quizui.QuizApplication.StageReadyEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class StageInitializer implements ApplicationListener<StageReadyEvent> {

    @Value("classpath:fxml/quiz.fxml")
    private Resource quizResource;

    public StageInitializer(@Value("${spring.application.ui.title}") String applicationTitle) {
        this.applicationTitle = applicationTitle;
    }

    private String applicationTitle;

    @Override
    public void onApplicationEvent(StageReadyEvent event) {
        Stage stage = event.getStage();
        ConfigurableApplicationContext springContext = event.getAppContext();
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(quizResource.getURL());
            fxmlLoader.setControllerFactory(springContext::getBean);
            Parent parent = fxmlLoader.load();
            stage.setScene(new Scene(parent, 800, 600));
            stage.setTitle(applicationTitle);
            stage.show();
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
}

我不断得到这个错误:(编辑)

Exception in Application start method
2021-01-16 15:37:15.286  INFO 8652 --- [lication Thread] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-01-16 15:37:15.320  INFO 8652 --- [lication Thread] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2021-01-16 15:37:15.343  INFO 8652 --- [lication Thread] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: 
/C:/Users/FacilOrdi/IdeaProjects/quizManagement/target/classes/fxml/quiz.fxml:7

    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:40)
    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:16)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:426)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
    at com.gi.quizui.QuizApplication.start(QuizApplication.java:20)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Caused by: javafx.fxml.LoadException: 
/C:/Users/FacilOrdi/IdeaProjects/quizManagement/target/classes/fxml/quiz.fxml:7

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:35)
    ... 16 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.gi.controllers.QuizController' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1177)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:938)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:980)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:227)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:752)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
    ... 19 more

控制器:

package com.gi.controllers;

import org.springframework.stereotype.Component;

@Component
public class QuizController {

}

我不明白为什么它不起作用,我发现了相关的问题,但我不明白它是如何工作的。如果有其他的替代方法,这将是非常有帮助的。

tnkciper

tnkciper1#

为了了解具有注解的类,例如 @Component 等等,spring引导需要在启动时扫描部分类路径。默认情况下,它将扫描包含您传递给的类的包 SpringApplicationBuilder ( Application 在你的情况下)和所有的子 Package 。
所以按照你设置的方式,它会扫描 com.gi.quizui 以及所有的分装。
你的 QuizController 类不在的子包中 com.gi.quizui ; 它在里面 com.gi.controllers . 因此它不会被找到。
spring引导文档中的建议实际上是 Application 在包含类或资源的最高级别包中初始化 com.gi 对你来说。如果您将该类移到该包中,它应该会修复该问题。
或者,可以使用 @ComponentScan 注解:

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan ;

@SpringBootApplication
@ComponentScan(basePackages={"com.gi.quizui","com.gi.controllers"})
public class Application {

    public static void main(String[] args) {

        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

类型安全的替代方法是使用 basePackageClasses 参数而不是 basePackages :

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan ;

import com.gi.controllers.QuizController ;

@SpringBootApplication
@ComponentScan(basePackageClasses={Application.class, QuizController.class})
public class Application {

    public static void main(String[] args) {

        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

相关问题