我在我的JavaFX
应用程序中使用了微调器。我已将listener
添加到我的微调器中,以便始终从Spinner
获取更新值。这个Spinner
是双值微调器。
lengthOverAllSpinner.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
try {
lengthOverAllSpinner.getValueFactory().setValue(Double.parseDouble(newValue));
} catch (NumberFormatException e) {
lengthOverAllSpinner.getValueFactory().setValue(Double.parseDouble(oldValue));
}
});
但是当我尝试从GUI编辑我的微调器(例如,当前值为340.23)时,当我按退格键并删除以下小数位的值时,抛出异常但我总是得到更新的值。不知道为什么会出现这种异常。请帮助:
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: The start must be <= the end
at javafx.scene.control.TextInputControl.getText(TextInputControl.java:446)
at javafx.scene.control.TextInputControl.updateContent(TextInputControl.java:564)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:548)
at javafx.scene.control.TextInputControl.deleteText(TextInputControl.java:496)
at javafx.scene.control.TextInputControl.deletePreviousChar(TextInputControl.java:897)
at com.sun.javafx.scene.control.skin.TextFieldSkin.deleteChar(TextFieldSkin.java:589)
at com.sun.javafx.scene.control.behavior.TextFieldBehavior.deleteChar(TextFieldBehavior.java:198)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.deletePreviousChar(TextInputControlBehavior.java:311)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callAction(TextInputControlBehavior.java:143)
at com.sun.javafx.scene.control.behavior.BehaviorBase.callActionForEvent(BehaviorBase.java:218)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callActionForEvent(TextInputControlBehavior.java:127)
at com.sun.javafx.scene.control.behavior.BehaviorBase.lambda$new$75(BehaviorBase.java:135)
at com.sun.javafx.scene.control.behavior.BehaviorBase$$Lambda$206/1978625466.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$KeyHandler.process(Scene.java:3965)
at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3911)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2502)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$349(GlassViewEventHandler.java:228)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$459/610595104.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
at com.sun.glass.ui.View.notifyKey(View.java:956)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(WinApplication.java:101)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/2058534881.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
先谢谢。
答案 0 :(得分:1)
我认为在Spinner
的编辑器TextField
中设置Spinner
值并不是一个好主意。
来自Spinner
的{{3}}的文档:
如果editable为true,则在用户输入后将收到用户输入 然后按Enter键。此时输入传递给 SpinnerValueFactory转换器StringConverter.fromString(String) 方法。然后将此调用(类型为T)的返回值发送给 SpinnerValueFactory.setValue(Object)方法。如果值是 有效,它将保留为值。如果它无效,则为该值 工厂需要做出相应的反应并取消这一变化。
因此,默认的工作原理是,只有在按Enter键之前才会对文本进行编辑。在回车键上按下提交TextField
的文本,然后传递到fromString
Spinner
的{{1}}方法。你可以在工厂处理这种情况,如:
lengthOverAllSpinner.getValueFactory().setConverter(new StringConverter<Double>() {
private final DecimalFormat df = new DecimalFormat("#.####");
@Override public String toString(Double value) {
// If the specified value is null, return a zero-length String
if (value == null) {
return "";
}
return df.format(value);
}
@Override public Double fromString(String value) {
try {
// If the specified value is null or zero-length, return null
if (value == null)
return null;
value = value.trim();
if (value.length() < 1)
return null;
// Perform the requested parsing
return df.parse(value).doubleValue();
} catch (Exception ex) {
return 0.0;
}
}
});
此外,您可以使用TextField
上的editableProperty过滤输入,使其不接受非法字符:
TextFormatter<Object> textFormatter = new TextFormatter<>(c -> {
if (c.getText().matches("[^0-9.,]+") && !c.getText().isEmpty())
return null;
SpinnerValueFactory.DoubleSpinnerValueFactory factory = (SpinnerValueFactory.DoubleSpinnerValueFactory) spinner.getValueFactory();
try {
Double newVal = Double.parseDouble(c.getControlNewText());
return (newVal >= factory.getMin() && factory.getMax() >= newVal) ? c : null;
} catch (Exception ex) {
c.setText("0.0");
return c;
}
});
spinner.getEditor().setTextFormatter(textFormatter);
此格式化程序只接受数字和“。”和“,”字符。