什么是“将位置和资源属性自动注入控制器"?在 JavaFX 中? [英] What is "automatic injection of location and resources properties into the controller" in JavaFX?

查看:21
本文介绍了什么是“将位置和资源属性自动注入控制器"?在 JavaFX 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Initializable的说明中界面是这样说的:

In the description of Initializable interface it is said:

注意此接口已被自动注入location 和 resources 属性到控制器中.FXMLLoader 将现在自动调用任何适当注释的无参数 initialize()控制器定义的方法.建议注射尽可能使用方法.

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.

问题是:如何合适的注释"方法?我只找到一个注释——@FXML.还有其他的吗?

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

推荐答案

答案是位于此处:

在 JavaFX 2.1 及更早版本中,控制器类需要实现 Initializable 接口,当内容发生时通知的关联 FXML 文档已完全加载.在 JavaFX 中2.2,这个已经没有必要了.FXMLLoader 类的一个实例只是在控制器上查找 initialize() 方法并调用它,如果可用.请注意,类似于其他 FXML 回调方法例如事件处理程序,此方法必须使用@FXML 进行注释如果不公开,则注释.

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.

建议开发者使用这种方式进行新的发展.Initializable 接口尚未被弃用,但可能会在未来的版本中发布.

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.

编辑

经过更多研究,我现在可以提供一个 SSCCE 演示如何将资源包注入带有注释的控制器.请注意,此 SSCCE 包含对此 SO 问题的回答的轻微修改.

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.

这是 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?

这篇关于什么是“将位置和资源属性自动注入控制器"?在 JavaFX 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆