在我的Guice模块中,我想关联FXML文件及其控制器,目前看起来像这样:
public class GuiceModule extends AbstractModule
{
@Override
protected void configure()
{
// associate controllers and fxml files
bind(MainController.class).toInstance((MainController)loadController("/main.fxml"));
bind(SubController.class).toInstance((SubController)loadController("/content.fxml"));
}
protected Object loadController(String url)
{
InputStream fxmlStream = null;
try
{
fxmlStream = getClass().getResourceAsStream(url);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource(url));
loader.setControllerFactory(new Callback<Class<?>, Object>() {
public Object call(Class<?> clazz) { // clazz because class is a reserved word
return injector.getInstance(clazz); // PROBLEM: no access to the injector here
}
});
loader.load(fxmlStream);
return loader.getController();
}
// [..] exception handling
}
}**strong text**
然而,在loadController(String url)
方法中,我遇到了该行的问题:
return injector.getInstance(clazz); // PROBLEM: no access to the injector here
如何从Guice模块中访问Guice的getInstance
方法?那可能是同等的吗?
答案 0 :(得分:3)
我是 fx-guice 的作者,这是一个开源库,可用于在JavaFX应用程序中使用Guice。该库使用Apache License v2许可,可以通过中心Maven repository获得。
即使它可能不回答您的确切问题,我建议您查看我的项目,其中包含了很多示例:
项目主页:→http://github.com/cathive/fx-guice/
我的框架的主要思想是: 您可以扩展“com.cathive.fx.GuiceApplication”而不是扩展“javafx.application.Application”。然后,您可以简单地在任何地方@Inject实现“GuiceFXMLLoader”,并可以使用这些特殊的FXMLLoader实例来加载您的UI定义。在您的FXML控制器类中,您可以根据需要混合@Inject和@FXML annoations →http://bit.ly/139fKQV
我的框架还提供了一系列关于“Guicified”JavaFX组件的功能,它们将Java类和单个FXML文件绑定在一起(使用特殊注释:“@ FXMLComponent”)。我写了一个简短的“计算器”示例,其源可以从Github页面获得(见上文)。代码的相关部分可以在这里找到:
CalculatorAppPane.java:→http://bit.ly/10YMVoM
CalculatorAppPane.fxml:→http://bit.ly/13loYv8
希望有所帮助。 : - )
答案 1 :(得分:1)
我将建议将Controller与 FXML 文件相关联的众多方法之一,我假设您使用的是 fx:controller FXML 文件中的标记。
为了演示目的,我将在舞台中间用一个按钮实现github上托管的演示应用。
Demo__
|___ App.java
|___ AppModule.java
|___ IController.java
|___ Controller.java
|___ InjectingFXMLLoader.java
|___ fxml
|__view.fxml
请注意我们在 FXML 文件中引用 fx:controller 中的界面,而不是实现,所以我们可以将fxml视图重用于实现该接口的其他控制器。
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<BorderPane fx:id="root" xmlns:fx="http://javafx.com/fxml" fx:controller="org.tarrsalah.stackoverflow.guice.fx.IController" >
<center>
<HBox alignment="CENTER" prefHeight="-1.0" prefWidth="-1.0">
<children>
<Button fx:id="fx_print" alignment="CENTER" contentDisplay="CENTER" defaultButton="true" mnemonicParsing="false" onAction="#printButton" text="Print !" HBox.hgrow="ALWAYS" />
</children>
<BorderPane.margin>
<Insets bottom="20.0" top="10.0" />
</BorderPane.margin>
</HBox>
</center>
</BorderPane>
控制器必须实现的界面,printButton()
将消息打印到屏幕,getRoot()
以获取Panel View。
import javafx.fxml.Initializable;
import javafx.scene.Parent;
public interface IController extends Initializable {
public void printButton();
public Parent getRoot();
}
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.Parent;
public class Controller implements IController {
@FXML
Parent root;
public void initialize(URL url, ResourceBundle rb) {
}
public Parent getRoot() {
return root;
}
public void printButton() {
System.out.println("Hello Guice !!");
}
}
一个带有一个静态方法的类,它可以获得控制器的具体实现 FXML 文件的网址,并返回视图的控制器。
import java.io.IOException;
import java.net.URL;
import javafx.fxml.FXMLLoader;
import javafx.util.Callback;
public class InjectingFXMLLoader {
/**
*
* @param <N>
* @param injector
* @return a controller injected within an FXML.
*/
public static <N> N loadFXMLController(final N controller, URL url) throws IOException {
FXMLLoader loader= new FXMLLoader();
loader.setLocation(url);
loader.setControllerFactory(new Callback<Class<?>, Object>() {
public Object call(Class<?> p) {
return controller;
}
});
loader.load();
return loader.getController();
}
}
在guice模块中,我们使用InjectingFXMLLoader类将控制器的具体实现与相应的 FXML 文件相关联。使用@Provides方法。
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import java.io.IOException;
public class AppModule extends AbstractModule {
@Override
protected void configure() {
}
/**
*
* @return IController
* @throws IOException
*/
@Provides
public IController getIController() throws IOException {
return InjectingFXMLLoader.loadFXMLController(new Controller(), getClass().getClassLoader().getResource("fxml/view.fxml"));
}
}
显示视图的主要类
import com.google.inject.Guice;
import javafx.application.Application;
import javafx.scene.SceneBuilder;
import javafx.stage.Stage;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(SceneBuilder
.create()
.root(Guice.createInjector(new AppModule()).getInstance(IController.class).getRoot())
.height(160)
.width(200)
.build());
stage.show();
}
}