blgrnboy
blgrnboy

Reputation: 5157

JavaFX FXML - Add choices to choice box

I am having a very tough time finding any documentation, so sorry in advance for the dumb question. I would like to populate a choice box that's declared with FXML with items that that are part of an ArrayList.

Here is my FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?>

<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="application.LMUController">   <columnConstraints>
    <ColumnConstraints hgrow="SOMETIMES" maxWidth="600.0" minWidth="10.0" prefWidth="551.0" />   </columnConstraints>   <rowConstraints>
    <RowConstraints maxHeight="346.0" minHeight="10.0" prefHeight="222.0" vgrow="SOMETIMES" />
    <RowConstraints maxHeight="316.0" minHeight="10.0" prefHeight="178.0" vgrow="SOMETIMES" />   </rowConstraints>    <children>
      <GridPane>
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="312.0" minWidth="0.0" prefWidth="0.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="443.0" minWidth="10.0" prefWidth="443.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" valignment="CENTER" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label contentDisplay="TOP" text="List Price" GridPane.halignment="RIGHT" GridPane.rowIndex="3">
               <GridPane.margin>
                  <Insets right="8.0" />
               </GridPane.margin>
            </Label>
            <Label contentDisplay="TOP" text="City" GridPane.halignment="RIGHT" GridPane.rowIndex="2">
               <GridPane.margin>
                  <Insets right="8.0" />
               </GridPane.margin>
            </Label>
            <Label contentDisplay="TOP" text="Address" GridPane.halignment="RIGHT" GridPane.rowIndex="1">
               <GridPane.margin>
                  <Insets right="8.0" />
               </GridPane.margin>
            </Label>
            <Label contentDisplay="TOP" text="Comps CSV" GridPane.halignment="RIGHT" GridPane.rowIndex="4">
               <GridPane.margin>
                  <Insets right="8.0" />
               </GridPane.margin>
            </Label>
            <FlowPane GridPane.columnIndex="1" GridPane.rowIndex="1">
               <children>
                  <TextField prefWidth="308.0" />
               </children>
            </FlowPane>
            <FlowPane GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
               <children>
                  <ChoiceBox id="choiceCity" prefWidth="150.0">
                     <FlowPane.margin>
                        <Insets right="8.0" />
                     </FlowPane.margin>
                  </ChoiceBox>
                  <Button id="btnCitiesRefresh" mnemonicParsing="false" text="Refresh" onAction="#btnCitiesRefresh_action">
                     <FlowPane.margin>
                        <Insets right="8.0" />
                     </FlowPane.margin>
                  </Button>
                  <Button id="btnLmuPreview" mnemonicParsing="false" text="Preview" />
               </children>
            </FlowPane>
            <FlowPane GridPane.columnIndex="1" GridPane.rowIndex="3">
               <children>
                  <TextField id="btnListPrice" prefWidth="150.0" />
               </children>
            </FlowPane>
            <FlowPane prefHeight="62.0" prefWidth="279.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
               <children>
                  <TextField id="txtCompsCSVPath" editable="false" prefWidth="200.0">
                     <FlowPane.margin>
                        <Insets right="8.0" />
                     </FlowPane.margin>
                  </TextField>
                  <Button id="btnCompsCSVBrowse" mnemonicParsing="false" text="Browse" />
               </children>
            </FlowPane>
         </children>
      </GridPane>
      <GridPane GridPane.halignment="LEFT" GridPane.rowIndex="1">
         <GridPane.margin>
            <Insets right="8.0" />
         </GridPane.margin>
         <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints maxHeight="91.0" minHeight="10.0" prefHeight="89.0" vgrow="SOMETIMES" />
            <RowConstraints maxHeight="61.0" minHeight="10.0" prefHeight="39.0" vgrow="SOMETIMES" />
         </rowConstraints>
         <children>
            <FlowPane prefHeight="43.0" prefWidth="592.0" GridPane.rowIndex="1" GridPane.valignment="CENTER">
               <children>
                <Button id="btnSaveExcel" mnemonicParsing="false" text="Export to Excel">
                     <FlowPane.margin>
                        <Insets left="8.0" />
                     </FlowPane.margin>
                  </Button>
               </children>
            </FlowPane>
         </children>
      </GridPane>    </children> </GridPane>

Here is my controller:

package application;

import java.awt.Choice;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.MenuBar;
import javafx.scene.input.InputEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import localMarketUpdate.*;

public class LMUController implements Initializable{

    LMUParser lmuParser;
    ChoiceBox choiceCity;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        lmuParser = new LMUParser();

    }

    @FXML
    private void btnCitiesRefresh_action(ActionEvent event)
    {
        ArrayList<String> cities = lmuParser.getCities();
        ObservableList<String> list = FXCollections.observableArrayList(cities);


        for (int i = 0; i < cities.size(); i++){

            list.add(i, cities.get(i));
            //list.add(i, cities.get(i));

        }

        choiceCity.setItems(FXCollections.observableArrayList("One","Two","Three"));
    }

}

I am getting an error on the line:

choiceCity.setItems(FXCollections.observableArrayList("One","Two","Three"));

Caused by: java.lang.NullPointerException at application.LMUController.btnCitiesRefresh_action(LMUController.java:47) ... 58 more

The ultimate goal here is to have the ChoiceBox by populated with the items in the ArrayList. How is this accomplished, and what am I doing wrong?

Upvotes: 2

Views: 7536

Answers (1)

fabian
fabian

Reputation: 82461

It should be done like this:

ArrayList<String> cities = lmuParser.getCities();
ObservableList<String> list = FXCollections.observableArrayList(cities);
choiceCity.setItems(list);

However for this to work the ChoiceBox actually has to be injected, which is not happening since you use the id attribute that assigns the Node's id property instead of using the id attribute from the fxml namespace. Also it would be a good idea to use a type parameter of ChoiceBox and use the private modifier:

@FXML
private ChoiceBox<String> choiceCity;

FXML file:

add the namespace prefix of the fxml namespace to the id attribute of the ChoiceBox:

...
<ChoiceBox fx:id="choiceCity" prefWidth="150.0">
...

Upvotes: 2

Related Questions