Program Tip

JavaFX FXML 컨트롤러-생성자 대 초기화 방법

programtip 2020. 11. 3. 18:53
반응형

JavaFX FXML 컨트롤러-생성자 대 초기화 방법


Application수업은 다음과 같습니다.

public class Test extends Application {

    private static Logger logger = LogManager.getRootLogger();

    @Override
    public void start(Stage primaryStage) throws Exception {

        String resourcePath = "/resources/fxml/MainView.fxml";
        URL location = getClass().getResource(resourcePath);
        FXMLLoader fxmlLoader = new FXMLLoader(location);

        Scene scene = new Scene(fxmlLoader.load(), 500, 500);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

먼저 기본 생성자를 호출 한 다음 메서드 를 호출 FXMLLoader하여 해당 컨트롤러의 인스턴스 ( FXML를 통해 파일에 제공됨)를 만듭니다 .fx:controllerinitialize

public class MainViewController {

    public MainViewController() {
        System.out.println("first");
    }

    @FXML
    public void initialize() {
        System.out.println("second");
    }
}

출력은 다음과 같습니다.

first
second

그렇다면 initialize방법이 존재 하는 이유는 무엇입니까? 생성자 또는 initialize컨트롤러를 초기화하는 방법을 사용하는 것의 차이점은 무엇입니까 ?

제안 해 주셔서 감사합니다!


간단히 말해서 생성자가 먼저 호출 된 다음 @FXML주석이 달린 필드가 채워진 다음 initialize()호출됩니다. 따라서 생성자는 @FXML.fxml 파일에 정의 된 구성 요소를 참조 하는 필드에 액세스 할 수 없지만 initialize()액세스 할 수 있습니다.

FXML 소개 에서 인용 :

[...] 컨트롤러는 관련 문서의 내용이 완전히로드되었을 때 구현 컨트롤러에서 한 번 호출되는 initialize () 메서드를 정의 할 수 있습니다. [...]이를 통해 구현 클래스가 필요한 게시를 수행 할 수 있습니다. -콘텐츠 처리.


initialize메서드는 @FXML주석이 달린 모든 멤버가 삽입 된 후에 호출 됩니다. 데이터로 채우려는 테이블 뷰가 있다고 가정합니다.

class MyController { 
    @FXML
    TableView<MyModel> tableView; 

    public MyController() {
        tableView.getItems().addAll(getDataFromSource()); // results in NullPointerException, as tableView is null at this point. 
    }

    @FXML
    public void initialize() {
        tableView.getItems().addAll(getDataFromSource()); // Perfectly Ok here, as FXMLLoader already populated all @FXML annotated members. 
    }
}

위의 답변 외에도 초기화를 구현하는 레거시 방법이 있다는 점에 유의해야합니다. fxml 라이브러리 에는 Initializable 이라는 인터페이스가 있습니다.

import javafx.fxml.Initializable;

class MyController implements Initializable {
    @FXML private TableView<MyModel> tableView;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        tableView.getItems().addAll(getDataFromSource());
    }
}

매개 변수 :

location - The location used to resolve relative paths for the root object, or null if the location is not known.
resources - The resources used to localize the root object, or null if the root object was not localized. 

그리고 문서의 간단한 사용 방법이 @FXML public void initialize()작동 하는 이유 :

NOTE This interface has been superseded by automatic injection of location and resources properties into the controller. FXMLLoader will now automatically call any suitably annotated no-arg initialize() method defined by the controller. It is recommended that the injection approach be used whenever possible.

참고URL : https://stackoverflow.com/questions/34785417/javafx-fxml-controller-constructor-vs-initialize-method

반응형