//package com.oracle.javafx;

import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TreeTableViewSelectedItemsDemo extends Application { 

    private TreeItem<Map<String, Object>> root; 
    private TreeTableView<Map<String, Object>> tree; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
        VBox outer = new VBox(); 

        root = new TreeItem<>(); 
        tree = new TreeTableView<>(root); 
        tree.setShowRoot(false); 
        tree.setRowFactory(this::rowFactory); 
        addColumn("Region", "region"); 
        addColumn("Type", "type"); 
        addColumn("Pop.", "population"); 
        setupData(); 
        tree.getSelectionModel().getSelectedItems().addListener((ListChangeListener.Change<? extends TreeItem<Map<String, Object>>> c) -> { 
            while (c.next()) { 
                if (c.wasAdded()) { 
                    System.out.println("bug : " + c.getAddedSubList()); 
                    c.getAddedSubList().forEach((item) -> System.out.println("bug origin: " + item.getChildren())); 
                } 
            } 
        }); 
        outer.getChildren().addAll(tree); 
        Scene scene = new Scene(outer, 640, 480); 
        primaryStage.setScene(scene); 
        primaryStage.show(); 
    } 

    private TreeTableRow<Map<String, Object>> rowFactory(TreeTableView<Map<String, Object>> view) { 
        TreeTableRow<Map<String, Object>> row = new TreeTableRow<>(); 

        return row; 
    } 

    private void setupData() { 
        TreeItem<Map<String, Object>> europe = createItem(root, "Europe", "continent", 742500000L); 
        TreeItem<Map<String, Object>> austria = createItem(europe, "Austria", "country", 847400L); 
        createItem(austria, "Tyrol", "state", 728537L); 
        createItem(europe, "Russia ", "country", 144031000); 
        createItem(europe, "Germany ", "country", 81276000); 
        createItem(europe, "Turkey ", "country", 78214000); 
        createItem(europe, "France ", "country", 67063000); 
        createItem(europe, "Italy ", "country", 60963000); 
        createItem(europe, "Spain ", "country", 46335000); 
        createItem(europe, "Ukraine ", "country", 42850000); 
        createItem(europe, "Poland ", "country", 38494000); 
        createItem(europe, "Romania ", "country", 19822000); 
        createItem(europe, "Kazakhstan ", "country", 17543000); 
        createItem(europe, "Netherlands ", "country", 16933000); 
        createItem(europe, "Belgium ", "country", 11259000); 
        createItem(europe, "Greece ", "country", 10769000); 
        createItem(europe, "Portugal ", "country", 10311000); 
        createItem(europe, "Hungary ", "country", 9835000); 
        createItem(europe, "Sweden ", "country", 9794000); 
        createItem(europe, "Azerbaijan ", "country", 9651000); 
        createItem(europe, "Belarus ", "country", 9481000); 
        createItem(europe, "Switzerland ", "country", 8265000); 
        createItem(europe, "Bulgaria ", "country", 7185000); 
        createItem(europe, "Serbia ", "country", 7103000); 
        createItem(europe, "Denmark ", "country", 5673000); 
        createItem(europe, "Finland ", "country", 5475000); 
        createItem(europe, "Slovakia ", "country", 5426000); 
        createItem(europe, "Norway ", "country", 5194000); 
        createItem(europe, "Ireland ", "country", 4630000); 
        createItem(europe, "Croatia ", "country", 4230000); 
        createItem(europe, "Bosnia and Georgia ", "country", 3707000); 
        createItem(europe, "Moldova ", "country", 3564000); 
        createItem(europe, "Armenia ", "country", 3010000); 
        createItem(europe, "Lithuania ", "country", 2906000); 
        createItem(europe, "Albania ", "country", 2887000); 
        createItem(europe, "Macedonia ", "country", 2071000); 
        createItem(europe, "Slovenia ", "country", 2065000); 
        createItem(europe, "Latvia ", "country", 1979000); 
        createItem(europe, "Kosovo ", "country", 1867000); 
        createItem(europe, "Estonia ", "country", 1315000); 
        createItem(europe, "Cyprus ", "country", 876000); 
        createItem(europe, "Montenegro ", "country", 620000); 
        createItem(europe, "Luxembourg ", "country", 570000); 
        createItem(europe, "Transnistria ", "country", 505153); 
        createItem(europe, "Malta ", "country", 425000); 
        createItem(europe, "Iceland ", "country", 331000); 
        createItem(europe, "Jersey (UK) ", "country", 103000); 
        createItem(europe, "Andorra ", "country", 78000); 
        createItem(europe, "Guernsey (UK) ", "country", 66000); 
        createItem(europe, "Liechtenstein ", "country", 37000); 
        createItem(europe, "Monaco ", "country", 37000); 
        TreeItem<Map<String, Object>> america = createItem(root, "America", "continent", 953700000L); 
        createItem(america, "USA", "country", 318900000L); 
        createItem(america, "Mexico", "country", 122300000L); 
    } 

    private TreeItem<Map<String, Object>> createItem(TreeItem<Map<String, Object>> parent, String region, String type, long population) { 
        TreeItem<Map<String, Object>> item = new TreeItem<>(); 
        Map<String, Object> value = new HashMap<>(); 
        value.put("region", region); 
        value.put("type", type); 
        value.put("population", population); 
        item.setValue(value); 
        parent.getChildren().add(item); 
        item.setExpanded(true); 
        return item; 
    } 

    protected void addColumn(String label, String dataIndex) { 
        TreeTableColumn<Map<String, Object>, String> column = new TreeTableColumn<>(label); 
        column.setPrefWidth(150); 
        column.setCellValueFactory( 
                (TreeTableColumn.CellDataFeatures<Map<String, Object>, String> param) -> { 
                    ObservableValue<String> result = new ReadOnlyStringWrapper(""); 
                    if (param.getValue().getValue() != null) { 
                        result = new ReadOnlyStringWrapper("" + param.getValue().getValue().get(dataIndex)); 
                    } 
                    return result; 
                } 
        ); 
        tree.getColumns().add(column); 
    } 

    public static void main(String[] args) { 
        launch(args); 
    } 

} 