[更新注:我本來使用的TreeItem
子類中的解決方案。此處顯示的解決方案比原始的要乾淨得多。]
創建一個ObservableSet<TreeItem<?>>
,其中包含應該突出顯示的TreeItem
。然後在單元工廠中觀察該單元格和單元格treeItemProperty()
,並設置樣式類別(我在下面的示例中使用了PseudoClass
),以便單元格在屬於該單元格的樹項目位於集合中時突出顯示。
最後,註冊mouseEntered
和mouseExited
處理與細胞。當鼠標進入單元格時,您可以獲取樹項目,使用它導航到您需要的任何其他樹項目,並將相應的項目添加到您定義的集合中。在mouseExited
處理程序中,清除集合(或根據需要執行其他邏輯)。
import java.util.HashSet;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class HighlightingTree extends Application {
private final PseudoClass highlighted = PseudoClass.getPseudoClass("highlighted");
@Override
public void start(Stage primaryStage) {
TreeView<Integer> tree = new TreeView<>();
tree.setRoot(buildTreeRoot());
ObservableSet<TreeItem<Integer>> highlightedItems = FXCollections.observableSet(new HashSet<>());
tree.setCellFactory(tv -> {
// the cell:
TreeCell<Integer> cell = new TreeCell<Integer>() {
// indicates whether the cell should be highlighted:
private BooleanBinding highlightCell = Bindings.createBooleanBinding(() ->
getTreeItem() != null && highlightedItems.contains(getTreeItem()),
treeItemProperty(), highlightedItems);
// listener for the binding above
// note this has to be scoped to persist alongside the cell, as the binding
// will use weak listeners, and we need to avoid the listener getting gc'd:
private ChangeListener<Boolean> listener = (obs, wasHighlighted, isHighlighted) ->
pseudoClassStateChanged(highlighted, isHighlighted);
// anonymous constructor: register listener with binding
{
highlightCell.addListener(listener);
}
};
// display correct text:
cell.itemProperty().addListener((obs, oldItem, newItem) -> {
if (newItem == null) {
cell.setText(null);
} else {
cell.setText(newItem.toString());
}
});
// mouse listeners:
cell.setOnMouseEntered(e -> {
if (cell.getTreeItem() != null) {
highlightedItems.add(cell.getTreeItem());
highlightedItems.addAll(cell.getTreeItem().getChildren());
}
});
cell.setOnMouseExited(e -> highlightedItems.clear());
return cell ;
});
BorderPane uiRoot = new BorderPane(tree);
Scene scene = new Scene(uiRoot, 600, 600);
scene.getStylesheets().add("highlight-tree-children.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private TreeItem<Integer> buildTreeRoot() {
return buildTreeItem(1);
}
private TreeItem<Integer> buildTreeItem(int n) {
TreeItem<Integer> item = new TreeItem<>(n);
if (n < 10_000) {
for (int i = 0; i<10; i++) {
item.getChildren().add(buildTreeItem(n * 10 + i));
}
}
return item ;
}
public static void main(String[] args) {
launch(args);
}
}
亮點,樹children.css:
.tree-cell:highlighted {
-fx-background: yellow ;
}
James_D:首先感謝您對顯而易見的思想和考慮,你把這個問題。讓我精神上審查你的迴應並回復你。 – funkyjive 2014-12-04 20:04:54
我強烈建議只跳轉到第二個(更新)版本。爲了完整起見,我將原件留在那裏,但也許我應該刪除它。 – 2014-12-04 20:16:51
詹姆斯,我做到了。我剛剛嘗試過,而且這真的是我以後的事情。非常好!謝謝。 – funkyjive 2014-12-04 21:09:31