Динамический доступ/обход/манипулирование узлами JavaFX, созданными из FXML вне класса контроллера

Может ли кто-нибудь помочь мне. Я новичок в JavaFX и FXML, и я безуспешно пытался что-то сделать в течение бесчисленных часов. Может ли кто-нибудь показать мне рабочий пример кода, который

1) загружает FXML, содержащий узлы (например, метки и кнопки), вложенные в несколько слоев вглубь различных панелей и узлов;

2) пройти всю сцену со списком узлов (таких как метки и кнопки);

3) связать код Java с узлом (например, меткой и кнопкой), чтобы я мог изменять его свойства (например, метку и содержимое) вне класса контроллера, определенного для FXML.

Моя цель — создать пользовательский интерфейс с помощью конструктора сцен, а затем иметь возможность динамически изменять содержимое сцены, а также добавлять в нее другие узлы. Моя проблема в том, что я не могу добраться до объектов на сцене/сцене.

Вот кусок кода, с которым я работал. Комментарии подсказывают, что я ищу.

//

public void start(Stage stage) throws Exception {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Sample.fxml"));
    Parent root = (Parent)fxmlLoader.load();
    SampleController controller = (SampleController)fxmlLoader.getController();
    controller.label.setText("Label text has been set");
    controller.button.setText("Button text has been set");

    // Looking for an example of traversing all the objects within the controller
    // looking for an object such as a TableView and its columns. Would like to
    // attach code outside the controller which populates the TableView.

    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

person Mark    schedule 07.02.2013    source источник
comment
Опубликуйте пример FXML и укажите желаемый результат, пожалуйста.   -  person zhujik    schedule 20.02.2013


Ответы (1)


Вы должны получить все узлы в контейнере root рекурсивно:

public void start(Stage stage) throws Exception {
   FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Sample.fxml"));
   Parent root = (Parent)fxmlLoader.load();

   List<Node> allNodes = getAllNodes(root);
   for(Node node : allNodes) {
      // do some stuff…
   }
   …
}

private List<Node> getAllNodes(Parent container) {
    List<Node> nodes = new ArrayList<Node>();
    for(Node node : container.getChildrenUnmodifiable())
    {
       nodes.add(node);
       if (node instanceof Parent) {
          Parent subContainer = (Parent) node;
          nodes.addAll( getAllNodes(subContainer) );
       }
    }
    return nodes;
}

Вы можете получить доступ к полю @FXML (например, TableView) вашего контроллера так же, как вы уже это делали… :-)

Кроме того, в TableView есть метод для получения столбцов, например. controller.tableView.getColumns()…

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

Ваше здоровье

person Ignatiamus    schedule 12.06.2017