Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8187309

TreeCell must not change tree's data

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • jfx19
    • 9
    • javafx
    • java9-ea-u180

      TreeViewCell sets the treeItem's value in its commitEdit method: doing so interferes with a custom handler (which may or may not accept the new value). It's clearly breaking the specified behaviour of the edit mechanism and is a singularity in all virtual controls.

      To reproduce, run the example, edit an item such that oldValue.length > newValue.length and commit:

      - expected: oldValue shown in tree
      - actual: newValue shown in tree

      Setting priority to p2, because the behaviour may corrupt data integrity and there's no clean way to get around.

      The example:

      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.TreeItem;
      import javafx.scene.control.TreeView;
      import javafx.scene.control.cell.TextFieldTreeCell;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      /**
       * TreeViewCell: must not interfere with custom commit handler
       */
      public class TreeViewEditCommitInterfere extends Application {

          @Override
          public void start(Stage stage) throws Exception {
              TreeItem<String> rootItem = new TreeItem<>("root");
              TreeItem<String> child = new TreeItem<>("child");
              rootItem.getChildren().add(child);
              TreeView<String> treeView = new TreeView<>(rootItem);
              treeView.setShowRoot(false);
              treeView.setEditable(true);
              treeView.setCellFactory(TextFieldTreeCell.forTreeView());
              // custom commit handler: replace value on some condition only
              treeView.setOnEditCommit(t -> {
                  String ov = t.getOldValue();
                  String nv = t.getNewValue();
                  if (nv.length() > ov.length()) {
                      t.getTreeItem().setValue(nv);
                  }
              });

              Button check = new Button("Print child value");
              check.setOnAction(e -> System.out.println(child.getValue()));
              BorderPane pane = new BorderPane(treeView);
              pane.setBottom(check);
              Scene scene = new Scene(pane, 400, 300);
              stage.setScene(scene);
              stage.show();
          }

          public static void main(String[] args) {
              launch(args);
          }
      }

            fastegal Jeanette Winzenburg
            fastegal Jeanette Winzenburg
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: