Użycie JavaFXBuilderFactory
Domyślna JavaFXBuilderFactory
Jeżeli klasy, które tworzymy, spełniają wymagania JavaBean – setters i getters oraz obecność konstruktora bezparametrowego, to z obiektami tych klas nie mamy żadnych problemów.
Klasa User.java
package codes; public class User{ private String nick; private Integer pesel; public User(String nick, Integer pesel){ this.nick = nick; this.pesel = pesel; } //domyślny konstruktor public User(){ this(null, null); } public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } public Integer getPesel() { return pesel; } public void setPesel(Integer pesel) { this.pesel = pesel; } @Override public String toString() { return "nick=" + nick + ", pesel=" + pesel; } }
Powyższa klasa ma settersy i gettersy oraz bezparametrowy konstruktor. Obiekty tej klasy mogą być użyte w plikach FXML.
listing10_creating_user.fxml
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.ListView?> <?import codes.User?> <?import javafx.collections.FXCollections?> <VBox xmlns:fx="http://javafx.com/fxml"> <Label fx:id="lab1" text="Lista użytkowników." /> <ListView> <items> <FXCollections fx:factory="observableArrayList"> <User nick="Jacek" pesel="52" /> <User nick="Ula" pesel="83" /> <User nick="Mirka" pesel="53" /> </FXCollections> </items> </ListView> </VBox>
Utworzyliśmy obiekty klasy User
i dodaliśmy je do kolekcji.
Listing10_creating_user.java
Klasa uruchamiająca.
package codes; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.net.URL; public class Listing10_creating_user extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { try { URL fxmlUrl = this.getClass().getClassLoader() .getResource("resources/listing10_creating_user.fxml"); VBox root = fxmlUrl != null ? FXMLLoader.load(fxmlUrl) : new VBox(); Scene scene = new Scene(root, 150, 150); stage.setScene(scene); stage.show(); } catch (Exception e) { e.printStackTrace(); } } }
Po uruchomieniu zobaczymy:
Implementacja BuilderFactory
Gdy nasza klasa nie spełnia wymogów JavaBean, a w szczególności nie ma domyślnego konstruktora albo jest typową klasą immutable, domyślna JavaFXBuiderFactory
nie poradzi sobie z utworzeniem obiektu. Przykładem takiej klasy jest User2
.
Klasa User2.java
package codes; public class User2 { private String nick; private Integer pesel; public User2(String nick, Integer pesel){ this.nick = nick; this.pesel = pesel; } public String getNick() { return nick; } public Integer getPesel() { return pesel; } @Override public String toString() { return "nick=" + nick + ", pesel=" + pesel; } }
Teraz musimy implementować interfejs Builder
aby pokazać jak zbudować obiekt klasy User2
oraz implementować interfejs BuilderFactory
, aby wykorzystać budowniczego do budowy obiektów.
Klasa User2BuilderFatory.java
package codes; import javafx.fxml.JavaFXBuilderFactory; import javafx.util.Builder; import javafx.util.BuilderFactory; public class User2BuilderFactory implements BuilderFactory { private final JavaFXBuilderFactory defaultBuilderFactory = new JavaFXBuilderFactory(); @Override public Builder<?> getBuilder(Class<?> type) { return (type==User2.class ? new User2Builder() : defaultBuilderFactory.getBuilder(type)); } public static class User2Builder implements Builder<User2> { private String nick; private Integer pesel; public void setNick(String nick) { this.nick = nick; } public void setPesel(Integer pesel) { this.pesel = pesel; } public String getNick() { return nick; } public Integer getPesel() { return pesel; } @Override public String toString() { return "nick=" + nick + ", pesel=" + pesel; } @Override public User2 build() { return new User2(nick, pesel); } } }
listing10_creating_user2.fxml
Tworzymy plik FXML używający obiektu User2
.
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.ListView?> <?import codes.User2?> <?import javafx.collections.FXCollections?> <VBox xmlns:fx="http://javafx.com/fxml"> <Label fx:id="lab1" text="Lista użytkowników." /> <ListView> <items> <FXCollections fx:factory="observableArrayList"> <User2 nick="Jacek" pesel="52" /> <User2 nick="Ula" pesel="83" /> <User2 nick="Mirka" pesel="53" /> </FXCollections> </items> </ListView> </VBox>
Chociaż analizator IntelliJ IDEA podkreśli atrybuty na czerwono sygnalizując, że coś jest nieprawidłowo, to wszystko jest prawidłowo i kod uruchomi się bez problemów.
Listing10_creating_user2.java
package codes; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.net.URL; public class Listing10_creating_user2 extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { try { URL fxmlUrl = this.getClass().getClassLoader() .getResource("resources/listing10_creating_user2.fxml"); VBox root = fxmlUrl != null ? FXMLLoader.load(fxmlUrl,null, new User2BuilderFactory()) : new VBox(); Scene scene = new Scene(root, 150, 150); stage.setScene(scene); stage.show(); } catch (Exception e) { e.printStackTrace(); } } }
Po uruchomieniu zobaczymy (tak jak poprzednio):