JavaFX FXML कंट्रोलर - कंस्ट्रक्टर बनाम इनिशियलाइज़ मेथड


84

मेरा 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:controllerपहले डिफ़ॉल्ट निर्माता और उसके बाद लागू द्वारा) initializeविधि:

public class MainViewController {

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

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

आउटपुट है:

first
second

तो, initializeविधि क्यों मौजूद है? initializeकंट्रोलर आवश्यक चीजों को इनिशियलाइज़ करने के लिए एक कंस्ट्रक्टर या विधि का उपयोग करने के बीच क्या अंतर है ?

आपके सुझाव के लिए धन्यवाद!

जवाबों:


124

कुछ शब्दों में: कंस्ट्रक्टर को पहले कहा जाता है, फिर किसी भी @FXMLएनोटेट फ़ील्ड को आबाद किया initialize()जाता है , फिर कहा जाता है। इसलिए निर्माणकर्ता के पास @FXML.fxml फ़ाइल में परिभाषित घटकों के संदर्भ में खेतों तक पहुंच नहीं है , जबकि initialize()उनके पास पहुंच नहीं है।

एफएक्सएमएल के परिचय से उद्धरण :

[...] नियंत्रक एक इनिशियलाइज़ () विधि को परिभाषित कर सकता है, जिसे एक बार कार्यान्वयन नियंत्रक पर कहा जाएगा जब उसके संबंधित दस्तावेज़ की सामग्री पूरी तरह से लोड हो गई हो [...] यह कार्यान्वयन वर्ग को किसी भी आवश्यक पोस्ट को करने की अनुमति देता है -सामग्री पर विवाद।


2
मुझे समझ नहीं आ रहा है। जिस तरह से वह ऐसा करता है FXMLLoader, ठीक है? इसलिए मुझे इस initialize()पद्धति के इंतजार में कोई लाभ नहीं दिखता है । जैसे ही एफएक्सएमएल लोड होता है, निम्न कोड में @FXMLचर तक पहुंच होती है । निश्चित रूप से, वह इसे स्टार्ट मेथड में करता है और कंस्ट्रक्टर में नहीं, लेकिन initialize()उसके मामले में कोई लाभ लाएगा?
14

90

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

11

उपरोक्त उत्तरों के अतिरिक्त, संभवतः यह ध्यान दिया जाना चाहिए कि आरंभीकरण को लागू करने के लिए एक विरासत तरीका है। वहाँ एक अंतरफलक कहा जाता है Initializable 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());
    }
}

पैरामीटर:

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इस इंटरफ़ेस को नियंत्रक में स्थान और संसाधनों के गुणों के स्वत: इंजेक्शन द्वारा दबा दिया गया है। FXMLLoader अब नियंत्रक द्वारा परिभाषित किसी भी उपयुक्त एनोटेट no-arg initialize () विधि को स्वचालित रूप से कॉल करेगा। यह अनुशंसा की जाती है कि इंजेक्शन दृष्टिकोण का उपयोग जब भी संभव हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.