[英]JavaFX: Apply text color to TableCell using custom style sheet?
JavaFX: How can I apply text color to a TableCell using a custom style sheet? JavaFX: 如何使用自定义样式表将文本颜色应用于TableCell?
It works fine, when I use setTextFill()
in my CellFactory directly, but I want to apply custom style using an external CSS file. 当我直接在我的CellFactory中使用setTextFill()
时,它工作正常,但我想使用外部CSS文件应用自定义样式。 I could prove that my CSS class is applied, since the font becomes bold. 我可以证明我的CSS类已应用,因为字体变为粗体。 The CSS file's font color, however, is not applied. 但是,不应用CSS文件的字体颜色。
@Override
protected void updateItem(MyObject item, boolean empty) {
super.updateItem(item, empty);
if (null != item) {
// EITHER:
this.getStyleClass().add("styleImportant"); // Does NOT set color.
// OR:
this.setTextFill(Color.RED); // Does set color.
}
else {
this.getStyleClass().remove("styleImportant");
}
}
Style sheet: 样式表:
.styleImportant {
-fx-font-weight: bold; /** Does work. */
-fx-text-fill: red; /** Does NOT work. */
}
It is somehow related to specificity of CSS selectors, but I did not manage to find any valid setup. 它在某种程度上与CSS选择器的特异性有关,但我没有找到任何有效的设置。
Edit: I managed to apply both, a custom text color and background color, using CSS. 编辑:我设法使用CSS同时应用自定义文本颜色和背景颜色。 My implementation now uses a Label
that is wrapped in a VBox
to make the background color fill the entire table cell. 我的实现现在使用包裹在VBox
的Label
来使背景颜色填充整个表格单元格。 However, I still had some issues with background color not being cleared when removing the custom style. 但是,在删除自定义样式时,仍然存在一些未清除背景颜色的问题。
Is there any better solution than applying a clear style ? 有没有比应用清晰风格更好的解决方案?
colExample.setCellFactory(new Callback<TableColumn<Example, Example>, TableCell<Example, Example>>() {
@Override
public TableCell<Example, Example> call(TableColumn<Example, Example> tableColumn) {
return new TableCell<Example, Example>() {
private VBox container;
private Label text;
// Anonymous constructor
{
this.container = new VBox();
this.text = this.createLabel();
this.container.getChildren().add(this.text);
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
this.setStyle("-fx-padding: -1 -1 -1 -1;"); // Remove padding from cell
this.setGraphic(this.container);
}
private final Label createLabel() {
Label label = new Label();
VBox.setVgrow(label, Priority.ALWAYS);
label.setMaxWidth(Double.MAX_VALUE);
label.setMaxHeight(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
return label;
}
@Override
protected void updateItem(Example example, boolean empty) {
super.updateItem(example, empty);
// Reset column styles
if (null != this.text && null != this.text.getStyleClass()) {
String[] possibleStyles = new String[] { "styleImportant", "clearStyle" };
for (String style: possibleStyles) {
if (this.text.getStyleClass().contains(style)) {
// Will not reset background, even though style is removed?
this.text.getStyleClass().remove(style);
}
}
// Apply reset style to clear background color
this.text.getStyleClass().add("clearStyle");
}
if (null != example) {
this.text.setText(example.getContent());
if (example.isImportant()) {
this.text.getStyleClass().add("styleImportant");
}
}
}
};
}
});
My style sheet: 我的样式表:
/** Keep black text color, when user selects row */
.table-row-cell:focused {
-fx-dark-text-color: #000000;
-fx-mid-text-color: #000000;
-fx-light-text-color: #000000;
}
/** Style to reset background color */
.clearStyle {
-fx-background-color: transparent;
}
/** Style for important cells */
.styleImportant {
/** Red text color on any background */
-fx-dark-text-color: #FF0000;
-fx-mid-text-color: #FF0000;
-fx-light-text-color: #FF0000;
-fx-background-color: #FF9999;
}
As José points out in his answer, if you are setting a graphic in your cell, you (probably) need to apply the css style class to the graphic (depending on what that graphic is). 正如José在他的回答中指出的那样,如果你在单元格中设置图形,你(可能)需要将css样式类应用于图形(取决于图形是什么)。 If you are simply calling setText(...)
your code should work. 如果您只是调用setText(...)
您的代码应该可以工作。
The reason that a Label
set as the graphic doesn't inherit -fx-text-fill
from the table cell is that the Label
also has a setting for -fx-text-fill
. 设置为图形的Label
不会从表格单元格继承-fx-text-fill
的原因是Label
还具有-fx-text-fill
。 In the default stylesheet, both TableCell
and Label
have this set as follows: 在默认样式表中, TableCell
和Label
都具有以下设置:
-fx-text-fill: -fx-text-background-color ;
fx-text-background-color
is a looked-up color that is defined as a ladder, as follows: fx-text-background-color
是一种被定义为梯形的查找颜色 ,如下所示:
-fx-text-background-color: ladder(
-fx-background,
-fx-light-text-color 45%,
-fx-dark-text-color 46%,
-fx-dark-text-color 59%,
-fx-mid-text-color 60%
);
This (fairly complex) setting means that the value of -fx-text-background-color
depends on the value of -fx-background
. 这个(相当复杂的)设置意味着-fx-text-background-color
的值取决于-fx-background
的值。 If -fx-background
is less than 45% of maximum intensity (ie it's dark), the value of -fx-text-background-color
is set to -fx-light-text-color
. 如果-fx-background
小于最大强度的45%(即它是暗的),则-fx-text-background-color
值设置为-fx-light-text-color
。 If -fx-background
is between 46% and 59% intensity, the value is equal to -fx-drak-text-color
. 如果-fx-background
强度介于46%和59%之间,则该值等于-fx-drak-text-color
。 If it is 60% or more, it's set to -fx-mid-text-color
. 如果它是60%或更多,则设置为-fx-mid-text-color
。 The idea here is that the text color will automatically adjust to the background to remain visible. 这里的想法是文本颜色将自动调整为背景以保持可见。 The values of -fx-dark-text-color
, -fx-mid-text-color
, and -fx-light-text-color
are set to black, a dark gray (#333), and white, respectively. -fx-dark-text-color
, -fx-mid-text-color
和-fx-light-text-color
分别设置为黑色,深灰色(#333)和白色。
Since Label
does not override the value of -fx-text-background-color
, you can achieve what you need by just changing the value of that for your table cell: 由于Label
不会覆盖-fx-text-background-color
的值,因此只需更改表格单元格的值即可实现所需:
.styleImportant {
-fx-text-background-color: red ;
}
Now this overrides the looked-up color value for the table cell, and since the graphic inside the cell doesn't override that value itself, it inherits it from the cell. 现在,这将覆盖表格单元格的查找颜色值,并且由于单元格内的图形本身不会覆盖该值,因此它会从单元格继承该值。
A more sophisticated way to do this is to redefine the -fx-[light|mid|dark]-text-color
s. 更复杂的方法是重新定义-fx-[light|mid|dark]-text-color
s。 The advantage of this is that the colors will adjust appropriately if you change the background: in particular if the cell is selected you can ensure that the text stays visible: 这样做的好处是,如果更改背景,颜色将适当调整:特别是如果选择了单元格,则可以确保文本保持可见:
.styleImportant {
-fx-light-text-color: white ;
-fx-mid-text-color: #c00 ;
-fx-dark-text-color: red ;
}
Since I don't know what type of object is in the cell, I'll use a Label
. 由于我不知道单元格中的对象类型,我将使用Label
。
This is what you are doing: 这就是你在做什么:
@Override
public void start(Stage primaryStage) {
TableView<Label> table = new TableView<>();
TableColumn<Label,String> column = new TableColumn<>();
column.setCellValueFactory(param -> param.getValue().textProperty());
column.setCellFactory((TableColumn<Label, String> param) -> {
TableCell<Label, String> cell = new TableCell<Label, String>(){
@Override
protected void updateItem(String item, boolean empty){
super.updateItem(item, empty);
if(!empty){
this.getStyleClass().add("styleImportant");
Label label = new Label(item);
setGraphic(label);
}
}
};
return cell;
});
table.getColumns().add(column);
...
}
This will give you bold text, but black. 这将为您提供粗体文字,但黑色。
If you want to have an object (in my case, a Label
) with red text, apply the style sheet to the object: 如果您想要一个带有红色文本的对象(在我的情况下是一个Label
),请将样式表应用于该对象:
@Override
protected void updateItem(String item, boolean empty){
super.updateItem(item, empty);
if(!empty){
Label label = new Label(item);
label.getStyleClass().add("styleImportant");
setGraphic(label);
}
}
EDIT 编辑
This is the full code of the example: 这是示例的完整代码:
@Override
public void start(Stage primaryStage) {
TableView<Label> table = new TableView<>();
ObservableList<Label> data = FXCollections.observableArrayList(
new Label("Some Text"), new Label("Some More Text"));
TableColumn<Label,String> column = new TableColumn<>("Column");
column.setCellValueFactory(param -> param.getValue().textProperty());
column.setCellFactory((TableColumn<Label, String> param) -> {
TableCell<Label, String> cell = new TableCell<Label, String>(){
@Override
protected void updateItem(String value, boolean empty){
super.updateItem(value, empty);
if(!empty){
Label label = new Label(value);
label.getStyleClass().add("styleImportant");
setGraphic(label);
} else {
setGraphic(null);
}
}
};
return cell;
});
column.setPrefWidth(100);
table.getColumns().add(column);
table.setItems(data);
Scene scene = new Scene(table, 300, 250);
scene.getStylesheets().add(getClass().getResource("table.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
where in table.css: table.css中的位置:
.styleImportant {
-fx-font-weight: bold;
-fx-text-fill: red;
}
Running this short sample should look like this: 运行此简短示例应如下所示:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.