1

So, I was making a menu in FXML and I was using a Group so I had to set a prefWidth otherwise it'd look weird. To do that, I wanted to initialize a variable with the screen width in the controller, and then use the width variable while setting up the menu in FXML. But I just couldn't find a way to do that.

Generalizing this problem, I want to initialize a variable in a controller and then use it in FXML like this:

[Controller]

package sample;

import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {
    @Override
    public void initialize (URL url, ResourceBundle resourceBundle) {
        String text = "test";
    }
}

[FXML]

<?import javafx.scene.control.Label?>
<?import javafx.scene.BorderPane?>

<BorderPane>
    <center>
        <label text="<!--use var 'text' here-->"/>
    </center>
</BorderPane>

I know, there are other ways to do it (like id-ing it and setting the text in the controller) but I just wanna see if it is possible to do it this way.

mathguy
  • 19
  • 2
  • 1
    This question does not make sense. It makes me think you don't have a true understanding of what's going on when you create nodes using `FXML` and how `FXML` and the code relates. It would probably be best if you describe your problem in detail and not try to get help on your proposed solution to the problem. – SedJ601 May 31 '19 at 13:36
  • 1
    You can add a `ResourceBundle` when loading the fxml. This allows you to use strings defined in the bundle via `text="%key"`. To specify variables other than strings would be rather difficult. I strongly recommend going with one of the approaches presented here: https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml Note though that the `initialize` method runs ***after*** all the nodes specified in the fxml file are created... – fabian May 31 '19 at 13:43
  • Could you post the code showing your menu width problem? Also, explain in detail what the problem is and what you are trying to achieve. See: [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – SedJ601 May 31 '19 at 14:18

3 Answers3

1

Instead of a variable use a property. Place it at the class level.

public class Controller implements Initializable {

    private String text; // or use binding property

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        text = "hello";
    }
}

FXML

<BorderPane fx:controller="sample.Controller"
            xmlns:fx="http://javafx.com/fxml">

    <center>
        <Label text="${controller.text}"/>

    </center>
</BorderPane>
sproketboy
  • 8,967
  • 18
  • 65
  • 95
1

FXMLLoader can bind a property in FXML to another in the controller. So you can define a property in the controller and access it FXML using its name.

Controller:

public class Controller implements Initializable {
    private StringProperty title = new SimpleStringProperty(this, "title", "");
    public final StringProperty titleProperty() {
        return title;
    }

    public final void setTitle(String value) { 
        titleProperty().setValue(value); 
    }

    public final String getTitle() { 
        return title.getValue(); 
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        setTitle("test");
    }
}

FXML:

<BorderPane>
    <center>
        <label text="${controller.title}"/>
    </center>
</BorderPane>

Note that in order for FXMLLoader to create the binding, a property should have mutators and accessor like in the example.

Miss Chanandler Bong
  • 4,081
  • 10
  • 26
  • 36
0

Try with a binding.

First, put an id to the label:

<Label fx:id="label" />

Then, declare it in the Controller of the view:

@FXML
private Label label;

Now you must create a StringProperty for your variable:

private final StringProperty text = new SimpleStringProperty();

And finally, add the binding:

label.textProperty().bind(text);
text.set("test");