我应该在哪里验证JavaFX属性更改?

cru*_*sam 12 java validation binding javafx properties

我有一个mvp结构化的javafx应用程序.有一个带有textfield的视图,它有自己的textProperty类型StringProperty.还有一个包含名为Item的Object的模型.物品有一个IntegerProperty.

现在我想在我的演示者类中绑定这两个属性,以便在一个或另一个更改时更新它们.虽然他们有不同的类型,但有可能通过以下方式绑定它们:

Bindings.bindBidirectional( textField.textProperty(), item.percentProperty(), new NumberStringConverter() );
Run Code Online (Sandbox Code Playgroud)

这非常NullPointerException合适,除非文本字段的值被清除,这导致a ,因为textProperty的空值导致Null值并IntegerProperty在a 中的结果中设置null值NullPointerException.你能想出任何避免这种情况的方法吗?我必须自己写NumberStringConverter吗?

此外,我想定义,Item只能保持0到100之间的百分比值.当值无效时,应通知View,以便用户可以获得反馈.我应该在哪里验证这些业务规则?

我想出了第一个例子,但我不确定,如果这应该是要走的路,所以我很好奇,如果你有更好的想法如何解决这个问题.

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 >= 0 && value <= 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();
}
Run Code Online (Sandbox Code Playgroud)

den*_*ned 1

(新版答案)

我认为最好的方法是首先不要让用户输入错误的值。您可以在JideFX Fields的帮助下轻松实现这一点:

FormattedTextField<Integer> field = new FormattedTextField<>();
field.getPatternVerifiers().put("p", new IntegerRangePatternVerifier(0, 100));
field.setPattern("p");
field.valueProperty().bindBidirectional(item.percentProperty());
Run Code Online (Sandbox Code Playgroud)

特别FormattedTextField是非常方便,因为它为您进行文本到值的转换和验证,因此无需自己实现任何实用程序类。

链接:

JideFX Fields开发者指南:http://www.jidesoft.com/jidefx/JideFX_Fields_Developer_Guide.pdf

源代码: https: //github.com/jidesoft/jidefx-oss

二进制:http ://search.maven.org/#search%7Cga%7C1%7Cjidefx