We have started our JavaFX application using Spring Boot, but there was no gain from it for that simple application. To make things more interesting, we will add a combobox that allows to select a country. For this, we adjust main.fxml:
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.deblauwe.airqualityfx.MainController"
>
<HBox>
<Label text="Country:"/>
<ComboBox fx:id="countriesComboBox"/>
</HBox>
</AnchorPane>
Since we now want to have some functionality in our UI, we link the FXML file to a controller called MainController
:
@Component
public class MainController {
@FXML
public ComboBox<Country> countriesComboBox;
@Autowired
private CountryService countryService;
@FXML
public void initialize() {
countriesComboBox.setConverter(new CountryNameStringConverter());
countriesComboBox.setItems(FXCollections.observableArrayList(countryService.getAllCountries()));
}
private static class CountryNameStringConverter extends StringConverter<Country> {
@Override
public String toString(Country object) {
return object.getName();
}
@Override
public Country fromString(String string) {
return null;
}
}
}
Not that much code, but quite some things are going on:
-
The class is annotated with @Component
so that Spring will create a singleton out of it using component scanning
-
We can access our combo box through the countriesComboBox
field (annotated with @FXML
). Note that the name of the field should match with the fx:id
given in the FXML file.
-
We @Autowire the CountryService, which is an interface for retrieving countries. Note how this is exactly as you autowire other dependencies in a normal Spring application.
To make this fully work, we need our Country model class (using Lombok):
@AllArgsConstructor
@Getter
public class Country {
private String code;
private String name;
}
The CountryService interface:
public interface CountryService {
Set<Country> getAllCountries();
}
@Component
public class HardcodedListCountryService implements CountryService {
@Override
public Set<Country> getAllCountries() {
Set<Country> result = new HashSet<>();
result.add(new Country("AU", "Australia"));
result.add(new Country("BR", "Brazil"));
result.add(new Country("BE", "Belgium"));
return result;
}
}
Since this is our only instance of CountryService
, we can just have it pick up by component scanning.
The resulting UI looks like this: