动态加载FXML组件

时间:2019-08-28 20:35:05

标签: java javafx fxml

我创建了一个包含2个VBOX场景的舞台,每个VBOX应该包含4个将从FXML文件动态加载的节点。

我使用以下函数动态加载节点

@FXML VBox firstColumnBox; // will contain four loaded nodes
@FXML VBox secondColumnBox; // will also contain four loaded , so the scene will have a two columns screens with four nodes at right and four nodes at left

public void showPreviewOfCards(int size) {
    for (int i = 0; i < size; i++) {
        try {
            FXMLLoader cardLoader = new FXMLLoader(getClass().getResource("CardEleveVerso.fxml"));
            AnchorPane cardRoot = cardLoader.load();

            if ((i == 0) || (i % 2 == 0)) {
                firstColumnBox.getChildren().add(cardRoot);
            } else {
                secondColumnBox.getChildren().add(cardRoot);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

使用上述功能,我得到了预期的结果,但是问题是:“性能”。应用程序变得太慢,并且在netbeans中使用探查器时,它几乎占据了堆大小的全部量。

然后我对此进行了一些更改

@FXML VBox firstColumnBox;
@FXML VBox secondColumnBox;

public void showPreviewOfCards() {
    int size = listofStudentToPrint.size();

    try {
        FXMLLoader cardLoader = new FXMLLoader(getClass().getResource("CardeEleve.fxml"));
        AnchorPane card = (AnchorPane) cardLoader.load();

        CardeEleveController controller = (CardeEleveController) cardLoader.getController();

        for (int i = 0; i < size; i++) {
            StudentModel student = listofStudentToPrint.get(i);
            student.setCardNo(String.valueOf(totalNoOfCard++));

            controller.setValues(student);

            if ((i == 0) || (i % 2 == 0)) {
                firstColumnBox.getChildren().add(card);
            } else {
                secondColumnBox.getChildren().add(card);
            }
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

这一次,我将负责加载fxml的代码行放在“ for循环”之外,以便在循环内部,我将仅通过使用节点的fxml控制器设置新值来重用已经加载的节点。

这是问题开始的地方,无论我添加了多少节点,在我的两栏中我都只会看到一个已加载的节点。

这是舞台场景的FXML文件

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.URL?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.TilePane?>
<?import javafx.scene.layout.VBox?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="612.0"
            styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/11.0.1"
            xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="monanocard.PrintCardRectoController">
  <stylesheets>
    <URL value="@printcardrecto.css"/>
  </stylesheets>
  <children>
    <BorderPane prefHeight="400.0" prefWidth="635.0"
                AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
                AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <bottom>
        <HBox alignment="CENTER_RIGHT" prefHeight="37.0"
              prefWidth="648.0" BorderPane.alignment="CENTER_RIGHT">
          <children>
            <Button fx:id="btnPrint" mnemonicParsing="false"
                    prefHeight="32.0" prefWidth="121.0" style="-fx-background-color: 
green;" text="IMPRIMER" textFill="WHITE">
              <graphic>
                <ImageView fitHeight="22.0" fitWidth="31.0"
                           pickOnBounds="true" preserveRatio="true">
                  <image>
                    <Image url="@../icons/ic_print.png"/>
                  </image>
                </ImageView>
              </graphic>
            </Button>
          </children>
          <BorderPane.margin>
            <Insets bottom="5.0" right="10.0" top="5.0"/>
          </BorderPane.margin>
        </HBox>
      </bottom>
      <center>
        <AnchorPane BorderPane.alignment="CENTER">
          <BorderPane.margin>
            <Insets/>
          </BorderPane.margin>
          <children>
            <ScrollPane fx:id="scrollPane" fitToHeight="true"
                        fitToWidth="true">
              <content>
                <TilePane fx:id="twoColumnsContainer"
                          alignment="TOP_CENTER" hgap="1.0" maxWidth="-Infinity" minHeight="- 
Infinity" minWidth="-Infinity" prefColumns="2" prefRows="8"
                          prefWidth="655.0" tileAlignment="TOP_CENTER" vgap="1.0">
                  <children>
                    <VBox fx:id="secondColumnBox"
                          alignment="TOP_CENTER" maxWidth="-Infinity" prefHeight="220.0"
                          prefWidth="315.0"/>
                    <VBox fx:id="firstColumnBox"
                          alignment="TOP_CENTER" maxWidth="-Infinity" prefHeight="220.0"
                          prefWidth="315.0"/>
                  </children>
                </TilePane>
              </content>
            </ScrollPane>
          </children>
        </AnchorPane>
      </center>
    </BorderPane>
  </children>
</AnchorPane>

这里是FXML文件,其中包含动态加载的节点的设计

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.URL?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
            prefHeight="176.0" prefWidth="310.0" style="-fx-background-color: white;" styleClass="card"
            xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="monanocard.CardeEleveController">
  <stylesheets>
    <URL value="@cardeeleve.css"/>
  </stylesheets>
  <children>
    <BorderPane layoutX="3.0" layoutY="3.0" prefHeight="156.0" prefWidth="307.0" AnchorPane.bottomAnchor="2.0"
                AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0">
      <center>
        <AnchorPane maxHeight="-Infinity" prefHeight="105.0" prefWidth="259.0" style="-fx-background-color: white;"
                    BorderPane.alignment="CENTER">
          <children>
            <ImageView fx:id="imageProfile" fitHeight="84.0" fitWidth="87.0" layoutX="6.0" layoutY="8.0"
                       pickOnBounds="true">
              <image>
                <Image url="@../icons/ben.jpg"/>
              </image>
            </ImageView>
            <VBox alignment="TOP_CENTER" layoutX="100.0" layoutY="3.0" prefHeight="100.0" prefWidth="188.0"
                  spacing="2.0">
              <children>
                <HBox prefHeight="11.0" prefWidth="202.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="72.0" text="Nom">
                      <font>
                        <Font name="Roboto Bold" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblNom" prefHeight="4.0" prefWidth="97.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="0.0" prefWidth="212.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="87.0" text="Postnom">
                      <font>
                        <Font name="Roboto Bold" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblPostnom" prefHeight="2.0" prefWidth="129.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="0.0" prefWidth="212.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="86.0" text="Prenom">
                      <font>
                        <Font name="Roboto Black" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblPrenom" prefHeight="0.0" prefWidth="129.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="0.0" prefWidth="212.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="84.0" text="Matricule">
                      <font>
                        <Font name="Roboto Bold" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblMatricule" prefHeight="0.0" prefWidth="129.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="6.0" prefWidth="212.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="87.0" text="Classe">
                      <font>
                        <Font name="Roboto Black" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblClasse" prefHeight="9.0" prefWidth="129.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="11.0" prefWidth="211.0">
                  <children>
                    <Label prefHeight="11.0" prefWidth="84.0" text="Sexe">
                      <font>
                        <Font name="Roboto Bold" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblSexe" prefHeight="0.0" prefWidth="129.0">
                      <font>
                        <Font name="System Bold" size="7.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
                <HBox prefHeight="21.0" prefWidth="211.0">
                  <children>
                    <Label alignment="TOP_LEFT" prefHeight="16.0" prefWidth="70.0" text="Adresse">
                      <font>
                        <Font name="Roboto Black" size="7.0"/>
                      </font>
                    </Label>
                    <Label fx:id="lblAddresse" alignment="TOP_LEFT" prefHeight="27.0" prefWidth="101.0" wrapText="true">
                      <font>
                        <Font name="System Italic" size="5.0"/>
                      </font>
                    </Label>
                  </children>
                </HBox>
              </children>
              <padding>
                <Insets bottom="2.0" left="2.0" right="2.0" top="2.0"/>
              </padding>
            </VBox>
          </children>
        </AnchorPane>
      </center>
      <bottom>
        <VBox alignment="CENTER" prefHeight="18.0" prefWidth="295.0" BorderPane.alignment="CENTER">
          <BorderPane.margin>
            <Insets bottom="2.0" left="2.0" right="2.0" top="2.0"/>
          </BorderPane.margin>
          <children>
            <Label fx:id="lblValidity" alignment="CENTER" layoutX="100.0" prefHeight="23.0" prefWidth="295.0">
              <font>
                <Font name="Felix Titling" size="9.0"/>
              </font>
              <padding>
                <Insets bottom="2.0"/>
              </padding>
            </Label>
          </children>
        </VBox>
      </bottom>
      <top>
        <HBox maxWidth="-Infinity" prefHeight="43.0" prefWidth="302.0" style="-fx-padding: 5;" styleClass="top"
              stylesheets="@cardeeleve.css" BorderPane.alignment="CENTER">
          <children>
            <ImageView fitHeight="29.0" fitWidth="36.0" pickOnBounds="true">
              <image>
                <Image url="@../icons/monano_logo.jpg"/>
              </image>
            </ImageView>
            <VBox prefHeight="29.0" prefWidth="212.0">
              <children>
                <Label alignment="CENTER" prefHeight="11.0" prefWidth="219.0" text="CS MONANO 1">
                  <font>
                    <Font name="Arial Black" size="10.0"/>
                  </font>
                </Label>
                <Label fx:id="lblCardNo" alignment="CENTER" prefHeight="11.0" prefWidth="220.0">
                  <font>
                    <Font name="Arial" size="8.0"/>
                  </font>
                </Label>
              </children>
            </VBox>
            <ImageView fitHeight="28.0" fitWidth="34.0" pickOnBounds="true">
              <image>
                <Image url="@../icons/rdc_flag.png"/>
              </image>
            </ImageView>
          </children>
        </HBox>
      </top>
    </BorderPane>
  </children>
</AnchorPane>

以及加载的Node的控制器

public class CardeEleveController implements Initializable {
    @FXML Label lblDevise;
    @FXML Label lblValidity;

    @FXML Label lblNom;
    @FXML Label lblPostnom;
    @FXML Label lblPrenom;
    @FXML Label lblClasse;
    @FXML Label lblSexe;
    @FXML Label lblAddresse;

    @FXML Label lblCardNo;
    @FXML Label lblMatricule;

    @FXML ImageView imageProfile;

    String serverAddress = FXMLDocumentController.configuration.get(ConfigurationHandler.OPTION_SERVER_ADDRESSE);
    String serverPort = FXMLDocumentController.configuration.get(ConfigurationHandler.OPTION_SERVER_PORT);
    String site = FXMLDocumentController.configuration.get(ConfigurationHandler.OPTION_SERVER_SITE);
    String photoSite = FXMLDocumentController.configuration.get(ConfigurationHandler.OPTION_PHOTO_SITE);
    String validite = FXMLDocumentController.configuration.get(ConfigurationHandler.OPTION_VALIDITY);

    private static boolean IS_OPERATION_MODE = false;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        String currentMode = FXMLDocumentController.CURRENT_MODE;
        if (currentMode.equalsIgnoreCase("operation")) {
            IS_OPERATION_MODE = true;
        }
    }

    public void setValues(StudentModel student) {
        if (student != null) {
            System.out.println("Controller setting values...");
            System.out.println();
            System.out.println("------------------------------");
            System.out.println("NAME: " + student.getNom() + " " + student.getPostnom() + " " + student.getPrenom());
            System.out.println("------------------------------");

            String cardNoTxt = "Carte d'Eleve No " + generateCardNoBasedNoOfDigit(Integer.parseInt(student.getCardNo()));
            lblCardNo.setText(cardNoTxt);

            lblNom.setText(student.getNom());
            lblPostnom.setText(student.getPostnom());
            lblPrenom.setText(student.getPrenom());
            lblClasse.setText(student.getClasse());
            lblMatricule.setText(student.getMatricule());
            lblSexe.setText(student.getSexe());

            AddressModel address = student.getAddress();
            String addresseString = address.getAv() + " No." + address.getNo() + "Q. " + address.getQuartier() + "\n" + "C." + address.getCommune();
            lblAddresse.setText(addresseString);

            String imagePath = student.getPhotoUrl();
            if (IS_OPERATION_MODE) {
                //construct photo url
                String photoUrl = "http://" + serverAddress + ":" + serverPort + "/" + photoSite + "/" + Utility.STUDENT_IMAGE_DIRECTORY + "/" + imagePath;
                Image image = new Image(photoUrl, 100, 100, false, false);
                imageProfile.setImage(image);
            } else {
                // to use during formation Mode
                // load the image saved locally
                if (imagePath != null && !imagePath.isEmpty()) {
                    Image image = new Image("file:" + student.getPhotoUrl(), 100, 100, false, false);
                    imageProfile.setImage(image);
                }
            }

            if (validite != null) {
                // get the two values separated by :
                Scanner scanner = new Scanner(validite);
                scanner.useDelimiter(":");

                String fromDate = scanner.next();
                String toDate = scanner.next();

                String valideString = "Valide Du " + fromDate + " Au " + toDate;
                lblValidity.setText(valideString);
            }
        }
    }
}

总而言之,我希望能够动态加载节点而不会出现性能问题。

0 个答案:

没有答案