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

前端 未结 1 541
遥遥无期
遥遥无期 2021-02-14 18:06

In the description of Initializable interface it is said:

NOTE This interface has been superseded by automatic injection of location and resources prope

相关标签:
1条回答
  • 2021-02-14 18:32

    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?
    
    0 讨论(0)
提交回复
热议问题