JavaFX + CDI (Weld)
Put in the class path:
The challenge is to bring FXMLLoader and CDI together, because JavaFX is creating naked objects by itself, now they have to be „CDI-aware“.
package tutego.fx;
import java.nio.charset.*;
import javafx.fxml.FXMLLoader;
import javafx.util.Callback;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
public class FXMLLoaderProducer
{
@Inject
Instance instance;
@Produces
public FXMLLoader createLoader()
{
return new FXMLLoader( null, null, null, new Callback
In the FXML-file there is a reference to the FX Controller. JavaFX has to load it and can make the injections with the help of our very first class. A regular service is getting injected into the controller:
package tutego.fx;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javax.inject.Inject;
public class RandomController
{
@FXML
private Label label;
@Inject
private RandomService randomService;
@FXML
public void onButtonClick()
{
label.setText( "Random " + randomService.nextInt() );
}
}
The service itself is a simple singleton:
package tutego.fx;
import java.util.Random;
import javax.inject.Singleton;
@Singleton
public class RandomService
{
private Random rnd = new Random();
public int nextInt()
{
return rnd.nextInt();
}
}
Thats it!
PS: When you start, dont forget to put a (even blank) beans.xml in META-INF.
2 Kommentare
Brian Mooney ·
Nice article. Helped me a lot to get a small app that I am working on bootstrapped. Just one point for anyone that may hit the same issue as myself. I wanted to load the FXML files via a URL. Unfortunately the load(URL) on FXMLLoader is a static (which internally creates a new FXMLLoader anyways which defeats the purpose). So to avoid having to have InputStreams in my code, you can use two isntance methods, setLocation(URL url) and load(): ```java @Inject private FXMLLoader fxmlLoader; @Inject private ResourceAccessor resourceAccessor; public void start(Stage primaryStage) throws IOException { fxmlLoader.setLocation(resourceAccessor .getResource(ResourceAccessor.FXML_LANDING_PAGE)); Parent root = (Parent) fxmlLoader.load(); Scene scene = new Scene(root, 400, 400); scene.getStylesheets().add( resourceAccessor.getResource(ResourceAccessor.CSS_APP) .toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); } ```
Oliver Welter ·
Thanks for the article, it helps a lot! I stumbled over an issue with the shown code if I try to load an fxml file which references stylesheets via ... ... In this case I got an NoSuchMethodException for java.net.URL.() . This can be solved by handing over an instance of JavaFXBuilderFactory when creating the FXMLLoader in FXMLLoaderProducer.java : import java.nio.charset.StandardCharsets; import javafx.fxml.FXMLLoader; import javafx.fxml.JavaFXBuilderFactory; import javafx.util.Callback; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Produces; import javax.inject.Inject; public class FXMLLoaderProducer { @Inject Instance instance; @Produces public FXMLLoader createLoader() { return new FXMLLoader(null, null, new JavaFXBuilderFactory(), new Callback<Class, Object>() { @Override public Object call(Class param) { return instance.select(param).get(); } }, StandardCharsets.UTF\_8); } }
Die bisherigen Kommentare wurden aus WordPress übernommen. Neue Kommentare sind derzeit geschlossen.