Javafx,TextArea插入符号不会移回第一行
Javafx, TextArea caret doesn't move back to first line on clear
清除 textarea
中的文本后,我很难将光标设置回第一行中的位置 0。
问题背景
我有一个 textarea
,它监听按键事件。 textarea只监听Enter
键,如果找到,要么提交文本,要么清除文本,如果文本区域有“\n”。
我尝试了以下所有方法,但 none 确实有效。
- textArea.setText("")
- textArea.clear()
- textArea.getText().replace("\n", "")
- 将焦点移开,然后再放回去。
这是一个可运行并演示问题的测试项目。
主要class:
public class Main extends Application {
Stage primaryStage;
AnchorPane pane;
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
initMain();
}
public void initMain(){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("main.fxml"));
pane = loader.load();
Controller controller = loader.getController();
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
launch();
}
}
控制器class:
public class Controller {
@FXML
TextArea textArea;
public void initialize() {
textArea.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
if (!textArea.getText().equals("")
&& !textArea.getText().contains("\n")) {
handleSubmit();
}
if (textArea.getText().contains("\n")) {
handleAsk();
}
}
}
});
}
/**
* After the user gives in a short input, that has no \n, the user submits by hitting enter.
* This method will be called, and the cursor jumps over to the beginning of the next line.
*/
public void handleSubmit(){
System.out.println("Submitted");
}
/**
* When this method is calls, the cursor is not in the first line.
* This method should move the cursor to the first position in the first line in the completely
* cleared text area.
*/
public void handleAsk(){
System.out.println("Asking and clearing text area.");
textArea.setText("");
}
}
fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="317.0" prefWidth="371.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<children>
<TextArea fx:id="textArea" layoutX="78.0" layoutY="59.0" prefHeight="114.0" prefWidth="200.0" />
</children>
</AnchorPane>
我的问题是,光标不会跳回...
因此,要么在文本更改之前调用您的密钥处理程序(由于键入内容),要么在文本更改之后调用它。
您可能希望它会在之前被调用,否则
textArea.getText().contains("\n")
将始终评估为 true
(因为用户刚刚按下 Enter 键)。
但在这种情况下,在第二次按 Enter 时,您将清除文本 ,然后再修改 文本。所以你清除文本,然后添加新行(从用户按 Enter)。因此文本区域中的空白行。
您可能不想依赖正在处理的事件的顺序。事实证明,文本在 keyTyped
事件上被修改(我认为),但没有记录,因此真的不能保证。更安全的方法是监听文本的变化,然后统计换行的数量:
textArea.textProperty().addListener((obs, oldText, newText) -> {
int oldNewlines = countNewlines(oldText); // note, can be more efficient by caching this
int numNewlines = countNewlines(newText);
if (numNewlines == 1 && oldNewlines != 1) {
// submit data
} else if (numNewlines == 2) {
textArea.clear();
}
});
有
private int countNewlines(String text) {
int newlines = 0 ;
while (text.indexOf("\n") >= 0) {
newlines++ ;
text = text.substring(text.indexOf("\n") + 1);
}
return newlines ;
}
(或其他一些实现,例如使用正则表达式)。
我找到了一个简短的解决方案:在我调用所需的方法 (handleAsk()) 之后,它应该在完成后清除文本区域,我调用:keyEvent.consume();
这消耗了ENTER的默认效果。
所以:首先,您明确定义的事件处理程序会执行它的工作,然后您可以决定是否要 "side effect" 给定键事件的默认效果,如果不是,您可以食用。
清除 textarea
中的文本后,我很难将光标设置回第一行中的位置 0。
问题背景
我有一个 textarea
,它监听按键事件。 textarea只监听Enter
键,如果找到,要么提交文本,要么清除文本,如果文本区域有“\n”。
我尝试了以下所有方法,但 none 确实有效。
- textArea.setText("")
- textArea.clear()
- textArea.getText().replace("\n", "")
- 将焦点移开,然后再放回去。
这是一个可运行并演示问题的测试项目。
主要class:
public class Main extends Application {
Stage primaryStage;
AnchorPane pane;
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
initMain();
}
public void initMain(){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("main.fxml"));
pane = loader.load();
Controller controller = loader.getController();
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]){
launch();
}
}
控制器class:
public class Controller {
@FXML
TextArea textArea;
public void initialize() {
textArea.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
if (!textArea.getText().equals("")
&& !textArea.getText().contains("\n")) {
handleSubmit();
}
if (textArea.getText().contains("\n")) {
handleAsk();
}
}
}
});
}
/**
* After the user gives in a short input, that has no \n, the user submits by hitting enter.
* This method will be called, and the cursor jumps over to the beginning of the next line.
*/
public void handleSubmit(){
System.out.println("Submitted");
}
/**
* When this method is calls, the cursor is not in the first line.
* This method should move the cursor to the first position in the first line in the completely
* cleared text area.
*/
public void handleAsk(){
System.out.println("Asking and clearing text area.");
textArea.setText("");
}
}
fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="317.0" prefWidth="371.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<children>
<TextArea fx:id="textArea" layoutX="78.0" layoutY="59.0" prefHeight="114.0" prefWidth="200.0" />
</children>
</AnchorPane>
我的问题是,光标不会跳回...
因此,要么在文本更改之前调用您的密钥处理程序(由于键入内容),要么在文本更改之后调用它。
您可能希望它会在之前被调用,否则
textArea.getText().contains("\n")
将始终评估为 true
(因为用户刚刚按下 Enter 键)。
但在这种情况下,在第二次按 Enter 时,您将清除文本 ,然后再修改 文本。所以你清除文本,然后添加新行(从用户按 Enter)。因此文本区域中的空白行。
您可能不想依赖正在处理的事件的顺序。事实证明,文本在 keyTyped
事件上被修改(我认为),但没有记录,因此真的不能保证。更安全的方法是监听文本的变化,然后统计换行的数量:
textArea.textProperty().addListener((obs, oldText, newText) -> {
int oldNewlines = countNewlines(oldText); // note, can be more efficient by caching this
int numNewlines = countNewlines(newText);
if (numNewlines == 1 && oldNewlines != 1) {
// submit data
} else if (numNewlines == 2) {
textArea.clear();
}
});
有
private int countNewlines(String text) {
int newlines = 0 ;
while (text.indexOf("\n") >= 0) {
newlines++ ;
text = text.substring(text.indexOf("\n") + 1);
}
return newlines ;
}
(或其他一些实现,例如使用正则表达式)。
我找到了一个简短的解决方案:在我调用所需的方法 (handleAsk()) 之后,它应该在完成后清除文本区域,我调用:keyEvent.consume(); 这消耗了ENTER的默认效果。
所以:首先,您明确定义的事件处理程序会执行它的工作,然后您可以决定是否要 "side effect" 给定键事件的默认效果,如果不是,您可以食用。