JavaFX can't settext() on Final TextField

I'm unable to set TextField if variable TextField is set as final but if i change it to private or public it changes text of my textfiel. I thought that final just don't allow create another instance of class. I tried print HashCode of both private and final TextField but they was not changing. So im curious why i have to have private or public TextField to SetText() to it.

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());
    }
}

Thank's you for answers.

Upvotes: 1

Views: 2063

Answers (2)

James_D
James_D

Reputation: 209330

When an FXMLLoader loads an FXML file, it

  1. Creates an instance of the controller class specified by fx:controller
  2. Creates instances of the classes described by the elements in the FXML file (i.e. for <Button> it creates a Button instance, etc), and sets their properties
  3. For elements with a fx:id attributes, sets the corresponding @FXML-injected field in the controller instance that was created
  4. Registers event handlers, etc.
  5. Calls the initialize() method on the controller

Since the @FXML fields are set after the constructor call has completed, they cannot be final. Additionally, it doesn't make sense to initialize them since they are going to be set by the FXMLLoader anyway: you should never initialize @FXML-annotated fields.

So your field declarations should be

@FXML
TextField textfieldSelectedDirectory ;

etc, (and you can, and probably should, make these private too).

The final keyword simply means that the variable is assigned a value exactly once. While this is technically true in the set up I describe (the field is only ever assigned a value once, by the FXMLLoader), the compiler needs to know this in order for the code to compile, and since it cannot possibly know what the FXMLLoader is going to do with instances of your controller class, you cannot make these fields final.

Upvotes: 2

Moh-Aw
Moh-Aw

Reputation: 3018

You cannot use final variables in combination with FXML injection. With FXML the fields will be created after the call of the constructor. So you would have to remove the new TextField() initialization. The compiler won't let you though.

Upvotes: 0

Related Questions