API updates for FXBeanInfo

We had some great discussions at JavaFX Days Zurich about our new FXBeanInfo API, and we decided to take this valuable feedback from the JavaFX community to improve our API.

So today we’re proud to present version 0.4 of the FXBeanInfo API:

<dependency>
  <groupId>com.dukescript.api</groupId>
  <artifactId>javafx.beaninfo</artifactId>
  <version>0.4</version>
</dependency>

The main point of critizism was how EventHandlers are registered.

So far with FXBeanInfo you would register actions like this:

class HTMLController implements FXBeanInfo.Provider {

    private final StringProperty labelText = new SimpleStringProperty(this, "labelText", "");
    private final Property<EventHandler<ActionEvent>> action =
            new SimpleObjectProperty<EventHandler<ActionEvent>>(
                    this, "action",
                    (e) -> labelText.set("Hello World!"));
    
    private final FXBeanInfo info = FXBeanInfo
            .newBuilder(this)
            .action(action)
            .property(labelText)
            .build();
    
    @Override
    public FXBeanInfo getFXBeanInfo() {
        return info;
    }

}

While this works great and isn’t overly verbose, it requires some complex generics in the API, and it felt very different from the way JavaFX users usually implement actions for FXML, where you annotate a simple method to expose it as a callable action:

class FXMLController{

   @FXML
   public Label label;

   @FXML
   public void buttonClick(ActionEvent evt){
        label.setText("Button clicked");
   }
}

Our enhanced API now allows you to use method handles for registering actions. Since we’re not using reflection, there’s no need for a marker Annotation:

class HTMLController implements FXBeanInfo.Provider {

    private final StringProperty labelText = new SimpleStringProperty(this, "labelText", "");
    
    public void buttonClick(ActionEvent evt){
        labelText.setValue("Button clicked");
    }
    
    private final FXBeanInfo info = FXBeanInfo
            .newBuilder(this)
            .action("buttonClick", this::buttonClick)
            .property(labelText)
            .build();
    
    @Override
    public FXBeanInfo getFXBeanInfo() {
        return info;
    }

}

This reduces the boilerplate code around a simple action call and makes the code a lot cleaner. Thanks to the JavaFX community for the feedback! We’re looking forward to more input to make our API even more useful.

Use it

You’re free to use this library on it’s own, in order to provide a BeanInfo in your own framework, or as we use it, in conjunction with DukeScript. The project on github contains two demo projects. One for embedding a HTML UI in a JavaFX application, and one for using only an HTML UI with JavaFX properties.