4

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

合乎逻辑的方法是请求关注文本字段,然后移动插入符号,但无论出于何种原因,它似乎都不起作用。

也许有人可以启发我?

4

2 回答 2

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(); 
                    }
                });
    }
}
于 2014-10-03T08:43:48.457 回答
-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;
        }
      };
  ...

  ...
  }




于 2020-04-13T20:52:04.890 回答