I will suggest one of many approaches to associate a Controller to an FXML file, I will suppose that you are using the fx:controller tag in your FXML file.
for the demonstration purpose, I will implement a demo app hosted on github with one button in the middle of the stage.

Demo__
|___ App.java
|___ AppModule.java
|___ IController.java
|___ Controller.java
|___ InjectingFXMLLoader.java
|___ fxml
|__view.fxml
View.fxml
note that we refer to the interface in the fx:controller in the FXML file, and not to the implementation, so we can reuse the fxml view with other controllers implementing the interface.
<?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>
IController
an interface that the controller must implement , the printButton()
to print a message to the screen , and getRoot()
to get the Panel View.
import javafx.fxml.Initializable;
import javafx.scene.Parent;
public interface IController extends Initializable {
public void printButton();
public Parent getRoot();
}
Controller
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 !!");
}
}
InjectingFXMLLoader
a class with one static method that get a concrete implementation of a controller and
URL of the FXML file and return the controller of the view.
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();
}
}
AppModule
in the guice module , we use the InjectingFXMLLoader class to associate a concrete implementation of the controller with the corresponding FXML file. using a @Provides method.
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"));
}
}
App
the main class that show the view
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();
}
}