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

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

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

function:

 private void handleInput(String s) { s = s.toUpperCase(); Matcher matcher = Pattern .compile( "^[AZ]{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)} 

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

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

要么

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

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

 tf.clear(); 

一切正常。

……有什么想法吗?

编辑swinkler的解决方案:

使用swinkler代码时得到的exception – 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) 

我遇到了同样的问题 ,发现了错误报告JDK-8081700 ,它解决了这个问题。 事实certificate这不是一个错误。

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

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

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

在简单的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( "^[AZ]{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文件:

            

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

这是 Netbeans自动创建的jar – 我是从CMD测试的。 工作也很好。 你能测试从CMD执行的jar文件是否在你的机器上正常工作?

对于调试 – 这是由change参数给出exception数据的方法。 变化有一个startend

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

然后,start和end值在getText(...)触发exception:

  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); }