Javafx 2 Java FX 2单元格编辑、焦点和文本选择

Javafx 2 Java FX 2单元格编辑、焦点和文本选择,javafx-2,Javafx 2,我正在测试JavaFX2.1,并试图让可编辑表视图按照我希望的方式运行 我使用JavaFX2文档中的示例作为基础: 该示例有两个问题: 用户必须在单元格上单击三次才能编辑它,一次选择行,一次选择单元格并使其可编辑,然后再单击以聚焦文本字段 只有在按下enter键时才会提交更改,如果在单元格外单击鼠标,则单元格中输入的数据将丢失 另一方面,一个正常工作的特性是,我可以选择文本,并使用鼠标在文本字段中重新定位插入符号,次数可以是我喜欢的 这里有两个问题分别与这两个问题有关: 及 当第一个问题的答

我正在测试JavaFX2.1,并试图让可编辑表视图按照我希望的方式运行

我使用JavaFX2文档中的示例作为基础:

该示例有两个问题:

  • 用户必须在单元格上单击三次才能编辑它,一次选择行,一次选择单元格并使其可编辑,然后再单击以聚焦文本字段
  • 只有在按下enter键时才会提交更改,如果在单元格外单击鼠标,则单元格中输入的数据将丢失
  • 另一方面,一个正常工作的特性是,我可以选择文本,并使用鼠标在文本字段中重新定位插入符号,次数可以是我喜欢的

    这里有两个问题分别与这两个问题有关:

    当第一个问题的答案单独应用时,我只需单击一次即可编辑单元格(选中行后),并且我仍然可以选择文本并移动插入符号

    当第二个问题的答案单独应用时,编辑将在不按enter键的情况下提交,但我只能重新定位插入符号或选择文本一次,如果我再次尝试,则编辑将提交

    当我同时应用这两个答案时,焦点会成功应用,并且当鼠标被单击时会提交编辑,但我无法重新定位插入符号或完全选择文本。单元格内的任何鼠标单击都将提交编辑


    我的问题是,如何在不失去定位插入符号和选择文本的能力的情况下修复最初的两个问题?

    在jkaufmann对自己问题的回答中尝试jkaufmann的示例应用程序他的绑定解决方案和TableView编辑语义的实现似乎充分解决了您在问题中提出的所有问题。

    您需要本着JavaFX框架的精神,在正确的时间修改GUI组件。i、 e.在控件布局子对象方法中。您需要覆盖自定义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;
          }
        }
      };
    
    我还注意到Java1.8.0241在TextFieldTableCell实现中也包含这个问题。更糟糕的是,TextField对于TextFieldTableCell实现是完全私有的,因此为了解决这个问题,我选择复制javax.scene.table.cell.TextFieldTableCell和javax.scene.table.cell.CellUtils的源代码。TextField在CellUtils中实例化,因此可以修复光标在其中的位置。e、 g

      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;
            }
          };
      ...
    
      ...
      }
    
    
    
    static TextField createTextField(最终单元格、最终StringConverter转换器){
    final TextField TextField=新的TextField(getItemText(单元格,转换器)){
    private boolean first=true;
    @重写受保护的void layoutChildren(){
    super.layoutChildren();
    //在文本末尾设置光标插入符号(并清除高亮显示)
    如果(第一){
    这个。结束();
    第一个=假;
    }
    };
    ...
    ...
    }
    
    这正是我所需要的,谢谢:)现在我只需要弄清楚它是如何工作的以及为什么工作的,这样我就可以在我自己的应用程序中复制它了。