समाधान 1: अपने आवेदन के माध्यम से HostServices
पर एक संदर्भ पास करें।
यह शायद "बहुत दर्दनाक" दृष्टिकोण के समान है जो आप उम्मीद कर रहे हैं।
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
Parent root = loader.load();
MainController controller = loader.getController();
controller.setHostServices(getHostServices());
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
और फिर MainController
में:
public class DialogController {
@FXML
private Hyperlink hyperlink ;
private HostServices hostServices ;
public HostServices getHostServices() {
return hostServices ;
}
public void setHostServices(HostServices hostServices) {
this.hostServices = hostServices ;
}
@FXML
private void openURL() {
hostServices.openDocument(hyperlink.getText());
}
}
समाधान 2:
public class MainController {
private HostServices hostServices ;
public HostServices getHostServices() {
return hostServices ;
}
public void setHostServices(HostServices hostServices) {
this.hostServices = hostServices ;
}
@FXML
private void showDialog() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("dialog.fxml"));
Parent dialogRoot = loader.load();
DialogController dialogController = loader.getController();
dialogController.setHostServices(hostServices);
Stage dialog = new Stage();
dialog.setScene(new Scene(dialogRoot));
dialog.show();
}
}
और पाठ्यक्रम DialogController
की तरह लग रहा है उपयोग लेकिन मूल रूप से आप की तरह कुछ करना होगा मेजबान servic धक्का करने के लिए एक नियंत्रक कारखाना नियंत्रकों के लिए es।
यह उपर्युक्त का एक क्लीनर संस्करण है।नियंत्रक हो रही है और उन्हें प्रारंभ करने के लिए एक विधि बुला के बजाय, आप एक controllerFactory
के माध्यम से उन्हें के निर्माण कॉन्फ़िगर और नियंत्रक के निर्माता के लिए एक HostServices
वस्तु पारित करके नियंत्रक बनाने के लिए, अगर यह एक उपयुक्त निर्माता है: अब
public class HostServicesControllerFactory implements Callback<Class<?>,Object> {
private final HostServices hostServices ;
public HostServicesControllerFactory(HostServices hostServices) {
this.hostServices = hostServices ;
}
@Override
public Object call(Class<?> type) {
try {
for (Constructor<?> c : type.getConstructors()) {
if (c.getParameterCount() == 1 && c.getParameterTypes()[0] == HostServices.class) {
return c.newInstance(hostServices) ;
}
}
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
जब आप FXML लोड नियंत्रक कारखाने का उपयोग करें:
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
loader.setControllerFactory(new HostServicesControllerFactory(getHostServices()));
Parent root = loader.load();
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
और एक निर्माता पैरामीटर के रूप में HostServices
लेने के लिए अपने नियंत्रक को परिभाषित:
public class MainController {
private final HostServices hostServices ;
public MainController(HostServices hostServices) {
this.hostServices = hostServices ;
}
@FXML
private void showDialog() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("dialog.fxml"));
loader.setControllerFactory(new HostServicesControllerFactory(hostServices));
Parent dialogRoot = loader.load();
Stage dialog = new Stage();
dialog.setScene(new Scene(dialogRoot));
dialog.show();
}
}
और पाठ्यक्रम
public class DialogController {
@FXML
private Hyperlink hyperlink ;
private final HostServices hostServices ;
public DialogController(HostServices hostServices) {
this.hostServices = hostServices ;
}
@FXML
private void openURL() {
hostServices.openDocument(hyperlink.getText());
}
}
समाधान 3 की:यह एक बुरी तरह बदसूरत समाधान है, और मैं दृढ़ता से यह उपयोग करने के खिलाफ सलाह देते हैं। मैं बस इसे शामिल करना चाहता था इसलिए मैं इसे व्यक्त कर सकता था कि जब उन्होंने इसे पोस्ट किया तो किसी और को अपमानित किया। एक स्थिर क्षेत्र में मेजबान सेवाओं को स्टोर करें।
public class MainApp extends Application {
private static HostServices hostServices ;
public static HostServices getHostServices() {
return hostServices ;
}
public void start(Stage primaryStage) throws Exception {
hostServices = getHostServices();
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
तो फिर तुम सिर्फ
MainApp.getHostServices().showDocument(hyperlink.getText());
कहीं भी आप की जरूरत है। यहां की समस्याओं में से एक यह है कि आप अपने आवेदन प्रकार पर उन सभी नियंत्रकों के लिए निर्भरता पेश करते हैं जिन्हें होस्ट सेवाओं तक पहुंच की आवश्यकता होती है।
समाधान 4 एक सिंगलटन HostServicesProvider
को परिभाषित करें। यह समाधान 3 से बेहतर है, लेकिन अभी भी एक अच्छा समाधान आईएमओ नहीं है।
public enum HostServicesProvider {
INSTANCE ;
private HostServices hostServices ;
public void init(HostServices hostServices) {
if (this.hostServices != null) {
throw new IllegalStateException("Host services already initialized");
}
this.hostServices = hostServices ;
}
public HostServices getHostServices() {
if (hostServices == null) {
throw new IllegalStateException("Host services not initialized");
}
return hostServices ;
}
}
अब तुम सिर्फ
public void start(Stage primaryStage) throws Exception {
HostServicesProvider.INSTANCE.init(getHostServices());
// just load and show main app...
}
और
public class DialogController {
@FXML
private Hyperlink hyperlink ;
@FXML
private void openURL() {
HostServicesProvider.INSTANCE.getHostServices().showDocument(hyperlink.getText());
}
}
समाधान की जरूरत है 5 एक निर्भरता इंजेक्शन ढांचे का प्रयोग करें। यह शायद आपके वर्तमान उपयोग मामले पर लागू नहीं होता है, लेकिन आपको यह विचार दे सकता है कि ये (अपेक्षाकृत सरल) ढांचे कितने शक्तिशाली हो सकते हैं।
उदाहरण के लिए, यदि आप afterburner.fx उपयोग कर रहे हैं, तो आप सिर्फ अपने आवेदन start()
या init()
विधि में
Injector.setModelOrService(HostServices.class, getHostServices());
क्या करने की जरूरत है, और फिर
public class DialogPresenter {
@Inject
private HostServices hostServices ;
@FXML
private Hyperlink hyperlink ;
@FXML
private void showURL() {
hostServices.showDocument(hyperlink.getText());
}
}
एक वसंत का उपयोग कर उदाहरण here है।
अगर आप getHostServices अलग तरह से जैसे नाम नहीं बदसूरत स्थिर समाधान काम नहीं करेगा getStaticHostServices। यह मेरे उपयोग के मामले में कम से कम प्रयास समाधान है। –
@WolfgangFahl हाँ, शायद। निश्चित नहीं है कि आप कुछ भी कोशिश क्यों करेंगे मैं वैसे भी उपयोग करने के खिलाफ दृढ़ता से अनुशंसा करता हूं। –
कोई चिंता नहीं है अब मैं एक इंटरफ़ेस का उपयोग कर रहा हूं सार्वजनिक इंटरफ़ेस लिंकर { सार्वजनिक शून्य ब्राउज़ (स्ट्रिंग यूआरएल); } जो कार्यान्वयन को छुपाता है - स्थिर सामग्री की आवश्यकता नहीं है –