Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "automatic injection of location and resources properties into the controller" in JavaFX?

In the description of Initializable interface it is said:

NOTE This interface has been superseded by automatic injection of location and resources properties into the controller. FXMLLoader will now automatically call any suitably annotated no-arg initialize() method defined by the controller. It is recommended that the injection approach be used whenever possible.

The question is: how to "suitable annotate" methods? I find only one annotation -- @FXML. Are there any others?

like image 224
Suzan Cioc Avatar asked Nov 20 '13 21:11

Suzan Cioc


1 Answers

The answer is located here:

In JavaFX 2.1 and earlier, controller classes were required to implement the Initializable interface to be notified when the contents of the associated FXML document had been completely loaded. In JavaFX 2.2, this is no longer necessary. An instance of the FXMLLoader class simply looks for the initialize() method on the controller and calls it, if available. Note that, similar to other FXML callback methods such as event handlers, this method must be annotated with the @FXML annotation if it is not public.

It is recommended that developers use this approach for new development. The Initializable interface has not been deprecated, but might be in a future release.

EDIT

After more research, I can now now provide an SSCCE demonstrating how to inject a resource bundle into a controller with annotations. Please note that this SSCCE contains slight modifications from the answer to this SO question.

Here is the SSCCE:

com/stackexchange/stackoverflow/_20107463/MyController.java:

package com.stackexchange.stackoverflow._20107463;

import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class MyController {

  @FXML 
  private Label label;

  @FXML private ResourceBundle resources;

  @FXML
  private void initialize() {
    label.setText(resources.getString("key1"));
  }

  // Or if you don't want to use @FXML you could do:
  //public void initialize() {
  //  label.setText(resources.getString("key1"));
  //}
}

com/stackexchange/stackoverflow/_20107463/MyView.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.*?>

<BorderPane fx:controller="com.stackexchange.stackoverflow._20107463.MyController" xmlns:fx="http://javafx.com/fxml">
  <top>
    <!-- This label's text will be set by the controller -->
    <Label fx:id="label"/>
  </top>
  <center>
    <!-- This label's text will be taken from the bundle automatically -->
    <Label text="%key2"/>
  </center>
</BorderPane>

com/stackexchange/stackoverflow/_20107463/BundleDemo.java:

package com.stackexchange.stackoverflow._20107463;

import java.io.IOException;
import java.util.Locale;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBoxBuilder;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class BundleDemo extends Application {

  private Stage stage;

  @Override
  public void start(Stage primaryStage) {
    stage = primaryStage;
    Button btnEN = new Button();
    btnEN.setText("English");
    btnEN.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        loadView(new Locale("en", "EN"));
      }
    });

    Button btnKG = new Button();
    btnKG.setText("Español");
    btnKG.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        loadView(new Locale("es", "ES"));
      }
    });

    VBox root = new VBox(20);
    root.getChildren().add(HBoxBuilder.create().spacing(10).style("-fx-background-color: gray").padding(new Insets(5)).children(btnEN, btnKG).build());
    root.getChildren().add(new StackPane());
    primaryStage.setScene(new Scene(root, 300, 250));
    primaryStage.show();
  }

  private void loadView(Locale locale) {
    try {
      FXMLLoader fxmlLoader = new FXMLLoader();

      fxmlLoader.setResources(ResourceBundle.getBundle("com.stackexchange.stackoverflow.bundles.MyBundle", locale));
      Pane pane = (BorderPane) fxmlLoader.load(this.getClass().getResource("MyView.fxml").openStream());
      // replace the content
      StackPane content = (StackPane) ((VBox) stage.getScene().getRoot()).getChildren().get(1);
      content.getChildren().clear();
      content.getChildren().add(pane);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  public static void main(String[] args) {
    launch(args);
  }
}

com/stackexchange/stackoverflow/_20107463/MyBundle_en.properties:

key1=Name Surname
key2=How are you?

com/stackexchange/stackoverflow/_20107463/MyBundle_es.properties:

key1=Apellido
key2=Que tal?
like image 176
axiopisty Avatar answered Oct 15 '22 15:10

axiopisty