Skip to content
This repository has been archived by the owner on Feb 15, 2021. It is now read-only.

Latest commit

 

History

History

easyfxml

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

EasyFXML

A tiny opinionated framework for integrating JavaFX with Spring Boot seamlessly

Maven Central

Required dependencies

EasyFXML is based on, and requires the following runtime setup:

It might still work on different environment set-ups, but there is no official support for it.

Especially considering that JavaFX applications are expected to be bundled with their own JDK and dependencies, this should not be an issue.

Features

  • Full support of both classpath and module path
  • Declarative and type-safe definition and usage of visual components
  • Easier asynchronous management of components' lifecycle
  • Built with first-class support for FXML files
  • No specific configuration needed

Philosophy

The idea of EasyFXML is to adopt the industry-standard MVC model for UI components and apply it to JavaFX. This allows easier separation of concerns and lifecycle management of these components inside applications.

There are thus three core elements that go into a UI component (an FxmlComponent hereafter):

  • For the Model, it is simple as your standard classes are just provided and usable via Java itself, and services and other more complex things can be injected via Spring's autowiring system.
  • The View, a standard .fxml file in the form of an FxmlFile
  • And Controller, that is, a Spring Bean implementing FxmlController

Getting started

This section is mostly an (extremely) simple example, available in the samples module, under Hello World if you want to check it out for yourself. Other more complex examples are available there.

So, let's see how building a very minimal greeter window, like follows, would work:

Hello World Sample Screenshot

For this you will need:

  • The component's FxmlComponent
  • An entrypoint for the UI
  • A main class
Component (FxmlComponent)
@Component
public class HelloComponent implements FxmlComponent {
    
    @Override 
    public FxmlFile getFile() {
        return () -> "HelloView.fxml"; 
    }

    @Override
    public Class<? extends FxmlController> getControllerClass() {
        return HelloController.class; 
    }

}
Controller (FxmlController)
@Component
public class HelloController implements FxmlController {

    @FXML 
    private TextField userNameTextField;
    
    @FXML 
    private Button helloButton;
    
    @FXML 
    private HBox greetingBox;
    
    @FXML 
    private Label greetingName;

    @Override
    public void initialize() { // called once loading is fully done
        greetingBox.setVisible(false);
        greetingName.textProperty().bind(userNameTextField.textProperty());

        setOnClick(helloButton, () -> greetingBox.setVisible(true));
    }

}

Note that if you can have multiple instances of a given component (a notification panel, or a individual cell in a list/table for example), you need to make sure that the controller class is not a singleton with @Scope(scopeName = ConfigurableBeanFactory.PROTOTYPE)

Entrypoint of the UI (FxUiManager)
(called by EasyFXML once JavaFX and Spring are both ready to use)
@Component
public class HelloWorldUiManager extends FxUiManager {

    private final HelloComponent helloComponent;

    @Autowired
    public HelloWorldUiManager(HelloComponent helloComponent) {
        this.helloComponent = helloComponent;
    }

    @Override
    protected String title() {
        return "Hello, World!";
    }

    @Override
    protected FxmlComponent mainComponent() { // defines what component must be loaded first into the main stage
        return helloComponent;
    }

}
Main class (FxApplication)
@SpringBootApplication // EasyFXML wires itself in the context via Spring Boot's autoconfiguration
public class HelloWorld extends FxApplication { // FxApplication is essential here to set-up JavaFX
    public static void main(String[] args) {    // and Spring cohabitation
        launch(args);
    }
}

And that's about all we need here.

Feel free to look into the samples if you want to see more advanced examples!