我在8u40b17使用Spinner。
SpinnerValueFactory svf = new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 100);
Spinner sp = new Spinner();
sp.setValueFactory(svf);
sp.setEditable(true);
sp.setPrefWidth(80);
我注意到当我从键盘输入一些值并且我增加了上限值时,预期的数字不是下一个。而不是这个,它是下一个默认值。我怎么解决这个问题?
例如:如果我有5作为默认值而我输入34,那么按下我希望得到35的上箭头实际上得到6。
答案 0 :(得分:5)
我对旋转器控件有同样的问题。您的错误已记录在此处:JDK-8094205
这是最后一条评论:
Jonathan Giles发表了评论 - 2014年12月15日上午12:59
在我的仓库本地修复,本周将推送至8u60回购 打开。现在,文本编辑器输入在递增时提交/ 调用递减(尽管该值仍未提交 焦点丢失了。)
单元测试:
javafx.scene.control.SpinnerTest.test_rt_39655_decrement() javafx.scene.control.SpinnerTest.test_rt_39655_increment()
变更集:http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/89ca7d3f699e
这是我对Autocommit微调器的看法。这个将自动提交工厂将接受的任何东西。
public class SpinnerAutoCommit<T> extends Spinner<T> {
public SpinnerAutoCommit() {
super();
addListenerKeyChange();
}
public SpinnerAutoCommit(int min, int max, int initialValue) {
super(min, max, initialValue);
addListenerKeyChange();
}
public SpinnerAutoCommit(int min, int max, int initialValue, int amountToStepBy) {
super(min, max, initialValue, amountToStepBy);
addListenerKeyChange();
}
public SpinnerAutoCommit(double min, double max, double initialValue) {
super(min, max, initialValue);
addListenerKeyChange();
}
public SpinnerAutoCommit(double min, double max, double initialValue, double amountToStepBy) {
super(min, max, initialValue, amountToStepBy);
addListenerKeyChange();
}
public SpinnerAutoCommit(ObservableList<T> items) {
super(items);
addListenerKeyChange();
}
public SpinnerAutoCommit(SpinnerValueFactory<T> valueFactory) {
super(valueFactory);
addListenerKeyChange();
}
private void addListenerKeyChange() {
getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
commitEditorText();
});
}
private void commitEditorText() {
if (!isEditable()) return;
String text = getEditor().getText();
SpinnerValueFactory<T> valueFactory = getValueFactory();
if (valueFactory != null) {
StringConverter<T> converter = valueFactory.getConverter();
if (converter != null) {
T value = converter.fromString(text);
valueFactory.setValue(value);
}
}
}
}
答案 1 :(得分:3)
按照设计,Spinner
控件的文本字段中的更改仅在用户通过操作处理程序按Enter键时才会被提交:
getEditor().setOnAction(action -> {
String text = getEditor().getText();
SpinnerValueFactory<T> valueFactory = getValueFactory();
if (valueFactory != null) {
StringConverter<T> converter = valueFactory.getConverter();
if (converter != null) {
T value = converter.fromString(text);
valueFactory.setValue(value);
}
}
});
请注意,如果键入的值无法转换,则会抛出NumberFormatException
,并在文本字段中保留错误的值。
我们可以提供我们自己的实现,通过事件过滤器监听其他键,如TAB键,同时,如果发生异常,还原最后一个有效值。
这样的事情:
private final Spinner sp = new Spinner();
@Override
public void start(Stage primaryStage) {
SpinnerValueFactory svf = new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 100);
sp.setValueFactory(svf);
sp.setEditable(true);
sp.setPrefWidth(80);
// Commit on TAB
sp.addEventFilter(KeyEvent.ANY, e->{
if (sp.isEditable() && e.getCode().equals(KeyCode.TAB)) {
doCommit();
e.consume();
}
});
// Override Commit on ENTER
sp.getEditor().setOnAction(e->{
if(sp.isEditable()) {
doCommit();
e.consume();
}
});
Scene scene = new Scene(new StackPane(sp), 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
/*
Commit new value, checking conversion to integer,
restoring old valid value in case of exception
*/
private void doCommit(){
String text = sp.getEditor().getText();
SpinnerValueFactory<Integer> valueFactory = sp.getValueFactory();
if (valueFactory != null) {
StringConverter<Integer> converter = valueFactory.getConverter();
if (converter != null) {
try{
Integer value = converter.fromString(text);
valueFactory.setValue(value);
} catch(NumberFormatException nfe){
sp.getEditor().setText(converter.toString(valueFactory.getValue()));
}
}
}
}
答案 2 :(得分:1)
这解决了我的问题,但它依赖于Apache Commons Validator来验证微调器中输入的值( org.apache.commons.validator.GenericValidator )
valueSpinner.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
try {
if (GenericValidator.isInt(newValue)) {
valueSpinner.getValueFactory().setValue(Integer.parseInt(newValue));
}
} catch (NumberFormatException e) {
if (GenericValidator.isInt(oldValue)) {
valueSpinner.getValueFactory().setValue(Integer.parseInt(oldValue));
}
}
});
修改: - 您可以在不使用Apache Commons Validator的情况下验证该值,如下例所示: -
private boolean isInteger(String value) {
if (value == null) {
return false;
}
try {
new Integer(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
valueSpinner.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
try {
if (isInteger(newValue)) {
valueSpinner.getValueFactory().setValue(Integer.parseInt(newValue));
}
} catch (NumberFormatException e) {
if (isInteger(oldValue)) {
valueSpinner.getValueFactory().setValue(Integer.parseInt(oldValue));
}
}
});