yahzee
yahzee

Reputation: 25

Add data to static ComboBox in JavaFX 2.2

I just can't figure out how to add data to static ComboBox in JavaFX 2.2. Whatever I try to do ComboBox is empty. Here is the code:

@FXML private MenuItem menuItemNewTile;
@FXML private static ComboBox<Tile> comboBoxTileList;

@FXML
private void menuItemNewTileSetOnAction(ActionEvent event) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource(TILE_WINDOW_URL));
    Scene scene = new Scene(root);

    Stage tileStage = new Stage();
    tileStage.setScene(scene);
    tileStage.show();
}

@FXML
private void comboBoxTileListSetOnAction(ActionEvent event) {

}

@Override
public void initialize(URL arg0, ResourceBundle arg1) {
    comboBoxTileList = new ComboBox<>();
}

public static void refreshTileList(Tile tile) {
    comboBoxTileList.getItems().add(tile);
}

If ComboBox is private, and I add item in initialize method it's working, but with static ComboBox I tried million things and still no progress.

Upvotes: 0

Views: 888

Answers (1)

jewelsea
jewelsea

Reputation: 159341

Solution

Don't use static and @FXML together.

Rework your design so that the static keyword is no longer required for the comboBoxTileList and use an instance variable instead.

Additional Issue

An @FXML member such as comboBoxTileList should never be set to a new value, so you should not have comboBoxTileList = new ComboBox<>();

Answer to additional questions

I use another window to create new Tile object and from controller class of that window i call refreshTileList method. How to do that without using static?

There are numerous ways of writing your code so that you don't need a static reference to controller members. Here is a sample based on a solution from: Passing Parameters JavaFX FXML. You will need to modify the example to fit your exact case, it's just presented to demonstrate a possible pattern that you could use.

You can construct a new controller in code, passing any parameters you want from your caller into the controller constructor. Once you have constructed a controller, you can set it on an FXMLLoader instance before you invoke the load() instance method.

To set a controller on a loader (in JavaFX 2.x) you CANNOT also define a fx:controller attribute in your fxml file.

class ComboController {
    @FXML private static ComboBox<Tile> comboBoxTileList;

    public void refreshTileList(Tile tile) {
        comboBoxTileList.getItems().add(tile);
    }
}

class AnotherController {
    @FXML private Button createTile;
    @FXML private Button newCombo;
    @FXML private StackPane mainPane;

    private comboController;

    @FXML private void createTile(ActionEvent event) {
        if (comboController == null) {
            return;
        }

        comboController.refreshTileList(
            new Tile()
        );
    }

    @FXML private void newCombo(ActionEvent event) {
        try {
            comboController = new ComboController();

            FXMLLoader loader = new FXMLLoader(
                getClass().getResource(
                    "combo.fxml"
                )
            );
            loader.setController(comboController);

            Pane comboPane = (Pane) loader.load();

            mainPane.getChildren().setAll(comboPane);
        } catch (IOException e) {
            // handle exception. 
        }
    }
}

Upvotes: 1

Related Questions