JavaFX Spinner 抛出 IllegalArgumentException : The start must be <= the end

标签 java exception javafx

我在我的 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)

提前致谢。

最佳答案

您的问题与此相关:JavaFX Textfield with listener gives: "java.lang.IllegalArgumentException: The start must be <= the end"

我认为在 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 的文本将被提交,并传递到 valueFactoryfromString 方法。您的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/

相关文章:

尽管在 list 中设置了 Android Studio 权限异常

java - 找不到适合响应类型 [class org.springframework.http.ResponseEntity] 和内容类型 [application/octet-stream] 的 HttpMessageConverter

带有 CDI、JPA 和 javafx-maven-plugin 的 JavaFX

java - 如何在单击netbeans上设置多个jlabel的颜色?

java - 在 JNI 和 C 中释放持久数组

java - 如何使用jdbcTemplate为pojo类变量设置多行

java - 字符串对象创建的微妙之处 : aliases and garbage

c# - 与 Contract.Requires<T> 相比抛出异常?

java - 在tabpane右侧添加一个按钮

java - 尝试查找 .css 文件时出现 InvocativeTargetException