JavaFX Spinner抛出IllegalArgumentException:start必须是< = end

时间:2016-07-22 06:58:51

标签: java exception javafx

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

先谢谢。

1 个答案:

答案 0 :(得分:1)

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

我认为在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);

此格式化程序只接受数字和“。”和“,”字符。