JavaFX 无法在 Final TextField 上设置文本()

JavaFX can't settext() on Final TextField

如果将变量 TextField 设置为最终变量,我将无法设置 TextField,但如果我将其更改为私有或 public,它会更改我的文本字段的文本。我认为 final 只是不允许创建 class 的另一个实例。我尝试打印 private 和 final TextField 的 HashCode,但它们没有改变。所以我很好奇为什么我必须有 private 或 public TextField 到 SetText() 到它。

public class SearchController {

    @FXML
    final TextField textfieldSelectedDirectory = new TextField();
    @FXML
    private Button path;
    @FXML
    private Label pathlabel;
    @FXML
    final TextField searchfield = new TextField();

    public String getSearchfield() {

        return searchfield.getText();
    }

    private MainApp mainApp;
    private Stage stage;

    public SearchController() {

    }

    @FXML
    private void Index() {

        IndexFiles.index();

    }

    @FXML
    private void search() {

        SearchFiles().Search();
        System.out.println(searchfield.hashCode());

        System.out.println("Somtu");

        System.out.println(getSearchfield());

    }

    private void setPath(File selectedDirectory) {
        String dir = selectedDirectory.getAbsolutePath();


        pathlabel.setText(dir);

        textfieldSelectedDirectory.clear();

        // textfieldSelectedDirectory.getParent().layout();

        System.out.println(textfieldSelectedDirectory.getText());
    }
}

谢谢你的回答。

您不能将 final 变量与 FXML 注入结合使用。使用 FXML,将在调用构造函数后创建字段。所以你必须删除 new TextField() 初始化。 编译器不会让你。

FXMLLoader 加载 FXML 文件时,它

  1. 创建由 fx:controller
  2. 指定的控制器 class 的实例
  3. 创建由 FXML 文件中的元素描述的 classes 的实例(即对于 <Button> 它创建一个 Button 实例等),并设置它们的属性
  4. 对于具有 fx:id 属性的元素,在创建的控制器实例中设置相应的 @FXML 注入字段
  5. 注册事件处理程序等
  6. 在控制器上调用 initialize() 方法

由于 @FXML 字段是在 构造函数调用完成后 设置的,因此它们不能 final。此外,初始化它们是没有意义的,因为它们无论如何都将由 FXMLLoader 设置:你应该 never 初始化 @FXML-annotated 字段。

所以你的字段声明应该是

@FXML
TextField textfieldSelectedDirectory ;

等,(你也可以,也可能应该制作这些 private)。

final 关键字仅表示变量只被赋值一次。虽然这在我描述的设置中在技术上是正确的(该字段只被赋值一次,由 FXMLLoader),编译器需要知道这一点才能编译代码,并且因为它不可能知道 FXMLLoader 将如何处理您的控制器 class 的实例,您不能创建这些字段 final.