我在我的 JavaFX
应用程序中使用微调器。我已将以下 listener
添加到我的微调器中,以便始终从 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)
提前致谢。
最佳答案
我认为在 Spinner
的编辑器 TextField
中设置 Spinner
值不是一个好主意。
来自 editableProperty 的文档Spinner
的:
If editable is true, user input will be received once the user types and presses the Enter key. At this point the input is passed to the SpinnerValueFactory converter StringConverter.fromString(String) method. The returned value from this call (of type T) is then sent to the SpinnerValueFactory.setValue(Object) method. If the value is valid, it will remain as the value. If it is invalid, the value factory will need to react accordingly and back out this change.
因此,默认工作是您只编辑文本,直到按 Enter 键。按 Enter 键后,TextField
的文本将被提交,并传递到 valueFactory 的 fromString
方法。您的Spinner
。您可以在工厂中处理这种情况,如下所示:
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;
}
}
});
此外,您可以使用 TextFormatter 过滤输入以不接受非法字符。在TextField
上:
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);
此格式化程序仅接受数字和“.”和“,”字符。
关于JavaFX Spinner 抛出 IllegalArgumentException : The start must be <= the end,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38520088/