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

Properties JavaFx:IntegerProperty.IntegerProperty()奇怪的行为,properties,bind,javafx-8,Properties,Bind,Javafx 8,在我看来,我有一个HBox @FXML private HBox hboxWarning; 我想根据 private ObjectProperty<Integer> maxClientCount; 而且效果很好。我的问题是 IntegerProperty.integerProperty(maxClientCount) 将maxClientCount的当前值设置为零。这是一个JavaFx错误还是我使用了IntegerProperty.IntegerProperty不正确?及 如何

在我看来,我有一个
HBox

@FXML
private HBox hboxWarning;
我想根据

private ObjectProperty<Integer> maxClientCount;
而且效果很好。我的问题是

IntegerProperty.integerProperty(maxClientCount)

maxClientCount的当前值设置为零。这是一个JavaFx错误还是我使用了
IntegerProperty.IntegerProperty
不正确?及
如何实现我的目标?

正如@kleopatra所说,这是JDK 8u20中固定的JavaFx

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

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

我希望这能帮助一些人。

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

// 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) {
//u5中的方法绑定错误

//(用于IntegerProperty.IntegerProperty中) 公共静态双向绑定编号(属性1, 集成属性属性2) //召唤 私有静态双向绑定绑定编号(属性1, 物业(2){
顺序是至关重要的,因为在设置p1的值时,我们需要一个从Number转换为T的类型(这是安全的,因为我们知道Number-type属性处理从Number->concrete-type的转换)

对于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;
}
public静态IntegerProperty IntegerProperty(最终属性){
if(属性==null){
抛出新的NullPointerException(“属性不能为null”);
}
返回新的IntegerPropertyBase(){
{
(铸造(属性));
//原件:
//bindNumber(属性,this);
}
@凌驾
公共对象getBean(){
返回null;//虚拟属性,无bean
}
@凌驾
公共字符串getName(){
返回property.getName();
}
@凌驾
受保护的void finalize()抛出可丢弃的{
试一试{
不绑定(铸造(属性));
//原创的
//双向绑定。解除绑定编号(属性,this);
}最后{
super.finalize();
}
}
};
}
/**
*键入cast以允许bidi与混凝土属性绑定(带
*XX=整数,双精度…。这是(?)安全的,因为xxx属性
*内部处理从数字到具体的类型转换
*在设置其自身值时键入,并将混凝土类型导出为
*对象属性所需的。
* 
*/
私有静态属性强制转换(属性p){
返回(财产)p;
}

恕我直言-虽然经过初步测试,但可能会有我忽略的副作用。

这是一个错误:我倾向于根本不使用工厂-c&p,修复适配器并使用它,直到修复程序发布。允许设置并恢复损坏的属性可能会给潜在的侦听器带来问题(他们将收到意外通知)b)自适应属性本身(适配器的集可能会破坏内部验证规则)与所有的bug解决方法一样,这是一个品味问题,尽管:)我同意你的观点,我的解决方法可能会产生问题。我会按照你的建议,但我不明白应该复制、粘贴什么,然后修改?IntegerProperty类?IntegerProperty.IntegerProperty是一个静态方法,它在内部将IntegerProperty封装在你的属性周围rty-c&p该方法,并将所有绑定(属性,此)转换为绑定(此,属性)啊..现在我明白了为什么错误会首先发生(只检测到它,自己从未尝试过修复它)-泛型类型很重要。我们将查看b20中的修复,然后回来感谢@kleopatra。我不太明白为什么未检查的强制转换可以被认为是安全的:-)我们只对绑定中同步的值感兴趣,通过setValue/getValue完成。那么t必须是具体数字类型的类型,即integralERPProperty ObjectProperty或DoubleProperty ObjectProperty对其他对象是安全的您的解决方法有效!!为什么编译器在cast方法中给我“unchecked”警告?数字是T的超类…:/
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;
}