title: Where should I validate JavaFX Property changes?
body: <p>I have a mvp structured javafx application. There is a view with a textfield, which has its own textProperty of type <code>StringProperty</code>. There is also a model which contains an Object called Item. Item has an <code>IntegerProperty</code>.</p>
  
  <p>Now I'd like to bind these two Properties within my presenter-class, so that they get updated, when one or another changes. Eventhough they have different types, there is the possibility to bind them the following way:</p>
  
  <pre><code>Bindings.bindBidirectional( textField.textProperty(), item.percentProperty(), new NumberStringConverter() );
  </code></pre>
  
  <p>This works perfectly fine, unless the value of the textfield gets cleared, which results in a <code>NullPointerException</code>, because an empty value of textProperty results in a Null-Value and setting a null Value in <code>IntegerProperty</code> results in a <code>NullPointerException</code>. Can you think of any way to avoid this? Do I have to write my own <code>NumberStringConverter</code>?</p>
  
  <p>Moreover I'd like to define, that <code>Item</code> can only hold a percent value between 0 and 100. The View should be informed, when the value is invalid, so the user can get feedback. <strong>Where should I verify these kind of businessrules?</strong></p>
  
  <p>I came up with a first example, but I am not sure, if that should be the way to go, so I'd be curious, if you might have better ideas how to solve this.</p>
  
  <pre><code>class PercentProperty extends SimpleIntegerProperty
  {
    private InvalidValueListener invalidValueListener = null;
  
    public PercentProperty ( final Integer defaultValue )
    {
      set( defaultValue );
    }
  
    @Override
    public void set( final int newValue )
    {
      if ( isValid( newValue ) )
      {
        super.set( newValue );
        if ( invalidValueListener != null )
          invalidValueListener.validValue();
      }
      else
      {
        if ( invalidValueListener != null )
          invalidValueListener.invalidValue();
      }
    }
  
    private boolean isValid( final int value )
    {
      return (value &gt;= 0 &amp;&amp; value &lt;= 100);//FIXME: Better use Predicates to define Rules.
    }
  
    public void setListener( final InvalidValueListener listener )
    {
      invalidValueListener = listener;
    }
  
    public void removeListener( @SuppressWarnings( "unused" ) final InvalidValueListener listener )
    {
      invalidValueListener = null;
    }
  
    protected void fireInvalidationValue()
    {
      invalidValueListener.invalidValue();
    }
  }
  
  
  interface InvalidValueListener
  {
    void validValue();
    void invalidValue();
  }
  </code></pre>