我得到一个例外但不明白是什么原因造成的。这是一个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)
答案 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
参数给出异常数据的方法。更改有start
和end
。
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);
}