Illustration einer tropischen Insel mit Palmen und einem hohen Berg

Java Blog für Programmierer

JavaFX + CDI (Weld)

· Christian Ullenboom

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.

Kategorien: JavaFX, CDI, Weld

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.

← Alle Beiträge