Sort TreeView by name


Question

I have this very simple example of TreeView.

import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;

public class TreeTableViewSample extends Application {

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

    @Override
    public void start(Stage stage) {
        stage.setTitle("Tree Table View Samples");
        final Scene scene = new Scene(new Group(), 200, 400);
        Group sceneRoot = (Group)scene.getRoot();  

        //Creating tree items
        final TreeItem<String> childNode1 = new TreeItem<>("Child Node 1");
        final TreeItem<String> childNode2 = new TreeItem<>("Child Node 2");
        final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3");

        //Creating the root element
        final TreeItem<String> root = new TreeItem<>("Root node");
        root.setExpanded(true);   

        //Adding tree items to the root
        root.getChildren().setAll(childNode1, childNode2, childNode3);        

        //Creating a column
        TreeTableColumn<String,String> column = new TreeTableColumn<>("Column");
        column.setPrefWidth(150);   

        //Defining cell content
        column.setCellValueFactory((CellDataFeatures<String, String> p) -> 
            new ReadOnlyStringWrapper(p.getValue().getValue()));  

        //Creating a tree table view
        final TreeTableView<String> treeTableView = new TreeTableView<>(root);
        treeTableView.getColumns().add(column);
        treeTableView.setPrefWidth(152);
        treeTableView.setShowRoot(true);             
        sceneRoot.getChildren().add(treeTableView);
        stage.setScene(scene);
        stage.show();
    }     
}

I'm interested how I can sort the tree nodes by name?

Is this functionality already implemented in JavaFX or I need to implement custom tree cell?

Is there any example that I can use?

1
3
9/21/2014 2:26:14 PM

By default, the items on every TableColumn can be sorted just by clicking on its header, once or twice, to get the default sort order (ascending or descending by default).

The default comparator is String.compareTo, which compares two strings lexicographically.

But you can implement your own. For instance, this will sort by the length of the strings:

// compare by length of the strings
column.setComparator(Comparator.comparing(String::length));

And this one will sort first by length, then in case of equal length, by name:

// compare by length first, and then lexicographically
column.setComparator(Comparator.comparing(String::length).thenComparing(String::compareTo));

EDIT: Since the example refers to a TreeTableView, but the OP asks for a TreeView, this is how the items can be sorted:

1) Since we are adding a collection of items, we can sort it before adding the children to the root

@Override
public void start(Stage stage) {
    stage.setTitle("Tree Table View Samples");
    final Scene scene = new Scene(new Group(), 200, 400);
    Group sceneRoot = (Group)scene.getRoot();  

    //Creating tree items
    final TreeItem<String> childNode1 = new TreeItem<>("Child Node 10");
    final TreeItem<String> childNode2 = new TreeItem<>("Child Node Two");
    final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3");

    //Creating the root element
    final TreeItem<String> root = new TreeItem<>("Root node");
    root.setExpanded(true);   

    List<TreeItem<String>> list = Arrays.asList(childNode1, childNode2, childNode3);
    // sort by length of the item's names
    list.sort(Comparator.comparing(t->t.getValue().length()));

    //Adding tree items to the root
    root.getChildren().setAll(list);  

    TreeView<String> tree = new TreeView<> (root);     

    sceneRoot.getChildren().add(tree);
    stage.setScene(scene);
    stage.show();        
}

2) Once we have added the items to the root we can provide a Comparator to the root:

@Override
public void start(Stage stage) {
    stage.setTitle("Tree Table View Samples");
    final Scene scene = new Scene(new Group(), 200, 400);
    Group sceneRoot = (Group)scene.getRoot();  

    //Creating tree items
    final TreeItem<String> childNode1 = new TreeItem<>("Child Node 10");
    final TreeItem<String> childNode2 = new TreeItem<>("Child Node Two");
    final TreeItem<String> childNode3 = new TreeItem<>("Child Node 3");

    //Creating the root element
    final TreeItem<String> root = new TreeItem<>("Root node");
    root.setExpanded(true);   

    //Adding tree items to the root
    root.getChildren().setAll(childNode1, childNode2, childNode3);  

    TreeView<String> tree = new TreeView<> (root);     

    // sort by length of the item's names          
    root.getChildren().sort(Comparator.comparing(t->t.getValue().length()));

    sceneRoot.getChildren().add(tree);
    stage.setScene(scene);
    stage.show();        
}
3
9/21/2014 11:12:44 PM

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