我正在構建一個小應用程式,TextField通過螢屏上的按鈕更新或洗掉文本。我已經利用這篇文章中的代碼來移動插入符號并添加文本。我可以在其中添加和洗掉字符,TextField但是當將n個字符添加到TextField然后洗掉nIndexOutOfBoundsException個字符時,當您嘗試添加另一個字符時發生,因為插入符號位置(當所有字符都被洗掉時)在應該為 0 時變為 1 .我不知道為什么它應該是0的時候變成了1。我在這里做錯了什么?
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);
}
}
uj5u.com熱心網友回復:
您的代碼無法編譯。你有一個catch沒有一個try。在下面的代碼中,我洗掉了 [orphan]catch塊。此外,您的樣式表,即檔案application.css與您的問題無關,因此為了使您問題中的代碼成為最小的、可重現的示例,我建議您洗掉該部分。它在下面的代碼中被注釋掉了。
我只有IndexOutOfBoundsException在caretPos為零并且按下deleteChar按鈕時才得到。因此,您只需添加處理該邊緣情況的代碼。在下面的代碼中,請參考注釋句柄洗掉后的部分,當 'caretPos' 為零時。
import javafx.application.Application;
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;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
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");
// Handle delete when 'caretPos' is zero.
if (caretPos.get() == 0) {
if (tf.getText().isEmpty()) {
return; // Nothing to delete.
}
else {
caretPos.set(1); // Ensure 'newCaretPos' will not be negative.
}
}
int newCaretPos = caretPos.get() - 1;
tf.deleteText(newCaretPos, caretPos.get());
tf.requestFocus();
tf.positionCaret(newCaretPos);
caretPos.set(newCaretPos);
System.out.println("caretPos on delete: " caretPos.get());
});
}
}
編輯
你是對的。當我使用 JavaFX 8 運行您的代碼時,我確實重現了該問題。經過一些除錯,問題是當TextField包含單個字符并且您按deleteChar時,caretPositionProperty偵聽器不會運行,因此caretPosition不會更新并保持值 1(一)而不是 0(零)。
這個問題可能有很多解決方法。我選擇在事件處理程式if的行之后添加以下陳述句:System.out.println("caretPos on delete: " caretPos.get());deleteChar
if (tf.getText().isEmpty()) {
caretPos.set(0);
}
For the sake of completeness, here is the code I used to debug the program.
import java.util.concurrent.atomic.AtomicInteger;
import javafx.application.Application;
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;
import javafx.stage.Stage;
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();
System.out.println("### DBUG ### -> Adding: [Before 'insertText'] pos = " pos);
tf.insertText(pos, btn.getText());
System.out.println("### DBUG ### -> Adding: [Before 'requestFocus'] pos = " pos);
tf.requestFocus();
System.out.println("### DBUG ### -> Adding: [Before 'positionCaret'] pos = " pos);
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;
System.out.println("### DBUG ### -> Deleting: [Before 'deleteText'] newCaretPos = " newCaretPos);
tf.deleteText(newCaretPos, caretPos.get());
System.out.println("### DBUG ### -> Deleting: [Before 'requestFocus'] newCaretPos = " newCaretPos);
tf.requestFocus();
System.out.println("### DBUG ### -> Deleting: [Before 'positionCaret'] newCaretPos = " newCaretPos);
tf.positionCaret(newCaretPos);
System.out.println("caretPos on delete: " caretPos.get());
if (tf.getText().isEmpty()) {
caretPos.set(0);
}
});
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Here is the output when TextField contains a single character and I press deleteChar.
newval0
Pressed delete button
### DBUG ### -> Deleting: [Before 'deleteText'] newCaretPos = 0
### DBUG ### -> Deleting: [Before 'requestFocus'] newCaretPos = 0
### DBUG ### -> Deleting: [Before 'positionCaret'] newCaretPos = 0
caretPos on delete: 1
As you can see, the caretPositionProperty listener is not executed.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/442304.html
上一篇:哪個組框是一個被點擊的按鈕。C#
