How to integrate Javafx with Springboot

Asked

Viewed 90 times

1

I’m on the following case:

I have an application developed with Spring Boot, and I am developing the front end with Javafx. It is a local application, not a web one. I can run the project, Spring runs, and the window prepared with Javafx appears. However, when trying to manipulate data, bringing them to be displayed in the window with Javafx, I get an error:

Cannot invoke "services.ClienteService.findAll()" because "this.cs" is null at com.fgwr.jpcorretora.FrontApp.<init>(FrontApp.java:39)

Without Javafx the application runs normally. I am running Javafx + Spring Boot as follows:

Spring Boot class:

@SpringBootApplication
public class JpcorretoraApplication implements CommandLineRunner {

@Autowired
ClienteService cs;

public JpcorretoraApplication() {
        List <Cliente> allcli = cs.findAll();
        for (Cliente cliente : allcli) {
            clienteData.add(cliente);
            System.out.println(cliente.getNome());
        }
    }
    
    public static void main(String[] args) {
        Application.launch(FrontApp.class, args);
    }

    @Override
    public void run(String... args) throws Exception {

Javafx class:

public class FrontApp extends Application {
    
    @Autowired
    ClienteService cs;
    
    private Stage primaryStage;
    private BorderPane rootLayout;
    private ConfigurableApplicationContext applicationContext;

    private ObservableList<Cliente> clienteData = FXCollections.observableArrayList();

    public FrontApp() {
        clienteData = (ObservableList<Cliente>) cs.findAll();
        for (Cliente cliente : clienteData) {
            System.out.println(clienteData);
        }
    }

    public ObservableList<Cliente> getClienteData() {
        return clienteData;
    }

    @Override
    public void init() {
        String[] args = getParameters().getRaw().toArray(new String[0]);
        this.applicationContext = new SpringApplicationBuilder().sources(JpcorretoraApplication.class).run(args);
    }

In any of the classes I try to perform my service cs, get the bug. From what I’ve worked on spring boot, I want it to be an injection failure, in which the service cs is not being injected when I try to work outside the context of Spring Boot, that is, inside javafx. I tried several solutions, but none satisfied my need.

All classes have their respective annotations correct (e.g.: @Service).

The idea is that I can recover the data from my database that is being operated by Jparepository in spring boot and move on to the javafx show on the screen. Anyone can help?

  • Ñ know how it works but try reading this: https://stackoverflow.com/q/33612130/2241463 It seems that the annotation @SpringBootApplication although it seems that it would only be for the main application may serve to be used in various applications within the main one, so it could give to include it in its class FrontApp. Another idea is to solve this via configuration file, Springboot should not know that in this class FrontApp has something to be injected, have to warn him in some way. This should not be a problem for the JpcorretoraApplication on account of that annotation.

  • I’ve tried these solutions. None of them worked. It’s like Springboot has isolated my class from Javafx so it doesn’t have access to the environment. I can’t run any service within Javafx classes.

1 answer

0


After studying a little, I got some solutions to the problem. The simplest and most functional for the scenario was:

1 - Register Applicationcontext in Javafx main class init method:

Myaccountmaindojavafx.java

    @Override
    public void init() {
        ApplicationContextInitializer<GenericApplicationContext> initializer = ac -> {

            ac.registerBean(Application.class, () -> MainJavaFX.this);
            ac.registerBean(Parameters.class, this::getParameters);
            ac.registerBean(HostServices.class, this::getHostServices);

        };
        this.applicationContext = new SpringApplicationBuilder().sources(MinhaClasseAplicaçãoSpring.class)
                .initializers(initializer).run(getParameters().getRaw().toArray(new String[0]));
    }

2 - Create a context injection class in the root package:

Springcontext.java.

public class SpringContext implements ApplicationContextAware {

    @Autowired
    static
    ApplicationContext context;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
        
    }
    
    public static ApplicationContext getAppContext() {
        return context;
     }

}

3 - Calling the Springcontext class IN THE METHOD THAT I WISH to perform the instantiation of my service within Springboot.

Editclientecontroller.java

    private void handleOk() {
        if (isInputValid()) {
            
            // Aqui iniciamos o contexto do SpringBoot chamando a class ApplicationContext atribuindo ela a variável context:
            ApplicationContext context = SpringContext.getAppContext();
            
            // Aqui chamamos o serviço do SpringBoot desejado, fazendo com que ele receba a bean clienteRepository vinda do ambiente do SpringBoot: 
            ClienteRepository repo = (ClienteRepository)context.getBean("clienteRepository");
            
            cliente.setNome(nomeField.getText());
            cliente.setEmail(emailField.getText());
            cliente.setDataNascimento(Date.from(dataNascimentoField.getValue().atStartOfDay(ZoneId.systemDefault()).toInstant()));
            cliente.setCpfOuCnpj(cpfField.getText());
            cliente.setRg(rgField.getText());
            cliente.setEstadoCivil(estadoCivilBox.getValue());
            
            // Aqui, executamos o serviço chamado pela nossa implementação do ApplicationContext:
            repo.save(cliente);
            okClicked = true;
            dialogStage.close();
        }
    }

I hope to help other colleagues who are also having this difficulty.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.