【问题标题】:Is it possible combine fx:include and afterburner是否可以结合 fx:include 和 afterburner
【发布时间】:2014-07-24 00:02:45
【问题描述】:

我目前使用 afterburner.fx 来定制基于 JavaFX 的应用程序的组件。 现在,我尝试在单独的 fxml 文件中移动组件,以便进行更舒适的维护。

要加载此类组件,我使用 fx:include 指令,该指令允许自动加载嵌套组件。

问题是自动加载我失去了从嵌套视图中获取演示者的可能性。

有没有办法结合自动加载,同时能够使用父根目录中的嵌套组件?

【问题讨论】:

    标签: javafx fxml


    【解决方案1】:

    这两个似乎可以很好地协同工作。

    Afterburner 通过在 FXML 加载器上设置一个控制器工厂来工作,该工厂负责实例化 Presenter 类并将值注入其中。

    <fx:include> 元素将在加载包含的 FXML 时传播控制器工厂,因此您还可以将值注入到包含的 FXML 中定义的控制器中。因为 afterburner 有效地使用单例范围进行注入,所以将使用注入字段的相同实例。这意味着您可以轻松地在不同的演示者类之间共享您的数据模型。

    如果您想访问与包含的 FXML 关联的演示者,只需使用 standard technique for "nested controllers"

    所以,例如:

    main.fxml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.control.TableView?>
    <?import javafx.scene.control.TableColumn?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.geometry.Insets?>
    
    <BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="application.MainPresenter">
        <center>
            <TableView fx:id="table">
                <columns>
                    <TableColumn text="First Name" prefWidth="150">
                    <cellValueFactory>
                        <PropertyValueFactory property="firstName" />
                        </cellValueFactory>
                    </TableColumn>
                    <TableColumn text="Last Name" prefWidth="150">
                    <cellValueFactory>
                        <PropertyValueFactory property="lastName" />
                        </cellValueFactory>
                    </TableColumn>
                    <TableColumn text="Email" prefWidth="200">
                    <cellValueFactory>
                        <PropertyValueFactory property="email" />
                        </cellValueFactory>
                    </TableColumn>
                </columns>
            </TableView>
        </center>
        <bottom>
            <fx:include source="Editor.fxml" fx:id="editor">
                <padding>
                    <Insets top="5" bottom="5" left="5" right="5"/>
                </padding>
            </fx:include>
        </bottom>
    </BorderPane>
    

    editor.fxml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Button?>
    
    <GridPane xmlns:fx="http://javafx.com/fxml" hgap="5" vgap="10" fx:controller="application.EditorPresenter">
        <Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="First Name:"/>
        <TextField fx:id="firstNameTextField" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
    
        <Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="Last Name"/>
        <TextField fx:id="lastNameTextField" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
    
        <Label GridPane.rowIndex="2" GridPane.columnIndex="0" text="Email"/>
        <TextField fx:id="emailTextField" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
    
        <HBox GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2">
            <Button fx:id="addEditButton" onAction="#addEdit" />
        </HBox>
    
    </GridPane>
    

    MainPresenter.java:

    package application;
    
    import javax.inject.Inject;
    
    import javafx.fxml.FXML;
    import javafx.scene.control.TableView;
    
    public class MainPresenter {
        @FXML
        private TableView<Person> table ;
    
        // This is the controller (presenter) for the included fxml
        // It is injected by the FXMLLoader; the rule is that "Controller" needs to be
        // appended to the fx:id attribute of the <fx:include> tag.
        // This is not used in this example but is here to demonstrate how to access it
        // if needed.
        @FXML
        private EditorPresenter editorController ;
    
        @Inject
        private DataModel dataModel ;
    
        public void initialize() {
            table.setItems(dataModel.getPeople());
    
            table.getSelectionModel().selectedItemProperty().addListener(
                    (obs, oldPerson, newPerson) -> dataModel.setCurrentPerson(newPerson));
    
            dataModel.currentPersonProperty().addListener((obs, oldPerson, newPerson) -> {
                if (newPerson == null) {
                    table.getSelectionModel().clearSelection();
                } else {
                    table.getSelectionModel().select(newPerson);
                }
            });
    
            dataModel.getPeople().addAll(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com")
            );
        }
    }
    

    EditorPresenter.java:

    package application;
    
    import javafx.beans.binding.Bindings;
    import javafx.fxml.FXML;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextField;
    
    import javax.inject.Inject;
    
    public class EditorPresenter {
        @FXML
        private TextField firstNameTextField ;
        @FXML
        private TextField lastNameTextField ;
        @FXML
        private TextField emailTextField ;
        @FXML
        private Button addEditButton ;
    
        @Inject
        private DataModel dataModel ;
    
        public void initialize() {
            addEditButton.textProperty().bind(
                Bindings.when(Bindings.isNull(dataModel.currentPersonProperty()))
                    .then("Add")
                    .otherwise("Update")
            );
    
            dataModel.currentPersonProperty().addListener((obs, oldPerson, newPerson) -> {
                if (newPerson == null) {
                    firstNameTextField.setText("");
                    lastNameTextField.setText("");
                    emailTextField.setText("");
                } else {
                    firstNameTextField.setText(newPerson.getFirstName());
                    lastNameTextField.setText(newPerson.getLastName());
                    emailTextField.setText(newPerson.getEmail());
                }
            });
        }
    
        @FXML
        private void addEdit() {
            Person person = dataModel.getCurrentPerson();
            String firstName = firstNameTextField.getText();
            String lastName = lastNameTextField.getText();
            String email = emailTextField.getText();
            if (person == null) {
                dataModel.getPeople().add(new Person(firstName, lastName, email));
            } else {
                person.setFirstName(firstName);
                person.setLastName(lastName);
                person.setEmail(email);
            }
        }
    }
    

    MainView.java:

    package application;
    
    import com.airhacks.afterburner.views.FXMLView;
    
    public class MainView extends FXMLView {
    
    }
    

    Main.java(应用程序类):

    package application;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    import com.airhacks.afterburner.injection.Injector;
    
    
    public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
            MainView mainView = new MainView();
            Scene scene = new Scene(mainView.getView(), 600, 400);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        @Override
        public void stop() throws Exception {
            Injector.forgetAll();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    DataModel.java:

    package application;
    
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    
    public class DataModel {
        private final ObservableList<Person> people = FXCollections.observableArrayList();
        private final ObjectProperty<Person> currentPerson = new SimpleObjectProperty<>(this, "currentPerson");
    
        public ObservableList<Person> getPeople() {
            return people ;
        }
    
        public final Person getCurrentPerson() {
            return currentPerson.get();
        }
    
        public final void setCurrentPerson(Person person) {
            this.currentPerson.set(person);
        }
    
        public ObjectProperty<Person> currentPersonProperty() {
            return currentPerson ;
        }
    }
    

    还有通常的 Person.java 示例:

    package application;
    
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    
    public class Person {
        private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
        public final String getFirstName() {
            return firstName.get();
        }
        public final void setFirstName(String firstName) {
            this.firstName.set(firstName);
        }
        public StringProperty firstNameProperty() {
            return firstName ;
        }
    
        private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
        public final String getLastName() {
            return lastName.get();
        }
        public final void setLastName(String lastName) {
            this.lastName.set(lastName);
        }
        public StringProperty lastNameProperty() {
            return lastName ;
        }
    
        private final StringProperty email = new SimpleStringProperty(this, "email");
        public final String getEmail() {
            return email.get();
        }
        public final void setEmail(String email) {
            this.email.set(email);
        }
        public StringProperty emailProperty() {
            return email ;
        }
    
        public Person(String firstName, String lastName, String email) {
            setFirstName(firstName);
            setLastName(lastName);
            setEmail(email);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多