【问题标题】:How to set row foreground color of a tableView on JavaFX?如何在 JavaFX 中设置 tableView 的行前景色?
【发布时间】:2015-03-26 03:43:29
【问题描述】:

我有一个 tableView,其中有很多项目,在其中一些项目中,我需要将前景色设置为红色。所以它是动态设置的。我成功的是将rowFactory添加到表中并通过css更改背景颜色,但前景没有改变。它总是黑色的:

tableViewAbastecidas.setRowFactory(param -> new TableRow<LeituraPista>() {
    @Override
    protected void updateItem(LeituraPista item, boolean empty) {
        if (item == null) {
            return;
        }
        String estilo;
        if (tableViewAbastecidas.getSelectionModel().getSelectedItems().contains(item)) {
            estilo = "-fx-background-color: linear-gradient(#95caff 0%, #77acff 90%, #e0e0e0 90%);";
        } else {
            estilo = "-fx-background-color: linear-gradient(white 0%, white 90%, #e0e0e0 90%);";
        }
        if (myConditionIsTrue) {
            estilo += "-fx-fill: #ff0000;-fx-text-fill: chartreuse;"; //Doesn't work, always black
        }
        setStyle(estilo);
    }
});

【问题讨论】:

  • 您错过了super.updateItem(item, empty); 电话。不确定这是否是问题所在,但它做了很多重要的“家务”。
  • 我试过打电话给super.updateItem(item,empty),但它似乎不起作用。有趣的是,背景颜色可以正确更改,如果我愿意,我什至可以更改字体和字体大小,但不能更改颜色。
  • @Reegan Miranda,我查看了您的参考资料,只看到他们在表格列上使用 cellFactory 而不是在 tableView 本身上使用 rowFactory。试过了,还是不行。

标签: java javafx javafx-2 javafx-8


【解决方案1】:

根据我的经验,将样式放在外部样式表中总是效果更好。

我认为您遇到的问题是 TableRow 不支持 -fx-text-fill 属性;它由它包含的TableCells 支持。您可以在所有列上设置单元格工厂,但如果您使用外部样式表,则可以操作行的样式类,然后更改其文本填充及其后代(因为 css 样式将由子节点继承) .

由于您使用的是 JavaFX 8,因此您可以使用 PseudoClasss,它的 API 比操作样式类列表更简洁。

所以(我没有直接测试过)

// the string "my-condition" is the name of the pseudoclass and appears in the 
// external css file (see below):
PseudoClass myConditionPseudoClass = PseduoClass.getPseudoClass("my-condition");

tableViewAbastecidas.setRowFactory(param -> new TableRow<LeituraPista>() {
    @Override
    protected void updateItem(LeituraPista item, boolean empty) {
        super.updateItem();
        pseudoClassStateChanged(myConditionPseudoClass,  (! empty) && myCondition);
    }
});

然后你在一个外部 CSS 文件中做所有的样式:

.table-row-cell {
    -fx-background-color: linear-gradient(white 0%, white 90%, #e0e0e0 90%);
}
.table-row-cell:selected {
    -fx-background-color: linear-gradient(#95caff 0%, #77acff 90%, #e0e0e0 90%);
}
.table-row-cell:my-condition .table-cell {
    -fx-fill: #ff0000;
    -fx-text-fill: chartreuse;    
}

这是一个完整的例子:

import java.util.Random;
import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableRowStyleExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Item> table = new TableView<>();

        TableColumn<Item, String> nameCol = new TableColumn<>("Name");
        nameCol.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getName()));

        TableColumn<Item, Number> valueCol = new TableColumn<>("Value");
        valueCol.setCellValueFactory(cellData -> new ReadOnlyIntegerWrapper(cellData.getValue().getValue()));

        table.getColumns().add(nameCol);
        table.getColumns().add(valueCol);

        final Random rng = new Random();
        IntStream.rangeClosed(1, 20)
            .mapToObj( i -> new Item("Item "+i, rng.nextInt(10)+1))
            .forEach(table.getItems()::add);

        PseudoClass highValuePseudoClass = PseudoClass.getPseudoClass("high-value");
        table.setRowFactory(tv -> new TableRow<Item>() {
            @Override
            public void updateItem(Item item, boolean empty) {
                super.updateItem(item, empty);
                pseudoClassStateChanged(highValuePseudoClass, (! empty) && item.getValue() >= 9);
            }
        });

        Scene scene = new Scene(new BorderPane(table), 600, 400);
        scene.getStylesheets().add("table-row-style-example.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Item {
        private final String name ;
        private final int value ;

        public Item(String name, int value) {
            this.name = name ;
            this.value = value ;
        }

        public String getName() {
            return name ;
        }

        public int getValue() {
            return value ;
        }
    }

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

table-row-style-example.css

.table-row-cell {
    -fx-background-color: linear-gradient(white 0%, white 90%, #e0e0e0 90%);
}
.table-row-cell:selected {
    -fx-background-color: linear-gradient(#95caff 0%, #77acff 90%, #e0e0e0 90%);
}
.table-row-cell:high-value .table-cell {
    -fx-text-fill: chartreuse;    
} 

【讨论】:

  • 试过了,伪类被正确触发了,我在.table-row-cell:my-condition里面放了另一个-fx-background-color: pink,背景正确地变成了粉红色,但是字体颜色没有变成#ff0000也没有黄绿色。
  • 查看编辑(在 css 文件中)。显然你必须直接在TableCell 上设置-fx-text-fill(这很容易用CSS 做到)。
  • 伟大的 James_D!诀窍是将-fx-text-fill 放在表格单元格中,而不是表格行中!
  • 这是所有类似问题的最佳答案。它灵活而优雅。非常感谢。
猜你喜欢
  • 2017-12-02
  • 1970-01-01
  • 2011-02-18
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 2017-03-11
相关资源
最近更新 更多