3

I am testing JavaFX 2.1 and trying to get editable table views to behave the way I would like them to.

I'm using the example from the JavaFX 2 documentation as a base :http://docs.oracle.com/javafx/2/ui_controls/table-view.htm

The example has 2 problems:

  1. The user is forced to click on a cell 3 times in order to edit it, once to select the row, once to select the cell and make it editable and a further click to focus the TextField
  2. The changes are only committed when the enter key is pressed, if the mouse is clicked outside of the cell, then the data entered in the cell is lost.

On the other hand, one feature that does work correctly, is that I can select text, and re-position the caret within the TextField using the mouse as many times as I like.

There are 2 questions here relating to both of these issues individually:

Java FX 2 Table Cell Editing and Focus

and

javafx 2.1 Updating TableView

When the answer to first question is applied on it's own, I only have to click once to edit the cell (after the row has been selected) and I can still select text and move the caret.

When the answer to the second question is applied on it's own, the edit is committed without the enter key being pressed, but I can only re-position the caret or select text once, if I try a second time, then the edit is committed.

When I apply both answers together, focus is applied successfully and edits are committed when the mouse is clicked away, but I lose the ability to re-position the caret or select text entirely. Any mouse click within the cell commits the edit.

My question is how can I fix the original 2 issues without losing the ability to position the caret and select text?

Community
  • 1
  • 1
ajames
  • 813
  • 8
  • 8

2 Answers2

1

Try jkaufmann's sample app in his answer to his own question TableView - Better Editing through Binding? His binding solution and implementation of TableView editing semantics seems to adequately address all concerns you raise in your question.

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • That's exactly what I needed, thanks :) Now I just need to get my head around how and why it works so I can replicate it in my own app. – ajames Jun 27 '12 at 08:11
1

You need to modify the GUI component at the correct time in the spirit of the JavaFX framework. i.e. in the controls layoutChildren method. You need to override the layoutChildren method of the custom TableCell and set the cursor position then e.g.

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

I also note that Java 1.8.0_241 also contains this problem in the TextFieldTableCell implementation. Worse TextField is completely private to the TextFieldTableCell implementation, so in order to work around that I chose to copy the source of javax.scene.table.cell.TextFieldTableCell and javax.scene.table.cell.CellUtils. TextField is instantiated in CellUtils, so you can fix the cursor positioning there. 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;
        }
      };
  ...

  ...
  }