带有监听器的JavaFX Textfield给出:“java.lang.IllegalArgumentException:start必须是< = end”

时间:2015-05-26 17:40:13

标签: java regex exception listener textfield

我得到一个例外但不明白是什么原因造成的。这是一个FXML文件的FX应用程序。在App的init()部分,我将一个监听器添加到一个文本字段,该文本字段调用一个函数,该函数使用模式的正则表达式监视String。

tf.textProperty().addListener(
        (observable, oldValue, newValue) -> {
            handleInput(newValue);
        });

功能:

private void handleInput(String s) {

            s = s.toUpperCase();
            Matcher matcher = Pattern
                    .compile(
                            "^[A-Z]{2}(20|21|22|23|[0-1]\\d)[0-5]\\d(20|21|22|23|[0-1]\\d)[0-5]\\d(T\\s|C\\s|TC|CT|\\s\\s)$")
                    .matcher(s);

            if (matcher.find()) {

                    // do something

                    // then clear the textfield
                    tf.clear();

                } else {
                    // do something else
                }
            }

它有效但在匹配器匹配的情况下给我一个例外。

例外:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: The start must be <= the end
    at javafx.scene.control.TextInputControl.getText(Unknown Source)
    at javafx.scene.control.TextInputControl.updateContent(Unknown Source)
    at javafx.scene.control.TextInputControl.replaceText(Unknown Source)
    at com.sun.javafx.scene.control.skin.TextFieldSkin.replaceText(Unknown Source)
    at com.sun.javafx.scene.control.behavior.TextFieldBehavior.replaceText(Unknown Source)
    at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.defaultKeyTyped(Unknown Source)
    at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callAction(Unknown Source)
    at com.sun.javafx.scene.control.behavior.BehaviorBase.callActionForEvent(Unknown Source)
    at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callActionForEvent(Unknown Source)
    at com.sun.javafx.scene.control.behavior.BehaviorBase.lambda$new$75(Unknown Source)
    at com.sun.javafx.scene.control.behavior.BehaviorBase$$Lambda$88/1978656397.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$KeyHandler.process(Unknown Source)
    at javafx.scene.Scene$KeyHandler.access$1800(Unknown Source)
    at javafx.scene.Scene.impl_processKeyEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$349(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$349/1135388943.get(Unknown Source)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(Unknown Source)
    at com.sun.glass.ui.View.handleKeyEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyKey(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)}

我已经尝试了一些我在其他帖子中找到的建议,比如在将它提供给匹配器之前检查字符串:

if (!tf.getText() == null) {

if (!tf.getText().equals("") {

但例外仍然存在。当我删除:

tf.clear();

一切正常。

......任何想法?

编辑swinkler的解决方案:

使用swinkler代码时得到的异常 - JDK 1.8.0_45:

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 com.sun.javafx.scene.control.skin.TextFieldSkin.replaceText(TextFieldSkin.java:576)
    at com.sun.javafx.scene.control.behavior.TextFieldBehavior.replaceText(TextFieldBehavior.java:202)
    at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.defaultKeyTyped(TextInputControlBehavior.java:238)
    at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callAction(TextInputControlBehavior.java:139)
    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$91/476337053.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.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$142/181559839.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/2117255219.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

2 个答案:

答案 0 :(得分:12)

我有相同的problem并找到了错误报告JDK-8081700,它解决了这个问题。事实证明不是一个错误。

  

测试用例尝试修改更改中的text属性   处理程序。这不受支持,属性事件处理程序是   不可重入。

     

正确的方法是让应用程序延迟修改,   使用runLater():

    if (matcher.find()) { 
        System.err.println("true"); 
        Platform.runLater(() -> { 
            textField.clear(); 
        }); 
    }

答案 1 :(得分:0)

在简单的JavaFX应用程序中使用它时,我无法得到您的错误。这是我用来测试你的实现的代码。我的测试输入是“AA20552055T”以匹配正则表达式 - 文本字段被清除。

请与您的解决方案进行比较:

public class JavaFXApplication1 extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

带有逻辑的Controller类:

public class FXMLDocumentController implements Initializable {

    @FXML
    private TextField textfield;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        textfield.textProperty().addListener(
                (observable, oldValue, newValue) -> {
                    handleInput(newValue);
                });
    }

    private void handleInput(String s) {

        s = s.toUpperCase();
        Matcher matcher = Pattern
                .compile(
                        "^[A-Z]{2}(20|21|22|23|[0-1]\\d)[0-5]\\d(20|21|22|23|[0-1]\\d)[0-5]\\d(T\\s|C\\s|TC|CT|\\s\\s)$")
                .matcher(s);

        if (matcher.find()) {

                    // do something
                    // then clear the textfield
            textfield.clear();

        } else {
            // do something else
        }
    }
}

FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication1.FXMLDocumentController">
    <children>
        <TextField layoutX="126" layoutY="150"  fx:id="textfield" /> 
    </children>
</AnchorPane>

关于评论,我安装了JDK 1.8.0_45(在1.8.0_20之前) 在Windows 7 x64上工作 再次,没有错误。

Here is the jar Netbeans自动创建 - 我是从CMD测试的。工作也很好。你能测试一下从CMD执行的jar文件是否在你的机器上工作正常吗?

对于调试 - 这是由change参数给出异常数据的方法。更改有startend

 private void updateContent(TextFormatter.Change change, boolean forceNewUndoRecord) {
        final boolean nonEmptySelection = getSelection().getLength() > 0;
        String oldText = getText(change.start, change.end);

然后,开始和结束值会在getText(...)

中触发异常
 public String getText(int start, int end) {
        if (start > end) {
            throw new IllegalArgumentException("The start must be <= the end");
        }

        if (start < 0
            || end > getLength()) {
            throw new IndexOutOfBoundsException();
        }

        return getContent().get(start, end);
    }