I'd like to modify the click-behavior of the TreeTableView, but honestly I am not sure what the intended way of doing this has to look like or if it is even ment to be changed in any way.

Most users complained the current behavior wouldn`t be consistent. Sometimes a click on a cell already collapses/expands the treeitem, sometimes a double-click is needed. This together with initalising the edit-mode can be a pain. So I would love to handle the click-behavior myself.

I was able to narrow the behavior down to the TreeTableCellBehavior Class:

@Override
protected void handleClicks(MouseButton button, int clickCount, boolean isAlreadySelected) {
        // handle editing, which only occurs with the primary mouse button
        TreeItem<S> treeItem = getControl().getTreeTableRow().getTreeItem();
        if (button == MouseButton.PRIMARY) {
            if (clickCount == 1 && isAlreadySelected) {
                edit(getControl());
            } else if (clickCount == 1) {
                // cancel editing
                edit(null);
            } else if (clickCount == 2 && treeItem.isLeaf()) {
                // attempt to edit
                edit(getControl());
            } else if (clickCount % 2 == 0) {
                // try to expand/collapse branch tree item
                treeItem.setExpanded(! treeItem.isExpanded());
            }
        }
}

Unfortunatly I don't see any possibilities to create a hook or anything to change this sort of behavior. Since behavior classes and skins are internal classes I dont really see any possibility of creating my own behavior. So has anyone any idea, at what point of TreeTableView I should hook in to modify the click behavior of TreeTableView?


Edit: It seems the Code changed since I posted the Code. So I updated this question. I also found portions of public api access, but still couldn´t figure out how to overwrite the click behavior. Can anyone give me any leads?


Edit2: Because of brians comment I created a small example and compared it with the user experience documentation. It worked as described (=> "Nodes can be opened by clicking on the "turner" icons or by double clicking the node name (note that if editing is enabled, double click will enter the edit mode)."), until I changed the TreeColumn of the TreeTableView to another column then the first one (which was the only difference between my project and example code). Changing the column results in the weird behavior: The turner isn´t reacting anymore on single mouseclicks and sometimes (barely occurs) the selection is not set correctly, instead the node gets expanded/collapsed.

I added a small example to demonstrate the problem:

public class TreeTableViewTurnerIssueExample extends Application
{
  @Override
  public void start( final Stage primaryStage )
  {
    TreeItem<Item> root = new TreeItem<>( new Item( "Root", "Root" ) );

    TreeItem<Item> item1 = new TreeItem<>( new Item( "1", "Item1" ) );
    TreeItem<Item> item2 = new TreeItem<>( new Item( "2", "Item2" ) );
    TreeItem<Item> item3 = new TreeItem<>( new Item( "3", "Item3" ) );
    TreeItem<Item> item4 = new TreeItem<>( new Item( "4", "Item4" ) );
    TreeItem<Item> item41 = new TreeItem<>( new Item( "4.1", "Item41" ) );
    TreeItem<Item> item42 = new TreeItem<>( new Item( "4.2", "Item42" ) );
    TreeItem<Item> item43 = new TreeItem<>( new Item( "4.3", "Item43" ) );
    TreeItem<Item> item5 = new TreeItem<>( new Item( "5", "Item5" ) );
    TreeItem<Item> item52 = new TreeItem<>( new Item( "5.1", "Item51" ) );

    root.getChildren().add( item1 );
    item1.getChildren().add( item2 );
    root.getChildren().add( item3 );
    item3.getChildren().add( item4 );
    item4.getChildren().add( item41 );
    item4.getChildren().add( item42 );
    item4.getChildren().add( item43 );
    root.getChildren().add( item5 );
    item5.getChildren().add( item52 );

    TreeTableColumn<Item, String> nameColumn = new TreeTableColumn<>( "Name" );
    TreeTableColumn<Item, String> valueColumn = new TreeTableColumn<>( "Value" );

    nameColumn.setCellValueFactory( new TreeItemPropertyValueFactory<Item, String>( "name" ) );
    valueColumn.setCellValueFactory( new TreeItemPropertyValueFactory<Item, String>( "value" ) );

    final TreeTableView<Item> treeTableView = new TreeTableView<>( root );
    treeTableView.getColumns().add( nameColumn );
    treeTableView.getColumns().add( valueColumn );

    treeTableView.setTreeColumn( valueColumn );//<- changing this to the first column, the clickbehavior is fine.

    treeTableView.setShowRoot( false );
    treeTableView.setColumnResizePolicy( TreeTableView.CONSTRAINED_RESIZE_POLICY );

    BorderPane layout = new BorderPane();
    layout.setCenter( treeTableView );
    Scene scene = new Scene( layout, 400, 400 );
    scene.getStylesheets().add( getClass().getResource( "application.css" ).toExternalForm() );
    primaryStage.setScene( scene );
    primaryStage.show();
  }

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


public class Item
{
  private final StringProperty name  = new SimpleStringProperty();
  private final StringProperty value = new SimpleStringProperty();

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

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

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

  public StringProperty nameProperty()
  {
    return name;
  }

  public String getValue()
  {
    return value.get();
  }

  public void setValue( final String value )
  {
    this.value.set( value );
  }

  public StringProperty valueProperty()
  {
    return value;
  }
}

I also created a Jira Ticket, since I guess this is indeed a bug, unless anyone can point me to any mistake I made in this example.

有帮助吗?

解决方案 2

It seems this was an offical bug fixed in 8u60 as you can see here: Jira

If you still should want to modify the click behaviour of your TreeTableView you will probably have to go with an EventFilter, delegating the events to your implementation and consume the events. Fortunatly for me the default-behavior will be fine with the fix again, so I stopped further digging.

其他提示

Maybe you can try an event filter. Since i do not know your use case in detail here is a simple example without any error handling to add a MouseEvent EventHandler to the TreeTableView for expanding/collapsing TreeItems by code.

treeTableView.addEventHandler( MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>(){
    @Override
    public void handle( MouseEvent e )
    {
        TreeTableCell<Item, String> cell = (TreeTableCell<Item, String>) e.getTarget();
        TreeItem<Item> item = cell.getTreeTableView().getTreeItem( cell.getTreeTableRow().getIndex() );
        item.setExpanded( !item.isExpanded() );
    }
});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top