Search code examples
javajavafxcombobox

Problem with adding items to ComboBox in JavaFX


I'm a newbie in JavaFX, trying to start with a windowed application. For start I have a simple ComboBox and I'm filling it with game types, to choose one. Nothing more for start. And there problem begins. According to this answer I have created a model class for entering values in a ComboBox. However, when application starts, there is an error:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at
com.vojjin.pcreator@1.1/com.vojjin.pcreator.HelloController$1.toString(HelloController.java:23)

Here is the window, with just a Label and ComboBox:

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

<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<Pane prefHeight="250.0" prefWidth="654.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.vojjin.pcreator.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
    </padding>
    <Label layoutX="7.0" layoutY="2.0" prefHeight="17.0" prefWidth="94.0" text="Select game type" />
    <ComboBox fx:id="gameTypeCombo" layoutX="7.0" layoutY="20.0" prefWidth="150.0" />
</Pane>

Here is the model class:

package com.vojjin.pcreator.items;

public class GameType {
  private final String name;
  private final String id;

  public GameType(String name, String id) {
    this.name = name;
    this.id = id;
  }
  public String getId() {
    return id;
  }

  public String getName() {
    return name;
  }
}

and Controller class (where I receive an error):

package com.vojjin.pcreator;

import com.vojjin.pcreator.items.GameType;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.util.StringConverter;

public class HelloController {
  private String gameType;

  @FXML
  private ComboBox<GameType> gameTypeCombo;

  public void initialize() {
    StringConverter<GameType> t=new StringConverter<>() {
      @Override
      public String toString(GameType object) {
        return object.getName(); //this is the error line
      }

      @Override
      public GameType fromString(String string) {
        return null;
      }
    };

    gameTypeCombo.setConverter(t);

    gameTypeCombo.setItems(FXCollections.observableArrayList(
        new GameType("Arithmo Games", "arithmo"),
        new GameType("iMath Games", "imath")
    ));

    gameTypeCombo.valueProperty().addListener((obs, oldVal, newVal) -> {
      gameType = newVal.getId();
      System.out.println(gameType);
    });
  }

}

Line: return object.getName(); is generating error. That line is what should be displayed in ComboBox. If I put, for example, return "A"; everything is working, except my ComboBox is filled with "A"'s instead of game names. And changing values are working just fine (I'm getting proper getId() value).

Any ideas?


Solution

  • When Combobox is initialized and no value is selected the object in public String toString(GameType object) is null.
    public String toString(GameType object) has to be modified to handle null object.
    For example:

      public String toString(GameType object) {
        return object == null ?  "" : object.getName(); 
      }
    

    Or

      public String toString(GameType object) {
        return object == null ?  "Please select" : object.getName(); 
      }
    

    Alternatively you could select a value when initializing the combo: gameTypeCombo.getSelectionModel().select(0);