Bộ điều khiển JavaFX FXML - phương thức khởi tạo và khởi tạo


84

ApplicationLớp của tôi trông như thế này:

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);
    }
}

Hàm FXMLLoadertạo một phiên bản của bộ điều khiển tương ứng (được cung cấp trong FXMLtệp qua fx:controller) bằng cách gọi hàm tạo mặc định đầu tiên và sau đó là initializephương thức:

public class MainViewController {

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

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

Đầu ra là:

first
second

Vì vậy, tại sao initializephương pháp tồn tại? Sự khác biệt giữa việc sử dụng một hàm tạo hoặc initializephương thức để khởi tạo những thứ cần thiết của bộ điều khiển là gì?

Cảm ơn những đề xuất của bạn!

Câu trả lời:


124

Nói một cách ngắn gọn: Hàm tạo được gọi đầu tiên, sau đó bất kỳ @FXMLtrường chú thích nào được điền vào, sau đó initialize()được gọi. Vì vậy, hàm tạo KHÔNG có quyền truy cập vào @FXMLcác trường tham chiếu đến các thành phần được xác định trong tệp .fxml, trong khi initialize()có quyền truy cập vào chúng.

Trích dẫn từ Giới thiệu về FXML :

[...] bộ điều khiển có thể định nghĩa một phương thức khởi tạo (), phương thức này sẽ được gọi một lần trên bộ điều khiển thực thi khi nội dung của tài liệu liên quan của nó đã được tải hoàn toàn [...] Điều này cho phép lớp thực thi thực hiện bất kỳ bài đăng cần thiết nào -xử lý về nội dung.


2
Tôi không hiểu. Cách anh ấy làm là hơn FXMLLoader, phải không? Vì vậy, tôi không thấy lợi ích khi chờ đợi initialize()phương pháp -. Ngay sau khi FXML được tải, mã sau có quyền truy cập vào các @FXMLbiến. Chắc chắn, anh ta làm điều đó trong phương thức bắt đầu chứ không phải trong hàm tạo, nhưng sẽ initialize()mang lại bất kỳ lợi ích nào trong trường hợp của anh ta?
codepleb 21/09/16

90

Các initializephương pháp được gọi là sau khi tất cả @FXMLcác thành viên chú thích đã được tiêm. Giả sử bạn có chế độ xem bảng mà bạn muốn điền dữ liệu:

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. 
    }
}

11

Ngoài các câu trả lời trên, có lẽ cần lưu ý rằng có một cách kế thừa để thực hiện khởi tạo. Có một giao diện được gọi là Initializable từ thư viện fxml.

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());
    }
}

Thông số:

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. 

Và lưu ý của tài liệu tại sao cách sử dụng đơn giản lại @FXML public void initialize()hoạt động:

NOTEGiao diện này đã được thay thế bằng cách tự động đưa các thuộc tính vị trí và tài nguyên vào bộ điều khiển. FXMLLoader bây giờ sẽ tự động gọi bất kỳ phương thức khởi tạo no-arg nào được chú thích thích hợp bởi bộ điều khiển. Khuyến cáo nên sử dụng phương pháp tiêm bất cứ khi nào có thể.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.