0

I am playing around with SceneBuilder and come across a few questions about the intialize() method and how to change ComboBox items after it's already been initialized in said method. So basically, after I set the items in initialize, I am not able to change them anymore from another method in the controller.

Here is my code:

public class AppController implements Initializable {

    private ObservableList<String> list = FXCollections.observableArrayList();
    private MainModel model;

    @FXML
    private ComboBox<String> cobUsers = new ComboBox<String>();

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        list.add("name1");
        list.add("name2");

        cobUsers.setItems(list); // this works!
    }   

    public void initModel(MainModel model) {
        this.model = model;
    }

    public void addItems(){
        list.add("name3");
        list.add("name4");

        cobUsers.setItems(list); // this does not work. ComboBox items remain "name1" and "name2"
    }
}


public class App extends Application {

    private Stage primaryStage;
    private AnchorPane rootLayout;
    private AppController appController = new AppController();
    MainModel model = new MainModel();

    @Override
    public void start(Stage primaryStage) {
        appController.initModel(model);

        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("App");

        initRootLayout();

        appController.addItems();
    }

    /**
     * Initializes the root layout.
     */
    public void initRootLayout() {
        try {
            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("FXMLDocument.fxml"));
            rootLayout = (AnchorPane) loader.load();

            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

So guess my question is, how can I access/change my ComboBox later on, after it's been initialized in intialize()?

Thanks! :)

UPDATE 1:

I have changed the initRootLayout() in the App class (see below) and it WORKS now. list now contains 4 items and all of them show up in the ComboBox after calling addItems(). Thanks everyone!

public void initRootLayout() {
        try {
            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();                loader.setLocation(getClass().getResource("FXMLDocument.fxml"));
            rootLayout = (AnchorPane) loader.load();

            AppController controller = loader.<AppController>getController();
            controller.addItems();

            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
kattapillar
  • 136
  • 12
  • because you set `cobUsers`'s `items` list to equal the ObservableList `list`, you shouldn't have to call `setItems(list)` again, adding values to `list` should add them to `cobUsers`'s `items` list. Try putting in a breakpoint before you call `setItems(list)` and check what is in `cobUsers.getItems()`, or if you don't want to use a breakpoint, print out the contents of `cobUsers.getItems()`. If all four strings are in there, then your problem may be something else. – MMAdams Jan 04 '18 at 15:10
  • 1
    I did that (printing the list items) and that is another thing I don't understand: after adding "name3" and "name4" to my list, when I print list, only "name3" and "name4" are printed. Yet the ComboBox shows "name1" and "name2". It's like it's creating a new list instead of adding to the existing list. – kattapillar Jan 04 '18 at 15:13
  • that's very odd! Are you sure you aren't changing the list from anywhere else? Is something calling list.clear()? – MMAdams Jan 04 '18 at 15:16
  • Your problem is most likely in your `app` class. Your app class structure is probably wrong. Just a guess here but you have `private AppController appController = new AppController();` and your `initRootLayout()` code. These appear to be two different objects of the same type of Controller. – SedJ601 Jan 04 '18 at 15:23
  • 2
    You need to call `addItems()` on the actual controller. `appController` is not the controller: it is just an object you created that happens to be the same class as the controller. See https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml for how to communicate with the controller. – James_D Jan 04 '18 at 15:33
  • @MMAdams nope, the code i posted is the entire code I have, plus a model class that's completely empty so far. – kattapillar Jan 04 '18 at 15:34
  • @James_D what is my actual controller/how do I call it? – kattapillar Jan 04 '18 at 15:35
  • @kattapillar See edit to previous comment. – James_D Jan 04 '18 at 15:36
  • In the link, Jame_D posted go look at the answer that starts with `This works`. – SedJ601 Jan 04 '18 at 15:37
  • Thanks guys! I'll let you know if it works :) – kattapillar Jan 04 '18 at 15:39
  • Thanks again! Everything works now. I added the changes I made to my original post in case someone else has a similar problem. – kattapillar Jan 04 '18 at 15:53

0 Answers0