JavaFX comes with the possibility to define your UI using a declarative XML-Syntax instead of writing Java code. To react on user input the XML-Syntax allows you to call back into programm code.
A simple example looks like this:
<?xml version="1.0" encoding="UTF-8"?> <!-- Do not edit this file it is generated by e(fx)clipse from /at/bestsolution/efxclipse/runtime/examples/guice/guice.fxgraph --> <?import java.lang.*?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.PasswordField?> <?import javafx.scene.control.TextField?> <?import javafx.scene.layout.AnchorPane?> <AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="at...LoginController"> <children> <Label layoutX="10" layoutY="10"> <text>Username</text> </Label> <TextField fx:id="username" layoutX="80" layoutY="10"/> <Label layoutX="10" layoutY="40"> <text>Password</text> </Label> <PasswordField fx:id="password" layoutX="80" layoutY="40"/> <Button layoutX="80" layoutY="70" onAction="#login"> <text>Login</text> </Button> <Label fx:id="message" layoutX="80" layoutY="100"/> </children> </AnchorPane>
The controller:
package at.bestsolution.efxclipse.runtime.examples.guice.controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import at.bestsolution.efxclipse.runtime.examples.guice.service.ILoginService;
import com.google.inject.Inject;
public class LoginController {
@FXML
TextField username;
@FXML
PasswordField password;
@FXML
Label message;
@FXML
public void login(ActionEvent event) {
// do the login
}
}
And load the FXML-File like this:
FXMLLoader.load(
GuiceExample.class.getResource("guice.fxml"),
null,
new JavaFXBuilderFactory()
);
If you are used to dependency injection – like I am since working on Eclipse 4 – you can’t imagine to work without it anymore and so you’d like to make guice inject an ILoginService to the controller.
package at.bestsolution.efxclipse.runtime.examples.guice.controller;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import at.bestsolution.efxclipse.runtime.examples.guice.service.ILoginService;
import com.google.inject.Inject;
public class LoginController {
@Inject
ILoginService loginService;
@FXML
TextField username;
@FXML
PasswordField password;
@FXML
Label message;
@FXML
public void login(ActionEvent event) {
try {
long id = loginService.login(username.getText(), password.getText());
message.setStyle("-fx-text-fill: green;");
message.setText("Logged in as User: " + id);
} catch (IllegalArgumentException e) {
message.setStyle("-fx-text-fill: red;");
message.setText(e.getMessage());
}
}
}
Now the question is how to make the FXMLLoader use Guice to inject stuff. The problem is that you can’t pass the loader a delegate so that you can make Guice create the controller instance which means you can’t use constructor injection but that’s a minor problem for me.
So we let the FXMLLoader construct the controller and execute the injection afterwards:
public static <N> N loadFXML(Injector injector, URL url) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(url);
loader.setBuilderFactory(new JavaFXBuilderFactory());
InputStream in = url.openStream();
N value = (N) loader.load(in);
in.close();
if( loader.getController() != null ) {
injector.injectMembers(loader.getController());
}
injectLoaders(loader, injector);
return value;
}
private static void injectLoaders(FXMLLoader parentLoader, Injector injector) {
for( FXMLLoader l : parentLoader.getIncludes() ) {
if( l.getController() != null ) {
injector.injectMembers(l.getController());
injectLoaders(l, injector);
}
}
}
I’ve packaged up the code in my runtime modules so you can make use of it quite easy. A similar implementation is available for Eclipse-DI but Eclipse-DI requires an OSGi-Runtime whereas the guice one can be used with or without OSGi.

October 7, 2011



Can you tell me as a first time Eclipse user how to install e(fx)clipse as a remote site, thanks.
I’ve added an installation guide on the github wiki
Thanks, that worked fine. I have a few more new to Eclipse questions.
In NetBeans it is possible to create JavaFX projects from templates and open samples. Is that possible in Eclipse? If not then do I start a JavaFX project with a normal Java project template and FXML with a normal XML template?
Is there a way to package the templates and samples for NetBeans and install them in in Eclipse? Maybe just importing the NetBeans JavaFX samples is just as easy?
Adding a project wizard is on my todo list for the 0.0.7 release. If I can find the time to fix some remaining CSS issues today and the wizard I’m going to release 0.0.7 today else I’m going to release it some time this week.