JavaFX: динамически добавленный VBox не отображается

Я работаю над проектом, который требует "табличного" представления VBoxes. Мой иерархический макет приложения - GridPane -> VBox (в одной из ячеек) -> VBoxes (которые отображают разные наборы данных друг над другом) -> Данные. У меня есть две сцены.

Данные отображаются на сцене 1. Пользователь может добавить данные через форму и, нажав кнопку на сцене 2. Затем добавленные данные должны отображаться под существующими данными в виде VBox в родительском VBox на сцене 1.

Вот код, который прояснит это:

Файл.fxml моей сцены 1 выглядит следующим образом (упрощенно):

<GridPane fx:id="grid" fx:controller="application.Controller">
  [here: ColumnConstraints]
  <children>
    <VBox fx:id="parentBox" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
    <Button fx:id="goToScene2" text="+" onAction="#goToScene2"/> 
  </children>  
</GridPane>

Сцена 2 просто имеет кнопку и TextField:

<GridPane fx:id="grid" fx:controller="application.AddDataController">
  [here: ColumnConstraints]
  <children>
    <Button fx:id="addData" text="add" onAction="#bAddData"/> 
    <TextField fx:id="data"/>
  </children>  
</GridPane>

Мой Scene 1 контроллер (контроллер) выглядит так:

public class Controller implements Initializable  {
  @FXML Button goToScene2;
  @FXML VBox parentBox;

  @Override
  public void initialize(URL location, ResourceBundle resources) {
  }

  public void addData(String s) {
    Label lbl = new Label(s);
    VBox dataBox = new VBox();
    dataBox.setPadding(new Insets(15, 5, 15, 5));
    dataBox.setSpacing(5);
    dataBox.setMaxHeight(80);
    dataBox.getChildren().add(lbl);
    parentBox.getChildren().add(dataBox);
  }
}

Это разработано так, как есть, потому что dataBox содержит больше элементов, чем метка, но это не кажется мне актуальным в этом контексте.

Мой контроллер Scene 2 (addDataController) выглядит так:

@FXML Button addData;
@FXML TextField data;

@FXML protected void bAddData(){
  String content = data.getText();    
  FXMLLoader fxmlLoader = new FXMLLoader();
  Pane p = fxmlLoader.load(getClass().getResource("scn1.fxml").openStream());
  Controller cont = (Controller) fxmlLoader.getController();

  cont.addData(content);
}

Таким образом, при нажатии кнопки "Добавить данные" в сцене 2 сработавший метод передает введенные данные контроллеру сцены 1. Это происходит потому, что новые данные должны отображаться в сцене 1 сейчас.

Я чувствую, что логика не работает (отредактировано здесь), потому что, когда я спрашиваю

System.out.println(parentBox.getChildren().size();

до и после добавления данных у него всегда есть один дочерний элемент, хотя у него должен быть еще один...

Если я искусственно заполняю String-Array и перемещаю все из addData в (String s) в Initialize(...), это работает, и данные отображаются как VBox в родительском VBox.

Я не опубликовал основной класс, потому что загрузка контроллеров и изменение сцены не является проблемой.

Большое спасибо всем за помощь!:)

1 ответ

Просто чтобы предоставить более подробную информацию вместе с идеей, которую я не знаю, как реализовать.

Это мой основной класс:

@Override
public void start(Stage primaryStage) {
  currentStage = primaryStage;
  Parent root = FXMLLoader.load(getClass().getResource("Scene1.fxml"));
  scene1 = new Scene(root);
}

Могу ли я загрузить контроллер в этот момент и создать геттер, который проходит через контроллер? Таким образом, у меня был только один экземпляр этого во всей программе.

Я попытался вставить:

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.load(getClass().getResource("Scene1.fxml").openStream());
Controller controller = (Controller) fxmlLoader.getController();

после

Parent root ...

линия. Но это загружает.xml файл дважды. Как я могу красиво соединить обе части?

Большое спасибо за терпение!

РЕДАКТИРОВАТЬ::::::::: Следующий код работал для меня:

@Override
public void start(Stage primaryStage) {
  currentStage = primaryStage;
  FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Scene1.fxml"));
  Parent root =(Parent) fxmlLoader.load();
  controller = (Controller) fxmlLoader.getController();
}

Теперь я могу попросить основной класс для controller и это всегда проходит тот единственный случай.

Спасибо, что указали мне правильное направление!:)

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