将样式应用于javaFX中的TreeView子节点

Ale*_*rin 1 css treeview javafx

我正在使用JavaFX TreeView,我想实现一个函数,如果我将鼠标悬停在树项上,该项及其所有子项将被突出显示.

到目前为止,我设法使用setCellFactory突出显示目标项目,如下所示:

treeCell.setOnMouseEntered(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
        redrawTree()
        treeCell.setStyle("-fx-background-color: #0093ff;");
    }
});
Run Code Online (Sandbox Code Playgroud)

结果是:

在此输入图像描述

但我不知道如何定位和应用样式给treeCell的孩子们.此解决方案还需要重新绘制树,这对于大树来说是滞后的.

任何人都可以帮助我前进或给我另类选择吗?我认为css解决方案会更好.

Jam*_*s_D 7

在外部css文件中,执行

.tree-cell:hover {
  -fx-background-color: #0093ff ;
}
Run Code Online (Sandbox Code Playgroud)

另请注意(由于中等复杂的原因)如果使用-fx-background而不是-fx-background-color,文本颜色将对背景颜色的变化作出适当的反应.

要为子节点(即添加到TreeCellgraphic属性中的节点)设置样式,只需执行类似的操作即可

.tree-cell:hover .label {
  /* styles... */
}
Run Code Online (Sandbox Code Playgroud)

这将在"悬停"树细胞内设置所有标签的样式.

这是一个完整的例子:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TreeTest extends Application {  
    @Override  
    public void start(Stage primaryStage) throws Exception {  
        final StackPane stackPane = new StackPane();  

        TreeItem<Integer> root = createTreeItem(1);

        final TreeView<Integer> tree = new TreeView<>(root);  
        tree.setCellFactory(treeView -> {  
            final Label label = new Label();
            final Label anotherLabel = new Label("Item:");
            label.getStyleClass().add("highlight-on-hover");
            final HBox hbox = new HBox(5, anotherLabel, label);
            TreeCell<Integer> cell =  new TreeCell<Integer>() {  
                @Override  
                protected void updateItem(Integer item, boolean empty) {  
                    super.updateItem(item, empty);  
                    if (empty) {
                        setGraphic(null);
                    } else {
                        setGraphic(hbox);
                    }
                }  
            };  
            cell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            cell.itemProperty().addListener((obs, oldItem, newItem) -> 
                label.setText(newItem != null ? String.valueOf(newItem) : ""));
            return cell ;
        });  
        stackPane.getChildren().add(tree);  
        final Scene scene = new Scene(stackPane);  

        scene.getStylesheets().add(getClass().getResource("tree-hover.css").toExternalForm());

        primaryStage.setScene(scene);  
        primaryStage.setTitle(getClass().getSimpleName());  
        primaryStage.show();  
    }  

    private TreeItem<Integer> createTreeItem(int value) {
        TreeItem<Integer> item = new TreeItem<>(value);
        if (value < 10000) {
            for (int i=0; i<10; i++) {
                item.getChildren().add(createTreeItem(10*value+i));
            }
        }
        return item ;
    }

    public static void main(String[] args) {  
        launch(args);  
    }  
}  
Run Code Online (Sandbox Code Playgroud)

使用tree-hover.css文件:

.tree-cell:hover {
    -fx-background-color: #0093ff ;
}

.tree-cell:hover .highlight-on-hover {
    -fx-text-fill: red ;
}
Run Code Online (Sandbox Code Playgroud)