由于插入符号位置,文本字段内出现 Javafx indexOutOfBoundsException
我正在构建一个小型应用程序,其中通过屏幕上的按钮更新或删除 TextField
文本。我已经利用了这篇帖子 能够移动插入符号并添加文本。我可以在 TextField
中添加和删除字符,但是当向 TextField
添加 n 个字符时,则 n数量被删除 当您尝试添加另一个字符时,会发生 IndexOutOfBoundsException
,因为插入符位置(当所有字符都被删除时)在它应该是 0 的时候变成 1。我不知道为什么它在它应该是 1 的时候变成 1是 0。我做错了什么 这里?
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Pane panel = new Pane();
VBox box = new VBox();
TextField tf = new TextField();
Button characterButton = new Button("a");
Button deleteChar = new Button("delete");
box.getChildren().addAll(tf, characterButton, deleteChar );
panel.getChildren().add(box);
root.getChildren().add(panel);
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
//handle caret pos
AtomicInteger caretPos = new AtomicInteger();
tf.caretPositionProperty().addListener((obs, oldVal, newVal) -> {
System.out.println("newval" + newVal);
if (tf.isFocused()) {
caretPos.set(newVal.intValue());
System.out.println("Innernewval" + newVal);
}
});
//add character
characterButton.setOnAction(( event) -> {
Button btn = (Button)event.getSource();
System.out.println("Pressed " + btn.getText() + " button");
int pos = caretPos.get();
tf.insertText(pos, btn.getText());
tf.requestFocus();
tf.positionCaret(pos+1);
System.out.println("caretPos on add: " + caretPos.get());
});
//remove character
deleteChar.setOnAction(( event) -> {
Button btn = (Button)event.getSource();
System.out.println("Pressed " + btn.getText() + " button");
int newCaretPos = caretPos.get()-1;
tf.deleteText(newCaretPos, caretPos.get());
tf.requestFocus();
tf.positionCaret(newCaretPos);
System.out.println("caretPos on delete: " + caretPos.get());
});
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
I'm building a small app where TextField
text is updated or deleted via buttons on screen. I have utilised code from this post to be able to move the caret around and add text. I can add and delete characters within the TextField
however when n amount of characters are added to the TextField
then n amount are removed an IndexOutOfBoundsException
occurs when you attempt to add another character as the caret position (when all characters are removed) becomes 1 when it should be 0. I do not know why it becomes 1 when it should be 0. What have I done wrong here?
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Pane panel = new Pane();
VBox box = new VBox();
TextField tf = new TextField();
Button characterButton = new Button("a");
Button deleteChar = new Button("delete");
box.getChildren().addAll(tf, characterButton, deleteChar );
panel.getChildren().add(box);
root.getChildren().add(panel);
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
//handle caret pos
AtomicInteger caretPos = new AtomicInteger();
tf.caretPositionProperty().addListener((obs, oldVal, newVal) -> {
System.out.println("newval" + newVal);
if (tf.isFocused()) {
caretPos.set(newVal.intValue());
System.out.println("Innernewval" + newVal);
}
});
//add character
characterButton.setOnAction(( event) -> {
Button btn = (Button)event.getSource();
System.out.println("Pressed " + btn.getText() + " button");
int pos = caretPos.get();
tf.insertText(pos, btn.getText());
tf.requestFocus();
tf.positionCaret(pos+1);
System.out.println("caretPos on add: " + caretPos.get());
});
//remove character
deleteChar.setOnAction(( event) -> {
Button btn = (Button)event.getSource();
System.out.println("Pressed " + btn.getText() + " button");
int newCaretPos = caretPos.get()-1;
tf.deleteText(newCaretPos, caretPos.get());
tf.requestFocus();
tf.positionCaret(newCaretPos);
System.out.println("caretPos on delete: " + caretPos.get());
});
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码无法编译。您有一个
catch
,但没有try
。在下面的代码中,我删除了 [orphan]catch
块。另外,您的样式表,即文件application.css,与您的问题无关,因此为了使问题中的代码成为最小的、可重现的示例 我建议您删除该部分。它在下面的代码中被注释掉了。当
caretPos
为零并且按下deleteChar
按钮时,我只会收到IndexOutOfBoundsException
。因此,您只需添加处理边缘情况的代码。在下面的代码中,请参阅注释后的部分当'caretPos'为零时处理删除。编辑
你是对的。当我使用 JavaFX 8 运行您的代码时,我确实重现了该问题。经过一些调试后,问题是当
TextField
包含单个字符并且您按deleteChar
时,caretPositionProperty
侦听器不会运行,因此 < code>caretPosition 未更新,并保持值 1(一)而不是 0(零)。这个问题可能有很多解决方法。我选择在事件处理程序中的
System.out.println("caretPos on delete: " + caretPos.get());
行之后添加以下if
语句deleteChar
:为了完整起见,这里是我用来调试程序的代码。
这是当
TextField
包含单个字符并且我按deleteChar
时的输出。如您所见,
caretPositionProperty
侦听器未执行。Your code does not compile. You have a
catch
without atry
. In the below code, I removed the [orphan]catch
block. Also, your style sheet, i.e. file application.css, is not related to your problem so in order to make the code in your question a minimal, reproducible example I suggest that you remove that part. It is commented out in the below code.I only get
IndexOutOfBoundsException
whencaretPos
is zero and I pressdeleteChar
button. Hence you simply need to add code that handles that edge case. In the below code, refer to the part after the comment Handle delete when 'caretPos' is zero.Edit
You are correct. When I run your code with JavaFX 8, I do reproduce the problem. After some debugging, the problem is that when the
TextField
contains a single character and you pressdeleteChar
, thecaretPositionProperty
listener does not run and hencecaretPosition
is not updated and remains with the value 1 (one) instead of 0 (zero).There are probably many workarounds to this problem. I chose to add the below
if
statement after the lineSystem.out.println("caretPos on delete: " + caretPos.get());
in the event handler fordeleteChar
:For the sake of completeness, here is the code I used to debug the program.
Here is the output when
TextField
contains a single character and I pressdeleteChar
.As you can see, the
caretPositionProperty
listener is not executed.