JavaFX FXML: как создавать новые экземпляры самодельного fxml для VBox

Я создал панель, похожую на карту, чтобы я мог добавлять к ней данные и создавать страницу со многими картами в соответствии с данными (очень похоже на макет карты в мобильных приложениях), однако я не знаю, как добавить новые экземпляры этого в VBox . Я устал с петлей и без нее и все еще не работал. Он продолжает давать следующую ошибку:

javafx.fxml.LoadException: 
/C:///////bin/application/HotelReservation.fxml

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at application.Main.start(Main.java:18)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Children: child node is null: parent = VBox[id=vboxData]
at javafx.scene.Parent$2.onProposedChange(Parent.java:435)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at application.HotelReservationController.initialize(HotelReservationController.java:45)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 17 more

Вот файл FXML для такой карты, как Pane:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>

<AnchorPane fx:id = "cardAnchor" xmlns = "http://javafx.com/javafx/11.0.1" xmlns:fx = "http://javafx.com/fxml/1">
   <children>
      <HBox fx:id = "cardHBox" prefHeight = "152.0" prefWidth = "584.0">
         <children>
            <ImageView fx:id = "cardPhoto" fitHeight = "150.0" fitWidth = "200.0" pickOnBounds = "true" preserveRatio = "true" />
            <VBox prefHeight = "200.0" prefWidth = "100.0">
               <children>
                  <Text fx:id = "cardTitle" strokeType = "OUTSIDE" strokeWidth = "0.0" text = "Ttile:" wrappingWidth = "385.9830722808838">
                     <font>
                        <Font name = "System Bold" size = "31.0" />
                     </font>
                  </Text>
                  <HBox prefHeight = "18.0" prefWidth = "386.0">
                     <children>
                        <Text fx:id = "cardLocation" strokeType = "OUTSIDE" strokeWidth = "0.0" text = "Location:" wrappingWidth = "211.9830722808838">
                           <font>
                              <Font name = "System Bold" size = "15.0" />
                           </font>
                        </Text>
                        <Text fx:id = "cardRating" strokeType = "OUTSIDE" strokeWidth = "0.0" text = "Rating:" wrappingWidth = "172.9830722808838">
                           <font>
                              <Font name = "System Bold" size = "15.0" />
                           </font>
                        </Text>
                     </children>
                  </HBox>
                  <HBox prefHeight = "100.0" prefWidth = "200.0">
                     <children>
                        <Text fx:id = "cardDescription" strokeType = "OUTSIDE" strokeWidth = "0.0" wrappingWidth = "308.9830722808838" />
                        <Button fx:id = "cardDetails" mnemonicParsing = "false" prefHeight = "89.0" prefWidth = "79.0" text = "Details" textAlignment = "JUSTIFY" />
                     </children>
                  </HBox>
               </children>
            </VBox>
         </children>
      </HBox>
   </children>
</AnchorPane>

а вот FXML, где находится VBox:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<AnchorPane maxHeight = "-Infinity" maxWidth = "-Infinity" minHeight = "-Infinity" minWidth = "-Infinity" prefHeight = "700.0" prefWidth = "700.0" xmlns = "http://javafx.com/javafx/11.0.1" xmlns:fx = "http://javafx.com/fxml/1" fx:controller = "application.HotelReservationController">
   <children>
      <SplitPane dividerPositions = "0.14630681818181818" layoutX = "-2.0" layoutY = "-2.0" orientation = "VERTICAL" prefHeight = "706.0" prefWidth = "708.0">
        <items>
          <AnchorPane minHeight = "0.0" minWidth = "0.0" prefHeight = "85.0" prefWidth = "162.0" style = "-fx-background-color: brown;">
               <children>
                  <HBox layoutX = "2.0" prefHeight = "100.0" prefWidth = "248.0" spacing = "2.0" AnchorPane.bottomAnchor = "0.0" AnchorPane.leftAnchor = "0.0" AnchorPane.rightAnchor = "0.0" AnchorPane.topAnchor = "75.0">
                     <children>
                        <Button mnemonicParsing = "false" style = "-fx-background-color: #EE854E;" text = "Home" />
                        <Button mnemonicParsing = "false" style = "-fx-background-color: #EE854E;" text = "Hotels" />
                        <Button mnemonicParsing = "false" style = "-fx-background-color: #EE854E;" text = "Cars" />
                        <Button mnemonicParsing = "false" style = "-fx-background-color: #EE854E;" text = "Trips" />
                     </children>
                  </HBox>
               </children>
            </AnchorPane>
          <AnchorPane minHeight = "0.0" minWidth = "0.0" prefHeight = "508.0" prefWidth = "673.0" style = "-fx-background-color: orange;">
               <children>
                  <ScrollPane fx:id = "scrollPaneContent" layoutX = "-1.0" layoutY = "-2.0" prefHeight = "605.0" prefWidth = "708.0" style = "-fx-background-color: orange;" AnchorPane.bottomAnchor = "0.0" AnchorPane.leftAnchor = "0.0" AnchorPane.rightAnchor = "0.0" AnchorPane.topAnchor = "0.0">
                     <content>
                        <VBox fx:id = "vboxData" prefHeight = "176.0" prefWidth = "705.0" style = "-fx-background-color: orange;" />
                     </content></ScrollPane>
               </children></AnchorPane>
        </items>
      </SplitPane>
   </children>
</AnchorPane>

и вот как я реализовал это в java:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;


public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage primaryStage) {
        try {
            AnchorPane root =(AnchorPane) FXMLLoader.load(Main.class.getResource("/application/HotelReservation.fxml"));
            
            Scene scene = new Scene(root);
            primaryStage.setScene(scene);
            primaryStage.setTitle("Hotel Reservation");
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
        
    }
}

......

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;

public class HotelReservationController implements Initializable{
@FXML
    private ScrollPane scrollPaneContent;
    @FXML
    private VBox vboxData;
    @FXML
    private AnchorPane cardAnchor;
    @FXML
    private HBox cardHBox;

    @Override
        public void initialize(URL arg0, ResourceBundle arg1) {
            // TODO Auto-generated method stub
            vboxData.setSpacing(5);
            
            vboxData.getChildren().add(cardAnchor);
    //      for (int j = 0; j < 100; j++) {
    //          vboxData.getChildren().add(cardAnchor);
    //      }
            
        }
минимальный воспроизводимый пример пожалуйста .. включая приложение, контроллер, fxml, полную трассировку стека
kleopatra 17.12.2020 13:28

Я отредактировал, так лучше?

TestUser1 17.12.2020 13:35

также я пометил его с помощью eclipse и Scene Builder для Java

TestUser1 17.12.2020 13:43

может быть .. (хотя это не похоже на полную трассировку стека - только форматирование :) .. и отсутствует приложение, которое загружает fxml

kleopatra 17.12.2020 14:03

какое приложение будет загружать fxml? Вы имеете в виду что-то кроме конструктора сцен или что-то в этом роде? кажется, я добавил это, может быть, вы хотели увидеть главное

TestUser1 17.12.2020 14:07

В вашем файле HotelReservation.fxml нет элемента с fx:id, установленным на cardAnchor, поэтому cardAnchor в контроллере имеет значение null. Если я понимаю, что вы пытаетесь сделать, вам нужно загрузить другой FXML в контроллер.

James_D 17.12.2020 14:43

ааа.. опять форматирование... не ожидал двух классов в одном блоке кода, лучше использовать два отдельных блока :) Но тут @James_D уже заметил проблему.

kleopatra 17.12.2020 14:49

@James_D как мне это сделать? Кроме того, правильно ли я все реализовал?

TestUser1 17.12.2020 14:53

@kleopatra я перередактировал это

TestUser1 17.12.2020 14:55

Ну, если вы получаете исключение и приложение не делает то, что вы хотите, то по определению вы не реализовали что-то правильно.

James_D 17.12.2020 14:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
739
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В HotelReservation.fxml нет элемента с fx:id = "cardAnchor", поэтому cardAnchor имеет значение null в контроллере, и вы получаете исключение нулевого указателя, показанное в трассировке стека.

Чтобы «создать экземпляры FXML», вам нужно загрузить файл FXML. Итак, я думаю, что вы пытаетесь сделать здесь:

public class HotelReservationController implements Initializable{
    @FXML
    private ScrollPane scrollPaneContent;
    @FXML
    private VBox vboxData;
    @FXML
    private HBox cardHBox;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // unclear why you wouldn't do this in the FXML
        vboxData.setSpacing(5);

        // guessing at the path, will need to be set appropriately:
        URL cardURL = getClass().getResource("/application/Card.fxml");

        try {
            for (int j = 0; j < 100; j++) {
                Parent cardAnchor = FXMLLoader.load(cardURL);
                vboxData.getChildren().add(cardAnchor);
            }
        } catch (IOException exc) {
            exc.printStackTrace();
            System.exit(1);
        }
        
    }
}

это сработало. большое спасибо. также вы должны окружить его с помощью Try and Catch, чтобы он работал, и я добавил vboxData.setSpacing(5), чтобы я мог тестировать его динамически и более легко.

TestUser1 17.12.2020 15:06

Другие вопросы по теме