【问题标题】:Javafx, TextArea caret doesn't move back to first line on clearJavafx,TextArea 插入符号不会移回第一行清除
【发布时间】:2015-03-23 15:50:03
【问题描述】:

在清除 textarea 中的文本后,我很难将光标设置回第一行的位置 0。

问题背景

我有一个textarea,它监听键事件。 textarea 只监听Enter 键,如果找到,要么提交文本,要么在文本区域中有“\n”时清除文本。

我尝试了以下所有方法,但都没有真正奏效。

  • textArea.setText("")
  • textArea.clear()
  • textArea.getText().replace("\n", "")
  • 从中移除焦点并重新放回去。

这是一个可运行并演示问题的测试项目。

主类:

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

控制器类:

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>

我的问题是,光标不会跳回来...

【问题讨论】:

  • 你的问题不是很清楚。您是否要从文本区域中删除所有文本?还是只是将光标移到开头?
  • 删除所有内容(适用于 .setText(""))并将光标移回左上角(但光标仍停留在第二行,尽管将 Text 设置为空字符串) .
  • 我无法重现。请创建并发布MCVE
  • 我可以在Ubuntu 14.04 + Java 8u40 上重现该问题。我已经编辑并添加了一个 MCVE,以帮助未来的观众。

标签: javafx textarea


【解决方案1】:

我找到了一个简短的解决方案:在我调用所需的方法 (handleAsk()) 后,它应该在完成后清除文本区域,我调用:keyEvent.consume(); 这会消耗 ENTER 的默认效果。

所以:首先,您明确定义的事件处理程序完成了它的工作,然后您可以决定是否要将给定键事件的默认效果作为“副作用”,如果没有,您可以使用它.

【讨论】:

    【解决方案2】:

    因此,您的密钥处理程序将在文本更改之前调用(由于键入的内容),或者将在文本更改后调用。

    您大概希望它之前会被调用,否则

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

    (或其他一些实现,例如使用正则表达式)。

    【讨论】:

    • 啊,其实,单看源码,我觉得是key typed event。反正就是在按键事件之后发生的事件……
    猜你喜欢
    • 2019-05-28
    • 2015-04-13
    • 2016-09-15
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多