JavaFX 2在表视图中设置插入位置在请求焦点后编辑TextField

时间:2012-10-19 09:56:38

标签: java tableview javafx-2 javafx

在JavaFX 2中,我创建了一个自定义TableCell,它覆盖了startEdit()方法以请求焦点。因此,只要我在单元格上调用编辑命令,就会显示出现的编辑文本字段。

下一步是将插入符号位置设置为文本字段的末尾。但由于不明原因它似乎不起作用。它总是放在第一个字符之前。

这是我到目前为止所尝试的内容:

public void startEdit() {
    if (!isEmpty()) {
        super.startEdit();
        createTextField();
        setText(null);
        textField.end();
        setGraphic(textField);
        ((TextField)getGraphic()).end();
        textField.end();

        Platform.runLater(
                new Runnable() {
                    @Override
                    public void run() {
                        getGraphic().requestFocus();
                    }
                });
    }
}


public void startEdit() {
    if (!isEmpty()) {
        super.startEdit();
        createTextField();
        setText(null);
        setGraphic(textField);
        textField.end();

        Platform.runLater(
                new Runnable() {
                    @Override
                    public void run() {
                        getGraphic().requestFocus();
                        textField.end(); 
                        ((TextField)getGraphic()).end();
                    }
                });
    }
}


public void startEdit() {
    if (!isEmpty()) {
        super.startEdit();

        createTextField();
        setText(null);
        textField.end();
        setGraphic(textField);
        ((TextField)getGraphic()).end();
        getGraphic().requestFocus();
        ((TextField)getGraphic()).end();
        textField.end();
    }
}

逻辑方法是请求专注于文本字段,然后移动插入符号,但它似乎不适用于任何原因。

也许有人可以启发我?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,在尝试了很多不同的事情之后,我终于找到了解决方案。

不要问我为什么,但问题似乎是由为每个编辑创建一个新的TextField引起的。如果您重用现有的文本字段,它就可以工作!

所以试试这个:

public void startEdit() {
    if (!isEmpty()) {
        super.startEdit();

        if (textField == null)
            createTextField();
        else
            textField.setText(getString());

        setText(null);
        setGraphic(textField);

        Platform.runLater(
                new Runnable() {
                    @Override
                    public void run() {
                        textField.requestFocus();
                        textField.deselect(); 
                        textField.end(); 
                    }
                });
    }
}

答案 1 :(得分:-1)

以上两个答案均不能正确解决自定义表单元格的TextField中光标定位的问题。如果您发现上面的方法对您有用,那么恕我直言,这取决于在定位光标之前已经布置好控件的竞争状态。

您需要本着JavaFX框架的精神在正确的时间修改GUI组件。即在控件layoutChildren方法中。例如您需要覆盖自定义TableCell的layoutChildren方法:

TextField textField = new TextField() {
    private boolean first = true;

    @Override protected void layoutChildren() {
      super.layoutChildren();

      // Set cursor caret at end of text (and clear highlighting)
      if (first) {
        this.end();
        first = false;
      }
    }
  };

我还注意到Java 1.8.0_241在TextFieldTableCell实现中也包含此问题。更糟糕的是,TextField完全不属于TextFieldTableCell实现,因此,为了解决该问题,我选择复制javax.scene.table.cell.TextFieldTableCell和javax.scene.table.cell.CellUtils的源。 TextField在CellUtils中实例化,因此您可以将光标定位在该位置。例如

  static <T> TextField createTextField(final Cell<T> cell, final StringConverter<T> converter) {
    final TextField textField = new TextField(getItemText(cell, converter)) {
    private boolean first = true;

      @Override protected void layoutChildren() {
        super.layoutChildren();

        // Set cursor caret at end of text (and clear highlighting)
        if (first) {
          this.end();
          first = false;
        }
      };
  ...

  ...
  }