【问题标题】:Is @FXML needed for every declaration?每个声明都需要@FXML 吗?
【发布时间】:2022-01-08 10:21:09
【问题描述】:

每个声明都需要@FXML 还是只需要第一个声明?

换句话说,我应该使用

@FXML
public Label timerLabel = new Label();
@FXML
public TextField mainTextField, projectTextField ;
@FXML
public Button goButton, deleteAllButton ;
@FXML
public ComboBox<String> projectComboBox ;
@FXML
public TableView<Entry> mainTable ;
@FXML
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ;
@FXML
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ;
@FXML
public checkBox checkAllCheckBox ;

或者

@FXML
public Label timerLabel = new Label();
public TextField mainTextField, projectTextField ;
public Button goButton, deleteAllButton ;
public ComboBox<String> projectComboBox ;
public TableView<Entry> mainTable ;
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ;
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ;
public checkBox checkAllCheckBox ;

谢谢!

【问题讨论】:

  • 两个都试试 ;)
  • @Romeo 需要指出的是,@FXML 注释的您的声明 public Label timerLabel = new Label(); 是不正确的。带有@FXML注解的引用在fxml加载时初始化,不应在外部初始化。
  • “初始化 timerLabel”是什么意思?如果 timerLabel 引用定义带有 @FXML 注释,则永远不要写 timerLabel = new TimerLabel()
  • 如果您的字段为public,则实际上不需要任何@FXML 注释。当然,无论如何,您都不应该将这些字段设为public;您应该将它们设为private,在这种情况下,所有@FXML 注释都是必需的。但是对于现在的代码,省略注释不会有任何区别。
  • 我认为是时候让 FXMLLoader 在加载时记录错误或警告 @FXML 注释字段是否已经实例化。或者在 setController() 中使用实例化的。

标签: javafx fxml fxmlloader


【解决方案1】:
@FXML
private TextField idTextField;

@FXML
private TextField passwordTextField;

@FXML
private TextField idTextField, passwordTextField;

【讨论】:

    【解决方案2】:

    @FXML 注释使FXMLLoader 能够将 FXML 文件中定义的值注入到控制器类中的引用中。换句话说,如果你用@FXML注释你的timerLabel,那么当FXML文件中的一个元素用fx:id="timerLabel"调用load()方法时,它将被FXMLLoader初始化。正如其他人在 cmets 中指出的那样,这意味着您永远不应该编写类似

    的代码
    @FXML
    private Label timerLabel = new Label();
    

    这里的timerLabel 将首先初始化为您在代码中创建的new Label();,然后几乎立即重新初始化为 FXML 文件中定义的值。这充其量是多余的,最坏的情况是误导。如果您没有将变量名正确匹配到fx:id,您的变量将引用错误的Label,并且该错误将很难追踪。

    要回答您的实际问题:

    FXMLLoader 加载FXML 文件时,它会尝试将任何具有fx:id 属性的元素注入到控制器中。它会寻找

    1. 具有与fx:id 属性匹配的变量名称的任何public 字段,
    2. 任何字段(public 或不),其变量名称与带有@FXML 注释的fx:id 属性匹配。

    因此,在您的示例中,由于您的所有字段都是 public,因此您可以省略所有 @FXML 注释(即使是第一个),它仍然可以工作。

    但是,如果您遵循良好做法并将字段设为 private,则必须为每个声明添加注释 @FXML 才能使注入工作。

    所以

    @FXML
    private Label timerLabel;
    @FXML
    private TextField mainTextField;
    

    等会起作用,但是

    @FXML
    private Label timerLabel;
    private TextField mainTextField;
    

    不会。

    【讨论】:

    • 需要注射吗?有没有办法只向加载程序询问我感兴趣的控件(通过 fx:id)?
    • 不确定我是否理解这个问题。这不正是注射的作用吗?
    【解决方案3】:

    每个

    fx:id="somename"
    

    你需要一个

    @FXML
    public SomeClass somename;
    

    我更喜欢用一行写,因为多行更容易阅读

    @FXML public SomeClass somename;
    

    没有初始化

    @FXML
    public Label timerLabel = new Label(); // this is wrong
    

    【讨论】:

    • timerLabel = new Label(); 不会被 FXMLLoader 覆盖吗?
    • 此答案具有误导性,因为当字段为公共时,不需要 @FXML。所以public SomeClass somename; 没有@FXML 也可以工作,但是当somename 不是public 例如@FXML private SomeClass somename; 时你需要它。
    猜你喜欢
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多