import java.util.ArrayList; import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.CheckBox; import javafx.scene.control.CheckMenuItem; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.SelectionMode; import javafx.scene.control.ToggleButton; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.util.Callback; import javafx.stage.Stage; import javafx.geometry.NodeOrientation; public class TreeTableApp extends Application { public static final int DATA_FIELDS_NUM = 5; public static final int DATA_ITEMS_NUM = 17; Pane content; TreeTableView treeTableView; ObservableList> data; CheckBox multiSelectionCheck; CheckBox singleCellSelectionCheck; public static void main(String args[]) { launch(TreeTableApp.class, args); } @Override public void start(Stage primaryStage) { init(primaryStage); primaryStage.setTitle("TreeTable Test " + System.getProperty("javafx.runtime.version")); primaryStage.show(); } private void init(Stage primaryStage) { Scene scene = getScene(); primaryStage.setScene(scene); } private Scene getScene() { return new TreeTableViewScene(); } public class TreeTableViewScene extends Scene { public TreeTableViewScene() { super(new HBox(5)); multiSelectionCheck = new CheckBox("multi-selection"); singleCellSelectionCheck = new CheckBox("single cell selection"); Pane cont = (Pane) getRoot(); cont.getChildren().add(getTestContainer()); cont.getChildren().add(getControlsContainer()); } } /** * A container containing the tested UI. * * @return */ protected Node getTestContainer() { content = new Pane(); content.setMinSize(500, 500); content.setMaxSize(500, 500); content.setPrefSize(500, 500); treeTableView = new TreeTableView(); treeTableView.setRoot(new TreeItem(new Data("root", DATA_FIELDS_NUM, 0))); treeTableView.getRoot().setExpanded(true); treeTableView.setMinSize(400, 400); treeTableView.setMaxSize(400, 400); treeTableView.setPrefSize(400, 400); reset(DATA_ITEMS_NUM - 1, DATA_FIELDS_NUM, 0);// -1, as we have root. content.getChildren().add(treeTableView); treeTableView.setTranslateX(50); treeTableView.setTranslateY(50); return content; } protected void reset(int rows, int columns, int length) { TreeItem root = new TreeItem(new Data("root", columns, 0)); root.setExpanded(true); treeTableView.setRoot(root); data = treeTableView.getRoot().getChildren(); fill(rows, columns, length); treeTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); multiSelectionCheck.setSelected(false); singleCellSelectionCheck.setSelected(false); } protected void refill(int rows, int columns, int length) { reset(rows, columns, length); } protected void fill(int rowsNum, int columnsNum, int length) { data.clear(); for (int i = 0; i < rowsNum; i++) { data.add(new TreeItem(new Data(String.format("%02d", i), columnsNum, length))); } treeTableView.getColumns().clear(); final ContextMenu contextMenu = new ContextMenu(); for (int i = 0; i < columnsNum; i++) { treeTableView.getColumns().add(createColumn(i, contextMenu)); } treeTableView.setContextMenu(contextMenu); } protected TreeTableColumn createColumn(final int index, final ContextMenu contextMenu) { final TreeTableColumn field = new TreeTableColumn("field " + index); final CheckMenuItem visible = new CheckMenuItem("field " + index); visible.setSelected(field.isVisible()); visible.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { field.setVisible(t1); } }); contextMenu.getItems().add(visible); final ContextMenu columnContextMenu = new ContextMenu(); field.setContextMenu(columnContextMenu); CheckMenuItem sortable = new CheckMenuItem("Sortable"); sortable.setSelected(field.isSortable()); sortable.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { field.setSortable(t1); } }); columnContextMenu.getItems().add(sortable); final MenuItem removeColumn = new MenuItem("Remove column"); removeColumn.setOnAction(new EventHandler() { public void handle(ActionEvent t) { treeTableView.getColumns().remove(field); contextMenu.getItems().remove(visible); } }); columnContextMenu.getItems().add(removeColumn); field.setCellValueFactory(new Callback, ObservableValue>() { public ObservableValue call(TreeTableColumn.CellDataFeatures p) { return ((Data) ((TreeItem) p.getValue()).getValue()).data.get(index); } }); return field; } protected Node getControlsContainer() { VBox res = new VBox(10); res.setTranslateY(50); VBox rtlVBox = new VBox(); ToggleButton rtlButton = new ToggleButton("RTL Orientation"); rtlButton.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { treeTableView.setNodeOrientation(t1 ? NodeOrientation.RIGHT_TO_LEFT : NodeOrientation.INHERIT); } }); rtlVBox.getChildren().add(rtlButton); res.getChildren().add(rtlVBox); HBox multipleSelectionHBox = new HBox(); res.getChildren().add(multipleSelectionHBox); multiSelectionCheck.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { treeTableView.getSelectionModel().setSelectionMode(t1 ? SelectionMode.MULTIPLE : SelectionMode.SINGLE); } }); multipleSelectionHBox.getChildren().add(multiSelectionCheck); singleCellSelectionCheck.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, Boolean t, Boolean t1) { treeTableView.getSelectionModel().setCellSelectionEnabled(t1); } }); multipleSelectionHBox.getChildren().add(singleCellSelectionCheck); return res; } public static class Data { protected String name; protected ArrayList data; public Data(String name, int fieldsNum, int length) { this.name = name; data = new ArrayList(fieldsNum); for (int i = 0; i < fieldsNum; i++) { data.add(new SimpleStringProperty("item " + name + " field " + i + getLongItem(length))); } } public String getName() { return name; } protected String getLongItem(int length) { if (length == 0) { return ""; } String str = " l"; for (int i = 0; i < length; i++) { str += "o"; } return str + "ng"; } } }