आप FXMLLoader
के लिए controller factory निर्दिष्ट कर सकते हैं। नियंत्रक फैक्ट्री एक ऐसा फ़ंक्शन है जो नियंत्रक वर्ग को ऑब्जेक्ट (संभवतः, लेकिन जरूरी नहीं, उस वर्ग का एक उदाहरण) पर मैप करता है जिसे नियंत्रक के रूप में उपयोग किया जाएगा।
ApplicationContext context = ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(context::getBean);
Parent root = loader.load();
SomeController controller = loader.getController(); // if you need it...
// ...
और अब FXMLLoader
context.getBean(c);
को फोन करके एक Class<?> c
के लिए नियंत्रक उदाहरण बना देगा:
तो तुम स्प्रिंग आप के लिए नियंत्रक उदाहरणों बनाना चाहते हैं, इस के रूप में सरल हो सकता है।
public class SomeController {
// injected by FXMLLoader:
@FXML
private TextField someTextField ;
// Injected by Spring:
@Inject
private MyService service ;
public void initialize() {
someTextField.setText(service.getSomeText());
}
// event handler:
@FXML
private void performAction(ActionEvent e) {
service.doAction(...);
}
}
साथ
@Configuration
public class AppConfig {
@Bean
public MyService service() {
return new MyServiceImpl();
}
@Bean
@Scope("prototype")
public SomeController someController() {
return new SomeController();
}
// ...
}
आप एक डि ढांचे का उपयोग नहीं कर रहे हैं, और आप "हाथ से" इंजेक्शन क्या करना चाहते हैं:
तो, उदाहरण के लिए, आप एक विन्यास हो सकता था , आप ऐसा कर सकते हैं, लेकिन इसमें काफी प्रतिबिंब का उपयोग करना शामिल है। निम्नलिखित कैसे पता चलता है (और आप कितना कुरूप काम स्प्रिंग आप के लिए क्या कर रहा है की एक विचार दे देंगे!):
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
MyService service = new MyServiceImpl();
loader.setControllerFactory((Class<?> type -> {
try {
// look for constructor taking MyService as a parameter
for (Constructor<?> c : type.getConstructors()) {
if (c.getParameterCount() == 1) {
if (c.getParameterTypes()[0]==MyService.class) {
return c.newInstance(service);
}
}
}
// didn't find appropriate constructor, just use default constructor:
return type.newInstance();
} catch (Exception exc) {
throw new RuntimeException(exc);
}
});
Parent root = loader.load();
// ...
और फिर बस
public class SomeController {
private final MyService service ;
public SomeController(MyService service) {
this.service = service ;
}
// injected by FXMLLoader:
@FXML
private TextField someTextField ;
public void initialize() {
someTextField.setText(service.getSomeText());
}
// event handler:
@FXML
private void performAction(ActionEvent e) {
service.doAction(...);
}
}
अंत में करते हैं, आप की जाँच करने के लिए चाहते हो सकता है afterburner.fx, जो कि बहुत हल्का है (सभी बेहतरीन तरीकों से) जावाएफएक्स-विशिष्ट डी ढांचे। (यह एक सम्मेलन-ओवर-कॉन्फ़िगरेशन दृष्टिकोण का उपयोग करता है, जहां आप केवल FXML फ़ाइल नामों को नियंत्रक वर्ग के नामों से मेल खाते हैं, और वैकल्पिक रूप से सीएसएस फ़ाइल नामों से मेल खाते हैं, और सबकुछ बस काम करता है।)