Как FXMLLoader загружает контроллер FXML?

Что происходит, когда я вызываю FXMLLoader#load() в JavaFX?

Предположим, контроллер FXML расширяет класс, у которого есть конструктор. Будет ли гарантия того, что конструктор будет вызван? А если нет, то как будет создан новый экземпляр объекта? Например, в приведенном ниже коде будет вызываться конструктор TextField()?

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
public class FXMLController extends TextField implements Initializable {
    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }    
}

Я уже пытался найти это, но, похоже, об этом нет никакой документации, кроме «Загружает иерархию объектов из документа FXML». из http://docs.oracle.com/javafx/2/api/javafx/fxml/FXMLLoader.html

Ваши ответы будут оценены. Большое спасибо!


person damat-perdigannat    schedule 09.10.2013    source источник


Ответы (2)


Чтобы ответить на ваш вопрос «что именно делает FXMLLoader при создании контроллера?»:

сначала он попытается получить экземпляр контроллера:

  • если в FXMLLoader уже установлен экземпляр контроллера, он будет использовать этот экземпляр.
  • если в FXMLLoader не установлена ​​фабрика контроллеров, он пытается вызвать конструктор класса с нулевым аргументом для каждого отражения. Если это не удается, генерируется InstantiationException.
  • если есть установленная фабрика контроллера, она вызовет эту фабрику для создания нового экземпляра контроллера.

после получения экземпляра контроллера он сделает с ним следующее:

  • если этот класс реализует Initializable, он вызывает public void initialize(URL-адрес, ResourceBundle resourceBundle). Если нет, он ищет метод с именем initialize с нулевыми аргументами и вызывает его через отражение. Если нет, то ничего не делает.
person zhujik    schedule 09.10.2013
comment
Ух ты. Спасибо за быстрый ответ. Процесс звучит интересно. Хотите сообщить мне ваш источник? - person damat-perdigannat; 09.10.2013
comment
Вы можете легко проверить это поведение, и вы также можете увидеть его в исходном коде, доступном на openjdk. - person zhujik; 09.10.2013
comment
Спасибо. Я мог бы проверить openjdk. - person damat-perdigannat; 10.10.2013
comment
Вы также можете установить контроллер явно (не только заводской). - person Puce; 19.10.2013
comment
Спасибо Пьюс. Будет ли правильно, если контроллер уже установлен, FXMLLoader просто вызовет метод инициализации контроллера? - person damat-perdigannat; 04.11.2013

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

Кроме того, это базовый материал Java: текстовое поле имеет пустой конструктор, ваш контроллер не имеет его, поэтому java (по умолчанию) вызовет пустой конструктор, доступный в TextField. Конструктор TextField по умолчанию (даже если его нет в коде) вызывает конструктор класса, который он расширяет, и так далее. Невозможно построить объект в java без вызова конструктора.

person nablex    schedule 09.10.2013
comment
Отлично, спасибо за оперативный ответ. Я думаю, что может быть что-то вроде текстового поля, которое может управлять элементами управления. - person damat-perdigannat; 09.10.2013