DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Introducing SmallRye LLM: Injecting Langchain4J AI Services
  • Injecting Implementations With Jakarta CDI Using Polymorphism
  • Evolution of Recommendation Systems: From Legacy Rules Engines to Machine Learning
  • Okta + SAML + JBoss EAP 6.4.x + Picketlink

Trending

  • How to Format Articles for DZone
  • My LLM Journey as a Software Engineer Exploring a New Domain
  • Microsoft Azure Synapse Analytics: Scaling Hurdles and Limitations
  • AI, ML, and Data Science: Shaping the Future of Automation
  1. DZone
  2. Coding
  3. Java
  4. FXML & JavaFX—Fueled by CDI & JBoss Weld

FXML & JavaFX—Fueled by CDI & JBoss Weld

By 
Matthieu Brouillard user avatar
Matthieu Brouillard
·
Aug. 07, 12 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
15.5K Views

Join the DZone community and get the full member experience.

Join For Free

It has been a while since I wanted to have CDI running with JavaFX2.
Some people already blogged on how to proceed by getting Guice injection [1] to work with JavaFX & FXML.

Well, now it's my turn to provide a way to empower JavaFX with CDI, using Weld as the implementation.

My goal was just to have CDI working, no matter how I was using JavaFX, by directly coding in plain Java or using FXML.

Ready? Let's go!!!

Bootstrap JavaFX & Weld/CDI

The launcher class will be the only place where we will have Weld-specific code—all the rest will be totally CDI compliant.

The only trick here is to make the application parameters available as a CDI-compliant object so we can reuse them afterwards.

Notice also that we use the CDI event mechanism to start up our real application code.

public class WeldJavaFXLauncher extends Application {
  /**
  * Nothing special, we just use the JavaFX Application methods to boostrap
  * JavaFX
  */
  public static void main(String[] args) {
    Application.launch(WeldJavaFXLauncher.class, args);
  }

  @SuppressWarnings("serial")
  @Override
  public void start(final Stage primaryStage) throws Exception {
    // Let's initialize CDI/Weld.
    WeldContainer weldContainer = new Weld().initialize();
    // Make the application parameters injectable with a standard CDI
    // annotation
    weldContainer.instance().select(ApplicationParametersProvider.class).get().setParameters(getParameters());
    // Now that JavaFX thread is ready
    // let's inform whoever cares using standard CDI notification mechanism:
    // CDI events
    weldContainer.event().select(Stage.class, new AnnotationLiteral<StartupScene>() {}).fire(primaryStage);
  }
}

 

Start our real JavaFX application

Here we start our real application code. We're just listening to the previously fired event (containing the Scene object to render into) so we can start showing our application.

In the following example, we load an FXML GUI, but it might have been any node created in any way.

public class LoginApplicationStarter {
  // Let's have a FXMLLoader injected automatically
 @Inject FXMLLoader fxmlLoader;

  // Our CDI entry point, we just listen to an event providing the startup scene
 public void launchJavaFXApplication(@Observes @StartupScene Stage s) {
  InputStream is = null;

  try {
   is = getClass().getResourceAsStream("login.fxml");
   // we just load our FXML form (including controler and so on)
   Parent root = (Parent) fxmlLoader.load(is);
   s.setScene(new Scene(root, 300, 275));
   s.show(); // let's show the scene
  } catch (IOException e) {
   throw new IllegalStateException("cannot load FXML login screen", e);
  } finally {
      // omitted is cleanup
  }
 }
}

 

But what about the FXML controller?

First let's have a look at the controller we want to use inside our application.

It is a pure POJO class annotated with both JavaFX & CDI annotations.

// Simple application controller that uses injected fields
// to delegate login process and to get default values from the command line using: --user=SomeUser
public class LoginController implements Initializable {
    // Standard FXML injected fields
 @FXML TextField loginField;
 @FXML PasswordField passwordField;
 @FXML Text feedback;

 // CDI Injected service
 @Inject LoginService loginService;

    // Default application parameters retrieved using CDI
 @Inject Parameters applicationParameters;

 @FXML protected void handleSubmitButtonAction(ActionEvent event) {
  feedback.setText(loginService.login(loginField.getText(), passwordField.getText()));
 }

 @Override
 public void initialize(URL location, ResourceBundle resources) {
  loginField.setText(applicationParameters.getNamed().get("user"));
 }
}

In order to have injection working inside the FXML controller, we need to set up JavaFX so that controller objects are created by CDI.

As we are in a CDI environment we can also have the FXMLLoader classes injected (that's exactly what we did in the previous LoginApplicationStarter class).

How can we achieve this?

We just have to provide a Producer class whose responsibility will be to create FXMLLoader instances that are able to load FXML GUIs and instantiate controllers using CDI.

The only part that's a little tricky there is that the controller instantiation depends on the required class or interface (using fx:controller in your fxml file). In order to have such a runtime injection/resolution available we use a CDI Instance Object.

public class FXMLLoaderProducer {
 @Inject Instance<Object> instance;

 @Produces
 public FXMLLoader createLoader() {
  FXMLLoader loader = new FXMLLoader();
  loader.setControllerFactory(new Callback<Class<?>, Object>() {
   @Override
   public Object call(Class<?> param) {
    return instance.select(param).get();
   }
  });
  return loader;
 }
}

I hope you found the article interesting and you do not hesitate to comment if you see some errors or possible enhancements.

Finally, if you are interested you can find the full source code here.

[1] http://andrewtill.blogspot.be/2012/07/creating-javafx-controllers-using-guice.htm

CDI JBoss

Opinions expressed by DZone contributors are their own.

Related

  • Introducing SmallRye LLM: Injecting Langchain4J AI Services
  • Injecting Implementations With Jakarta CDI Using Polymorphism
  • Evolution of Recommendation Systems: From Legacy Rules Engines to Machine Learning
  • Okta + SAML + JBoss EAP 6.4.x + Picketlink

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!