JavaFx:IntegerProperty.integerProperty()奇怪的行为

时间:2014-06-25 19:19:45

标签: properties bind javafx-8

在我看来,我有HBox

@FXML
private HBox hboxWarning;

我希望根据

的值隐藏/显示它
private ObjectProperty<Integer> maxClientCount;

如果maxClientCount > 10然后hboxWarning可见,则隐藏它。 我以这种方式绑定了这两个元素

hboxWarning.visibleProperty().bind(IntegerProperty.integerProperty(maxClientCount).greaterThan(10));

并且运作良好。我的问题是

IntegerProperty.integerProperty(maxClientCount)

maxClientCount的当前值设置为零。它是JavaFx错误还是我使用IntegerProperty.integerProperty不正确?和 我怎样才能实现目标?

2 个答案:

答案 0 :(得分:2)

原来并不像假设那么容易:核心修复需要BidirectionalBinding中的其他方法来处理交换的数字类型序列。实际的数字绑定是私有的,因此无法访问变通方法代码。

// method in u5, binds the wrong way round 
// (for usage in IntegerProperty.integerProperty) 
public static BidirectionalBinding bindNumber(Property<Integer> property1, 
       IntegerProperty property2) 

// calls 
private static <T extends Number> BidirectionalBinding bindNumber(Property<T> property1, 
       Property<Number> property2) {

序列是至关重要的,因为在设置p1的值时我们需要从Number到T的类型转换(这是安全的,因为我们知道number-type属性应对来自Number的转换 - &gt;具体类型)。核心修复只是添加了所有那些带有切换参数序列的方法。

对于JDK 8u20发布之前的自定义hack,我看到的唯一方法是不使用特殊数字绑定方法,而是使用通用对象绑定:

public static IntegerProperty integerProperty(final Property<Integer> property) {
    if (property == null) {
        throw new NullPointerException("Property cannot be null");
    }
    return new IntegerPropertyBase() {
        {
            bindBidirectional(cast(property));
            // original:
            //BidirectionalBinding.bindNumber(property, this);
        }

        @Override
        public Object getBean() {
            return null; // Virtual property, no bean
        }

        @Override
        public String getName() {
            return property.getName();
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                unbindBidirectional(cast(property));
                // original
                // BidirectionalBinding.unbindNumber(property, this);
            } finally {
                super.finalize();
            }
        }
    };
}

/**
 * Type cast to allow bidi binding with a concrete XXProperty (with
 * XX = Integer, Double ...). This is (?) safe because the XXProperty
 * internally copes with type conversions from Number to the concrete
 * type on setting its own value and exports the concrete type as
 * needed by the object property.
 * 
 */
private static <T extends Number> Property<Number> cast(Property<T> p) {
    return (Property<Number>) p;
}

带上一粒盐 - 虽然进行了初步测试,但可能会出现我忽略的副作用。

答案 1 :(得分:1)

正如@kleopatra所说,这是在JDK 8u20中修复的JavaFx bug

与此同时,我使用了以下解决方法:

int maxClients = maxClientCount.get();
hboxWarning.visibleProperty().bind(IntegerProperty.integerProperty(maxClientCount).greaterThan(10));
maxClientCount.setValue(maxClients);

我希望这可以帮助别人。