【问题标题】:JavaFX can't settext() on Final TextFieldJavaFX 无法在最终文本字段上设置文本()
【发布时间】:2016-03-24 11:53:52
【问题描述】:

如果变量 TextField 设置为 final,我无法设置 TextField,但如果我将其更改为私有或公共,它会更改我的 textfiel 的文本。我认为 final 只是不允许创建另一个类实例。我尝试打印私有和最终 TextField 的 HashCode,但它们没有改变。所以我很好奇为什么我必须有私人或公共的 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());
    }
}

谢谢你的回答。

【问题讨论】:

    标签: java javafx java-8 textfield settext


    【解决方案1】:

    FXMLLoader 加载 FXML 文件时,它

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

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

    所以你的字段声明应该是

    @FXML
    TextField textfieldSelectedDirectory ;
    

    等等,(你也可以而且可能应该做这些private)。

    final 关键字仅仅意味着变量只被赋值一次。虽然这在我描述的设置中在技术上是正确的(该字段只被分配一次值,由FXMLLoader),编译器需要知道这一点才能编译代码,因为它不可能知道什么FXMLLoader 将与您的控制器类的实例有关,您不能将这些字段设为 final

    【讨论】:

    • 非常感谢。编译器让我运行它唯一不起作用的是 SetText() 或 setPromptText() 但如果我向 TextField 写一些东西,我就能获得价值。我现在清楚了,再次感谢你。但我还是很好奇为什么编译器让我运行它?
    • 您的代码可以编译,因为它遵循所有常规规则:您有final 字段,并且它们只被赋值一次。 FXMLLoader 将尝试通过反射为这些字段分配新值(因此没有编译器检查),但失败(我很惊讶没有堆栈跟踪,或者至少没有警告),因此不会重新分配字段.因此,当您调用 setText(..) 时,您是在控制器初始化程序中设置的初始文本字段上调用它,而不是在您在 FXML 中指定的那个(即不在显示的那个)上调用它。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多