限制哪些值可以在javafx属性中结算?
将javafx属性的值保持在特定范围内的最佳方法是什么 (或者-这是一种不好的做法,有没有任何理由不过滤javafx属性包装的值?) 示例1:避免整数属性中出现负值限制哪些值可以在javafx属性中结算?,java,properties,javafx,javafx-2,Java,Properties,Javafx,Javafx 2,将javafx属性的值保持在特定范围内的最佳方法是什么 (或者-这是一种不好的做法,有没有任何理由不过滤javafx属性包装的值?) 示例1:避免整数属性中出现负值 示例2:将IntegerProperty的值保持在列表的范围内 第一个想法:-覆盖IntegerPropertyBase.set(int)。安全吗?实际上setValue(int)只调用set(int),但是如果有一天这个实现发生了变化,那么对值集的控制就会丢失 第二个想法:-重写IntegerPropertyBase.invali
示例2:将IntegerProperty的值保持在列表的范围内 第一个想法:-覆盖
IntegerPropertyBase.set(int)
。安全吗?实际上setValue(int)
只调用set(int)
,但是如果有一天这个实现发生了变化,那么对值集的控制就会丢失
第二个想法:-重写IntegerPropertyBase.invalidate()。但是在这一点上,这个值已经设置好了
它是否更适合javafx属性抛出一个IllegalArgumentException
(或者ArrayIndexOutOfBoundsException
,如果包装的值是数组的索引),或者更好地拒绝超出边界的值,设置边界中的最后一个值
也许是这样:
class BoundedIntegerProperty extends IntegerPropertyBase {
(...)
int oldValue = defaultValueInBounds;
boolean settingOldValue = false;
public void invalidated() {
if(!settingOldValue){
if(outOfBounds(get())){
settingOldValue = true;
set(oldValue);
} else {
oldValue = get();
}
} else
settingOldValue = false;
}
}
只有在invalidated()中抛出值超出范围的异常,才能使属性的值超出范围
我是否忽略了提供给筛选值的javafx属性中的任何内容?(如有必要,请帮助我改进本文中可能不好的英语…在两个示例中,似乎都有一个逻辑默认值(例如,如果要求为正数,负数将变为0)。假设您记录的很好(如果值无效,默认值是什么),我认为您的第一种方法似乎走在了正确的道路上 我建议您从一个具体的类开始,比如要扩展的类
SimpleIntegerProperty
(除非您选择IntegerPropertyBase
)
然后,我将覆盖set(int)
方法和setValue(Number)
方法,将父对象包装到您的逻辑中:
/**
* Explanation that values under 0 are set to 0
*/
@Override
public void set(int value){
super.set(value > 0 ? value : 0);
}
/**
* Explanation that values under 0 are set to 0
*/
@Override
public void setValue(Number value){
super.setValue(value.intValue() > 0 ? value : 0);
}
可能存在这样一种情况,即没有逻辑默认值(或者您只想拒绝无效值)。这种情况使问题变得更加困难—您实际上希望使用类似的方法签名,以便调用者知道值是否更改:
public boolean set(int value)
为了做到这一点,您必须返回许多类—一直返回到ReadOnlyIntegerProperty
,并自己实现设置/失效结构
我会犹豫是否使用异常来处理无效的输入。这是对异常的合法使用,但我担心的是,异常会被依赖于验证。异常是非常资源密集型的,只有在有需要修复的事情时才应该被命中。所以这真的是关于你的意图以及你对peop的信任程度请使用您的类来做正确的事情(并在发送给您之前进行验证)。我相信我了解您现在的目标。您希望执行用户输入验证 在进行用户验证时,实际上有两种方法:
TextField field = new TextField();
field.textProperty().addListener(new ChangeListener<String>(){
@Override
public void changed(ObservableValue<? extends String> value,
String oldValue, String newValue) {
//Do your validation or revert the value
}});
注意:
我假设您只是想为更新UI的系统代码设置一个故障保护。我将保留我以前的回答,因为我相信它也提供了有用的信息。在设置属性之前验证输入可能更简单,例如验证文本字段、DB结果或文件中的数据。我看不到任何好的处理方法,w你真的想要一套吗调用以引发异常?您是对的:例如,为没有访问此列表权限的列表设置索引是没有意义的。但是,如果我有访问此列表的权限,则索引属性的设置器可能在列表本身中,并且该属性可能是只读的。在列表中,如果索引超出范围,则索引的设置器可能引发异常边界。当然:如果输入可能非法,我需要一个布尔函数来检查输入是否非法。这不包含在Javafx属性中。如果验证返回false,并且我将属性还原为
oldValue
,则验证将以“new”的旧值重新开始。如果对oldValue
的验证也返回false(可能是添加验证侦听器之前属性中包含的值),我们将进入一个循环。在这种情况下,在还原到它们之前验证oldValue
会更安全。
TextField field = new TextField();
field.focusedProperty().addListener(new ChangeListener<Boolean>(){
String lastValidatedValue = "";
@Override
public void changed(ObservableValue<? extends Boolean> value,
Boolean oldValue, Boolean newValue) {
if(newValue == false && oldValue == true){
//Do your validation and set `lastValidatedValue` if valid
}
}});