Çözüm 1: Uygulamanız boyunca HostServices
numaralı başvuruya başvurun.
Bu, muhtemelen tahmin ettiğiniz "oldukça acı verici" yaklaşıma benzer. MainController
sonra
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();
}
ve:
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());
}
}
Çözüm 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(); } }
ve tabii DialogController
ait
benziyor Kullanım Ama temelde böyle bir şey yapsın ana servise basmak için bir kontrolör fabrikası denetleyicilere
Bu, daha temiz bir sürümdür.Şimdi
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);
}
}
}
: Yerine denetleyicileri alma ve bunları başlatmak için bir yöntem çağırma uygun bir yapıcı varsa, sen bir controllerFactory
postayla oluşturulmasını yapılandırıp kontrolörün kurucusuna bir HostServices
nesne geçirerek denetleyicileri oluşturmak Eğer FXML yüklediğinizde kontrolör fabrika kullanın:
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();
}
ve yapıcı parametre olarak HostServices
almaya Denetleyicilerinizi tanımlayın:
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();
}
}
ve tabii
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());
}
}
Çözüm 3:Bu sefil çirkin bir çözümdür ve bunu şiddetle kullanmamanızı öneririz. Ben sadece onu eklemek istedim başka birine saldırmaksızın ifade edebileceğini ifade etmek istedim. Ana bilgisayar hizmetlerini statik bir alanda depolayın.
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();
}
}
Sonra sadece
MainApp.getHostServices().showDocument(hyperlink.getText());
her yerde gerekiyor. Buradaki sorunlardan biri, ana bilgisayar hizmetlerine erişmesi gereken tüm denetleyiciler için uygulama türünüze bağımlılık getirmenizdir.
Çözüm 4 a tek HostServicesProvider
tanımlayın. Bu çözüm 3'ten daha iyidir, ama yine de iyi bir çözüm imo değildir.
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 ;
}
}
Şimdi sadece 5 bir bağımlılık enjeksiyon çerçeve kullanın
public void start(Stage primaryStage) throws Exception {
HostServicesProvider.INSTANCE.init(getHostServices());
// just load and show main app...
}
ve
public class DialogController {
@FXML
private Hyperlink hyperlink ;
@FXML
private void openURL() {
HostServicesProvider.INSTANCE.getHostServices().showDocument(hyperlink.getText());
}
}
Çözüm gerekir. Bu muhtemelen geçerli kullanım durumunuz için geçerli değildir, ancak bu (nispeten basit) çerçevelerin ne kadar güçlü olabileceği konusunda size bir fikir verebilir. Eğer afterburner.fx kullanıyorsanız Örneğin, sadece uygulama start()
veya init()
yöntemde
Injector.setModelOrService(HostServices.class, getHostServices());
yapmak gerekir, ve Bahar kullanarak sonra
public class DialogPresenter {
@Inject
private HostServices hostServices ;
@FXML
private Hyperlink hyperlink ;
@FXML
private void showURL() {
hostServices.showDocument(hyperlink.getText());
}
}
bir örnek here olduğunu.
çirkin statik çözüm işe yaramaz ... getStage() olarak adlandırılan benim kontrolörü sınıfında bir yöntemi var getStaticHostServices. Kullanım durumumda en az çaba gerektiren çözümdür. –
@WolfgangFahl Evet, muhtemelen. Yine de neden kullanmaya karşı şiddetle tavsiye ettiğim bir şeyi bile denediğinizden emin değilsiniz. –
Hayır endişe Şimdi bir arabirim kullanıyorum herkese açık arabirim Bağlayıcı { public void browse (String url); Uygulamayı gizleyen } - statik malzeme bu şekilde gerekli değildir –