gpt4 book ai didi

java - 使用 Guice 将数据注入(inject) JavaFX ViewController

转载 作者:行者123 更新时间:2023-11-30 06:10:14 24 4
gpt4 key购买 nike

今天我将 Guice 添加到我的 Java FX 应用程序中。主要目标是用注入(inject)替换我的单例并分解依赖关系。到目前为止一切正常,这是我必须开始一个新场景的代码:

public class App extends Application{

public static void main(String[] args){
launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
final String LANGUAGE_BUNDLE = "myBundlePath";
final String FXML = "myFXMLPath";

try {
ResourceBundle resourceBundle = ResourceBundle.getBundle(LANGUAGE_BUNDLE, Locale.GERMAN, this.getClass().getClassLoader());
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(FXML), resourceBundle, new JavaFXBuilderFactory(), getGuiceControllerFactory());
primaryStage.setScene(new Scene(fxmlLoader.load()));
primaryStage.show();
}catch (IOException ex) {
ex.printStackTrace();
}
}

private Callback<Class<?>, Object> getGuiceControllerFactory(){
Injector injector = Guice.createInjector(new GuiceModule());
return new Callback<Class<?>, Object>() {
@Override
public Object call(Class<?> clazz) {
return injector.getInstance(clazz);
}
};
}
}

我的 Guice 模块如下所示:

public class GuiceModule extends AbstractModule {
@Override
protected void configure() {
bind(ITester.class).to(Tester.class);
bind(ISecondTest.class).to(SecondTest.class);
}
}

请注意,我替换了资源包和 fxml 文件的路径,因为它们会暴露我的身份。但是加载和一切正常,所以这应该不是问题;)

现在的问题是,我想通过在不同 View 中单击按钮来实例化一个新 View 。第二个 View 应该显示 View 1 中数据的更详细版本。我需要传递给第二个 View 的所有内容都是整数(或 int),但我完全不知道如何执行此操作。

我有标准的 FX 设置:

View.fxml (with a reference to the ViewController)
ViewController.java
Model.java
ViewModel.java

ViewController 然后绑定(bind)到 ViewModel 提供的属性。我需要 int 来选择正确的模型。

我能找到的所有内容都是关于注释 @Named 但据我所知,这不能用于注入(inject)动态数据。

你能给我提示一下我想做的这个叫什么吗?或者长话短说:如何在第二个 ViewController 中注入(inject)由不同 View 选择的变量,并将其余部分留在标准 FX 方式中?

感谢任何帮助并提前致谢!

问候,克里斯蒂安

最佳答案

经过多方尝试,看来我自己找到了解决方案!但是,它“感觉”我正在做的事情很丑陋,所以我想得到一些确认;)

首先是理论:Guice 支持“AssistedInject”。这是,当一个类不能由默认构造函数构造时。为了能够使用 AssistedInject,您必须下载扩展程序(我从 maven repository 下载了 jar)。

AssistedInject 为您做的是它允许您指定一个为您构建变量的工厂。所以这就是我所做的:

首先,为您稍后要使用的类创建一个接口(interface),在我的例子中:

public interface IViewController {
}

其次,为工厂创建一个接口(interface)。重要提示:您不必实现工厂

public interface IControllerFactory {

ViewController create(@Assisted int myInt);

}

第三,将带有相应参数的构造函数添加到您稍后要实例化的类中,并让它实现您创建的接口(interface),如下所示:

public class ViewController implements IViewController{

@AssistedInject
public ViewController(@Assisted int i){
final String LANGUAGE_BUNDLE = "languageBundle";
final String FXML = "View.fxml";

try{
ResourceBundle resourceBundle = ResourceBundle.getBundle(LANGUAGE_BUNDLE, Locale.GERMAN, this.getClass().getClassLoader());
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(FXML), resourceBundle, new JavaFXBuilderFactory());
fxmlLoader.setController(this);
Stage second = new Stage();
second.setScene(new Scene(fxmlLoader.load()));
second.show();
}catch (IOException e){
e.printStackTrace();
}
System.out.println("ViewController constructor called with: " + i);
}

这里有几点需要注意:

  • 方法的注释“@AssistedInject”
  • 我们要向外部提供的参数的注解“@Assisted”
  • 我们手动设置加载器的 Controller (使用 fxmlLoader.setController(this);)
  • 我必须删除 fxml 文件中的 Controller 配置,所以 fxml 中没有“fx:controller”!

接下来我们需要将一个变量添加到我们想要实例化另一个类的类中:

@Inject
IControllerFactory controllerFactory;

我们可以像这样在类中使用它:

controllerFactory.create(3)

注意:我们将从未在 ViewController 类中实现的方法称为“create”! Guice 知道它必须调用构造函数 - 魔法

作为最后一步,我们需要在我们的 GuiceModule 中添加到上下文的连接,如下所示:

@Override
protected void configure(){
install(new FactoryModuleBuilder()
.implement(IPagingDirectoryViewController.class, PagingDirectoryViewController.class)
.build(IPagingDirectoryControllerFactory.class));
}

注意 我收到错误:无法解析方法'implement java.lang.Class<"The interface class">, java.lang.Class<"The implementing class">'。这是因为我忘记让我的 Controller 类实现接口(interface)。

好的,这就是我让它工作的方式。然而,正如我所说,我很乐意听取一些意见!

问候,克里斯蒂安

关于java - 使用 Guice 将数据注入(inject) JavaFX ViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36165151/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com