title: Why toString is not getting called in TextFormatter?
body: <p>I want to make a field where you can type any number and it will be converted to <strong>#.#</strong> (Decimal with one number after dot) and stored as Integer. </p>
  
  <p><strong>Problem:</strong> If user has already number <strong>5.0</strong> and erases <strong>0</strong>, after focus lost, it will remain as <strong>5.</strong> , because <code>toString</code> method from converter is not getting called. </p>
  
  <p>However, if user has number <strong>55.0</strong> and erases <strong>0</strong>, after focus lost, <code>toString</code> method is getting called and number becomes <strong>55.0</strong> again.</p>
  
  <p>My <code>Main.fxml</code>:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;?import javafx.scene.control.TableColumn?&gt;
  &lt;?import javafx.scene.control.TableView?&gt;
  &lt;?import javafx.scene.layout.AnchorPane?&gt;
  
  
  &lt;AnchorPane prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="home.accounting.view.MainController"&gt;
     &lt;children&gt;
        &lt;TableView fx:id="waterTable" layoutX="31.0" layoutY="50.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="50.0"&gt;
          &lt;columns&gt;
            &lt;TableColumn fx:id="flat" maxWidth="75.0" prefWidth="75.0" text="Flat" /&gt;
            &lt;TableColumn fx:id="newValue" prefWidth="185.0" text="New Value" /&gt;
              &lt;TableColumn fx:id="oldValue" prefWidth="185.0" text="Old Value" /&gt;
          &lt;/columns&gt;
        &lt;/TableView&gt;
     &lt;/children&gt;
  &lt;/AnchorPane&gt;
  </code></pre>
  
  <p><code>MainApp.java</code>:</p>
  
  <pre><code>public class MainApp extends Application {
  
      private AnchorPane rootLayout;
  
      @Override
      public void start(Stage primaryStage) {
  
          primaryStage.setTitle("Test");
          try {
              FXMLLoader loader = new FXMLLoader();
              loader.setLocation(MainApp.class.getResource("view/Main.fxml"));
              rootLayout = (AnchorPane)loader.load();
              Scene scene = new Scene(rootLayout);
              primaryStage.setScene(scene);
              primaryStage.show();
          } catch (Exception e) {
              e.printStackTrace();
          }
  
      }
  
      public static void main(String[] args) {
          launch(args);
      }
  }
  </code></pre>
  
  <p><code>MainController.java</code>:</p>
  
  <pre><code>public class MainController {
  
      @FXML
      private TableView&lt;Water&gt; waterTable;
  
      @FXML
      private TableColumn&lt;Water, Integer&gt; flat;
  
      @FXML
      private TableColumn&lt;Water, Integer&gt; newValue;
  
      @FXML TableColumn&lt;Water, Integer&gt; oldValue;
  
      private List&lt;Water&gt; waterList;
  
      private static final String waterFormat = "0.0";
  
      private static final StringConverter&lt;Integer&gt; VALUE_CONVERTER = new StringConverter&lt;Integer&gt;() {
  
          @Override
          public String toString(Integer object) {
              System.out.println("TO STRING CONVERTER: "+object);
              return object == null ? "" : convertToString(object);
          }
  
          @Override
          public Integer fromString(String string) {
              System.out.println("TO INTEGER CONVERTER:"+string+";"+string.isEmpty());
              return string.isEmpty() ? null : convertToInt(string);
          }
  
      };
  
  
      @FXML
      private void initialize(){
          createObjects();
          setupCells();
          createRows();
      }
  
      private void createObjects(){
          waterList = new ArrayList&lt;&gt;();
  
          for(int i=0; i&lt;5; i++){
              waterList.add(new Water(i+1));
          }
      }
  
      private void setupCells(){
          flat.setCellValueFactory(cellData -&gt; new ReadOnlyObjectWrapper&lt;&gt;(cellData.getValue().getFlat()));
  
          newValue.setCellValueFactory(cellData -&gt; new ReadOnlyObjectWrapper&lt;&gt;(cellData.getValue().getNewValue()));
          newValue.setCellFactory(new Callback&lt;TableColumn&lt;Water,Integer&gt;, TableCell&lt;Water, Integer&gt;&gt;() {
  
              @Override
              public TableCell&lt;Water, Integer&gt; call(TableColumn&lt;Water, Integer&gt; param) {
                  return new TableCell&lt;Water, Integer&gt;(){
  
                      private final TextFormatter&lt;Integer&gt; formatter;
                      private final TextField textField;
                      {
                          textField = new TextField();
                          formatter = new TextFormatter&lt;&gt;(VALUE_CONVERTER, null, null);
                          textField.setTextFormatter(formatter);
                      }
                      @Override
                      protected void updateItem(Integer value, boolean empty){
                          super.updateItem(value, empty);
                          if (empty){
                              setGraphic(null);
                          } else {
                              setGraphic(textField);
                              formatter.setValue(value);
                          }
                      }
                  };   
              }
          });
      }
  
      private void createRows(){
          waterTable.setItems(FXCollections.observableArrayList(waterList));
      }
  
      private static int convertToInt(String water){
          int waterInt = 0;
          try{
              BigDecimal userInput = new BigDecimal(water);
              DecimalFormat waterConverter = new DecimalFormat(waterFormat);
              String waterString = waterConverter.format(userInput);
              waterInt = Integer.parseInt(String.valueOf(new BigDecimal(waterString).movePointRight(1)));
          }catch (Exception e) {
              e.printStackTrace();
          }
  
          return waterInt;
      }
  
      private static String convertToString(int water){
          System.out.println("TO STRING CONVERTER: "+water);
          BigDecimal userInput = new BigDecimal(water);
          DecimalFormat waterConverter = new DecimalFormat(waterFormat);
          String waterString = waterConverter.format(userInput.movePointLeft(1));
          return waterString;
      }
  }
  </code></pre>
  
  <p><code>Water.java</code>:</p>
  
  <pre><code>public class Water {
  
      private Integer flat;
      private Integer newValue;
      private Integer oldValue;
  
      public Water(Integer flat){
          this.flat = flat;
      }
  
      public Integer getFlat() {
          return flat;
      }
  
      public void setFlat(Integer flat) {
          this.flat = flat;
      }
  
      public Integer getNewValue() {
          return newValue;
      }
  
      public void setNewValue(Integer newValue) {
          this.newValue = newValue;
      }
  
      public Integer getOldValue() {
          return oldValue;
      }
  
      public void setOldValue(Integer oldValue) {
          this.oldValue = oldValue;
      }
  }
  </code></pre>
  
  <p>Result:</p>
  
  <p><a href="https://i.stack.imgur.com/w5E8v.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/w5E8v.png" alt="enter image description here"></a></p>