Why JavaFX TreeTableView edit-mode gets undesirably canceled?


Question

Following workflow is intended: User clicks a Button -> At the selected TreeItem a new TreeItem should be created. The selected TreeItem should get expanded and the new TreeItem should be displayed and entering in editing-mode, as displayed in the following screenshot:

enter image description here

Unfortunatly the editing-mode seems to be canceled immediately in 99%, just in really rare cases the cell is staying in editing-mode. I tried implementing my own CellFactories and Editable-Cells, but for this usecase I always end up in the same situation. Anyone knows what I am doing wrong here?

I created a small example to demonstrate the case.

/**
 * Small Example for EditableState not initialized Case.
 * 
 * @author mst
 */
public class TreeTableViewCreateExpandAndEditMain extends Application
{
  @Override
  public void start( final Stage primaryStage )
  {
    TreeItem<Item> root = new TreeItem<>( new Item( 1, "Root" ) );

    TreeItem<Item> item1 = new TreeItem<>( new Item( 2, "Item1" ) );
    TreeItem<Item> item11 = new TreeItem<>( new Item( 3, "Item11" ) );
    TreeItem<Item> item2 = new TreeItem<>( new Item( 4, "Item2" ) );
    TreeItem<Item> item3 = new TreeItem<>( new Item( 5, "Item3" ) );
    TreeItem<Item> item31 = new TreeItem<>( new Item( 6, "Item31" ) );

    root.getChildren().add( item1 );
    item1.getChildren().add( item11 );
    root.getChildren().add( item2 );
    root.getChildren().add( item3 );
    item3.getChildren().add( item31 );

    TreeTableColumn<Item, Integer> columnId = new TreeTableColumn<>( "ColumnId" );
    TreeTableColumn<Item, String> columnName = new TreeTableColumn<>( "ColumnName" );

    columnId.setCellValueFactory( new TreeItemPropertyValueFactory<Item, Integer>( "id" ) );
    columnName.setCellValueFactory( new TreeItemPropertyValueFactory<Item, String>( "name" ) );

    columnName.setCellFactory( TextFieldTreeTableCell.forTreeTableColumn() );

    columnName.setOnEditCommit( new EventHandler<CellEditEvent<Item, String>>()
    {
      @Override
      public void handle( final CellEditEvent<Item, String> event )
      {
        final Item item = event.getRowValue().getValue();
        System.out.println( "Change Item " + item + " from " + event.getOldValue() + " to new value "
            + event.getNewValue() );
        item.setName( event.getNewValue() );
      }
    } );

    final TreeTableView<Item> treeTableView = new TreeTableView<>( root );
    treeTableView.getColumns().add( columnName );
    treeTableView.getColumns().add( columnId );
    treeTableView.setShowRoot( false );
    treeTableView.setColumnResizePolicy( TreeTableView.CONSTRAINED_RESIZE_POLICY );

    treeTableView.setEditable( true );

    BorderPane layout = new BorderPane();

    Button button = new Button( "DoAction!" );
    button.setOnAction( new EventHandler<ActionEvent>()
    {
      @Override
      public void handle( final ActionEvent event )
      {
        /*
         * This Method should create a new node at the currently selected node, expand the selected node and start editing the new created node.
         */
        final TreeItem<Item> selectedItem = treeTableView.getSelectionModel().getSelectedItem();

        final TreeItem<Item> newItem =
            new TreeItem<>( new Item( 100, "newItemFor" + selectedItem.getValue().getName() ) );
        selectedItem.getChildren().add( newItem );

        selectedItem.expandedProperty().set( true );
        final int rowIndex = treeTableView.getRow( newItem );

        treeTableView.edit( rowIndex, columnName );//Does 99% not start or get canceled, why?
      }

    } );

    layout.setCenter( treeTableView );
    layout.setBottom( button );

    Scene scene = new Scene( layout, 400, 400 );
    primaryStage.setScene( scene );
    primaryStage.show();
  }

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

DataClass:

public class Item
{

  private final IntegerProperty id   = new SimpleIntegerProperty();
  private final StringProperty  name = new SimpleStringProperty();

  public Item( final int id, final String name )
  {
    this.id.set( id );
    this.name.set( name );
  }

  public int getId()
  {
    return id.get();
  }

  public String getName()
  {
    return name.get();
  }

  public void setId( final int id )
  {
    this.id.set( id );
  }

  public void setName( final String name )
  {
    this.name.set( name );
  }

  public IntegerProperty idProperty()
  {
    return id;
  }

  public StringProperty nameProperty()
  {
    return name;
  }
}
1
2
6/18/2014 3:55:57 PM

Accepted Answer

Your code worked in 1.8.0_20-ea on XP for me.

I've often had trouble with the table losing focus and other strange behaviour after edits. Sometimes you have to re-focus the table or cell you want. I keep updating java in hopes it will all work one day.

1
6/19/2014 1:39:29 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon