You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX TreeTableView选中行文字颜色异常 求非CSS解决方案

解决TreeTableView自定义单元格颜色后选中行文字不切换为白色的问题

问题核心是:直接通过setTextFill设置的文字颜色会覆盖MODENA主题中选中行的默认白色文字样式——因为节点的直接样式优先级高于CSS样式类。要在不使用CSS的前提下解决,需要监听单元格的选中状态,动态切换文字颜色。

具体实现思路

  1. 在自定义TreeTableCell时,监听其selectedProperty(),当选中状态变化时立即更新文字颜色。
  2. 在updateItem方法中初始化文字时,同步根据当前选中状态设置对应颜色,避免初始状态显示错误。

修改后的完整代码

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class SelectionBarColor extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Person> treeTableView = new TreeTableView<>();

        // 创建姓名列
        TreeTableColumn<Person, String> nameColumn = new TreeTableColumn<>("Name");
        nameColumn.setCellValueFactory(cellData -> cellData.getValue().getValue().nameProperty());

        nameColumn.setCellFactory(param -> new TreeTableCell<Person, String>() {
            {
                // 监听选中状态变化,动态调整文字颜色
                selectedProperty().addListener((obs, oldVal, newVal) -> {
                    if (getItem() != null) {
                        setTextFill(newVal ? Color.WHITE : Color.ORANGE);
                    }
                });
            }

            @Override
            public void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    setText(item);
                    // 根据当前选中状态设置初始颜色
                    setTextFill(isSelected() ? Color.WHITE : Color.ORANGE);
                } else {
                    setText("");
                    setGraphic(null);
                }
            }
        });

        // 创建地址列
        TreeTableColumn<Person, String> addressColumn = new TreeTableColumn<>("Address");
        addressColumn.setCellValueFactory(cellData -> cellData.getValue().getValue().addressProperty());

        // 创建年龄列
        TreeTableColumn<Person, Number> ageColumn = new TreeTableColumn<>("Age");
        ageColumn.setCellValueFactory(cellData -> cellData.getValue().getValue().ageProperty());

        ageColumn.setCellFactory(param -> new TreeTableCell<Person, Number>() {
            {
                // 监听选中状态变化
                selectedProperty().addListener((obs, oldVal, newVal) -> {
                    if (getItem() != null && getItem().doubleValue() != -1) {
                        setTextFill(newVal ? Color.WHITE : Color.BLUE);
                    }
                });
            }

            @Override
            public void updateItem(Number item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    if (item.doubleValue() != -1) {
                        setText(String.valueOf(item.intValue()));
                        // 根据选中状态设置初始颜色
                        setTextFill(isSelected() ? Color.WHITE : Color.BLUE);
                    } else {
                        setText("");
                    }
                    setGraphic(null);
                } else {
                    setText("");
                    setGraphic(null);
                }
            }
        });

        // 设置列宽
        nameColumn.setPrefWidth(150);
        addressColumn.setPrefWidth(200);
        ageColumn.setPrefWidth(100);

        // 添加列到TreeTableView
        treeTableView.getColumns().addAll(nameColumn, addressColumn, ageColumn);

        // 创建根节点
        TreeItem<Person> rootItem = new TreeItem<>(new Person("Persons", "", -1));
        rootItem.getChildren().addAll(
                new TreeItem<>(new Person("Alice", "456 Park Ave", 25)),
                new TreeItem<>(new Person("Bob", "789 Broadway", 35)),
                new TreeItem<>(new Person("Carol", "987 Elm St", 40)),
                new TreeItem<>(new Person("John", "123 Main St", 40))
        );
        rootItem.setExpanded(true);
        treeTableView.setRoot(rootItem);

        Scene scene = new Scene(treeTableView, 500, 300);
        primaryStage.setScene(scene);
        primaryStage.setTitle("JavaFX TreeTableView SelectionBar");
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public static class Person {
        private StringProperty name;
        private StringProperty address;
        private IntegerProperty age;

        public Person(String name, String address, int age) {
            this.name = new SimpleStringProperty(name);
            this.address = new SimpleStringProperty(address);
            this.age = new SimpleIntegerProperty(age);
        }

        public StringProperty nameProperty() {
            return name;
        }

        public StringProperty addressProperty() {
            return address;
        }

        public IntegerProperty ageProperty() {
            return age;
        }
    }
}

关键说明

  • 为每个自定义单元格添加selectedProperty()监听器,确保选中状态变化时实时更新文字颜色。
  • 在updateItem方法中初始化内容时,同步判断单元格选中状态,避免初始加载时颜色显示异常。
  • 该方案完全通过Java代码实现,无需依赖外部CSS文件,满足需求。

内容的提问来源于stack exchange,提问作者tretonis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:05:19