use of org.jabref.gui.util.RecursiveTreeItem in project jabref by JabRef.
the class GroupTreeController method initialize.
@FXML
public void initialize() {
viewModel = new GroupTreeViewModel(stateManager, dialogService, taskExecutor);
// Set-up groups tree
groupTree.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
// Set-up bindings
Consumer<ObservableList<GroupNodeViewModel>> updateSelectedGroups = (newSelectedGroups) -> newSelectedGroups.forEach(this::selectNode);
Consumer<List<TreeItem<GroupNodeViewModel>>> updateViewModel = (newSelectedGroups) -> {
if (newSelectedGroups == null) {
viewModel.selectedGroupsProperty().clear();
} else {
viewModel.selectedGroupsProperty().setAll(newSelectedGroups.stream().map(TreeItem::getValue).collect(Collectors.toList()));
}
};
BindingsHelper.bindContentBidirectional(groupTree.getSelectionModel().getSelectedItems(), viewModel.selectedGroupsProperty(), updateSelectedGroups, updateViewModel);
viewModel.filterTextProperty().bind(searchField.textProperty());
groupTree.rootProperty().bind(EasyBind.map(viewModel.rootGroupProperty(), group -> new RecursiveTreeItem<>(group, GroupNodeViewModel::getChildren, GroupNodeViewModel::expandedProperty, viewModel.filterPredicateProperty())));
// Icon and group name
mainColumn.setCellValueFactory(cellData -> cellData.getValue().valueProperty());
mainColumn.setCellFactory(new ViewModelTreeTableCellFactory<GroupNodeViewModel, GroupNodeViewModel>().withText(GroupNodeViewModel::getDisplayName).withIcon(GroupNodeViewModel::getIconCode, GroupNodeViewModel::getColor).withTooltip(GroupNodeViewModel::getDescription));
// Number of hits
PseudoClass anySelected = PseudoClass.getPseudoClass("any-selected");
PseudoClass allSelected = PseudoClass.getPseudoClass("all-selected");
numberColumn.setCellFactory(new ViewModelTreeTableCellFactory<GroupNodeViewModel, GroupNodeViewModel>().withGraphic(group -> {
final StackPane node = new StackPane();
node.getStyleClass().setAll("hits");
if (!group.isRoot()) {
BindingsHelper.includePseudoClassWhen(node, anySelected, group.anySelectedEntriesMatchedProperty());
BindingsHelper.includePseudoClassWhen(node, allSelected, group.allSelectedEntriesMatchedProperty());
}
Text text = new Text();
text.textProperty().bind(group.getHits().asString());
text.getStyleClass().setAll("text");
node.getChildren().add(text);
node.setMaxWidth(Control.USE_PREF_SIZE);
return node;
}));
// Arrow indicating expanded status
disclosureNodeColumn.setCellValueFactory(cellData -> cellData.getValue().valueProperty());
disclosureNodeColumn.setCellFactory(new ViewModelTreeTableCellFactory<GroupNodeViewModel, GroupNodeViewModel>().withGraphic(viewModel -> {
final StackPane disclosureNode = new StackPane();
disclosureNode.visibleProperty().bind(viewModel.hasChildrenProperty());
disclosureNode.getStyleClass().setAll("tree-disclosure-node");
final StackPane disclosureNodeArrow = new StackPane();
disclosureNodeArrow.getStyleClass().setAll("arrow");
disclosureNode.getChildren().add(disclosureNodeArrow);
return disclosureNode;
}).withOnMouseClickedEvent(group -> event -> group.toggleExpansion()));
// Set pseudo-classes to indicate if row is root or sub-item ( > 1 deep)
PseudoClass rootPseudoClass = PseudoClass.getPseudoClass("root");
PseudoClass subElementPseudoClass = PseudoClass.getPseudoClass("sub");
// Pseudo-classes for drag and drop
PseudoClass dragOverBottom = PseudoClass.getPseudoClass("dragOver-bottom");
PseudoClass dragOverCenter = PseudoClass.getPseudoClass("dragOver-center");
PseudoClass dragOverTop = PseudoClass.getPseudoClass("dragOver-top");
groupTree.setRowFactory(treeTable -> {
TreeTableRow<GroupNodeViewModel> row = new TreeTableRow<>();
row.treeItemProperty().addListener((ov, oldTreeItem, newTreeItem) -> {
boolean isRoot = newTreeItem == treeTable.getRoot();
row.pseudoClassStateChanged(rootPseudoClass, isRoot);
boolean isFirstLevel = (newTreeItem != null) && (newTreeItem.getParent() == treeTable.getRoot());
row.pseudoClassStateChanged(subElementPseudoClass, !isRoot && !isFirstLevel);
});
row.setDisclosureNode(null);
row.disclosureNodeProperty().addListener((observable, oldValue, newValue) -> row.setDisclosureNode(null));
row.contextMenuProperty().bind(EasyBind.monadic(row.itemProperty()).map(this::createContextMenuForGroup).orElse((ContextMenu) null));
row.setOnDragDetected(event -> {
TreeItem<GroupNodeViewModel> selectedItem = treeTable.getSelectionModel().getSelectedItem();
if ((selectedItem != null) && (selectedItem.getValue() != null)) {
Dragboard dragboard = treeTable.startDragAndDrop(TransferMode.MOVE);
dragboard.setDragView(row.snapshot(null, null));
ClipboardContent content = new ClipboardContent();
content.put(DragAndDropDataFormats.GROUP, selectedItem.getValue().getPath());
dragboard.setContent(content);
event.consume();
}
});
row.setOnDragOver(event -> {
Dragboard dragboard = event.getDragboard();
if ((event.getGestureSource() != row) && row.getItem().acceptableDrop(dragboard)) {
event.acceptTransferModes(TransferMode.MOVE, TransferMode.LINK);
removePseudoClasses(row, dragOverBottom, dragOverCenter, dragOverTop);
switch(getDroppingMouseLocation(row, event)) {
case BOTTOM:
row.pseudoClassStateChanged(dragOverBottom, true);
break;
case CENTER:
row.pseudoClassStateChanged(dragOverCenter, true);
break;
case TOP:
row.pseudoClassStateChanged(dragOverTop, true);
break;
}
}
event.consume();
});
row.setOnDragExited(event -> {
removePseudoClasses(row, dragOverBottom, dragOverCenter, dragOverTop);
});
row.setOnDragDropped(event -> {
Dragboard dragboard = event.getDragboard();
boolean success = false;
if (dragboard.hasContent(DragAndDropDataFormats.GROUP)) {
String pathToSource = (String) dragboard.getContent(DragAndDropDataFormats.GROUP);
Optional<GroupNodeViewModel> source = viewModel.rootGroupProperty().get().getChildByPath(pathToSource);
if (source.isPresent()) {
source.get().draggedOn(row.getItem(), getDroppingMouseLocation(row, event));
success = true;
}
}
if (dragboard.hasContent(DragAndDropDataFormats.ENTRIES)) {
TransferableEntrySelection entrySelection = (TransferableEntrySelection) dragboard.getContent(DragAndDropDataFormats.ENTRIES);
row.getItem().addEntriesToGroup(entrySelection.getSelection());
success = true;
}
event.setDropCompleted(success);
event.consume();
});
return row;
});
// Filter text field
setupClearButtonField(searchField);
}
Aggregations