我正在开发一个 JavaFX 应用程序,其中有一个 TableView,其中包含一些文本和复选框。
.table-row-cell:selected {
-fx-background-color: rgb(180, 228, 156);
}
.table-row-cell:selected .text {
-fx-fill: black;
}
当我选择一条线时,它是绿色的,但边框是蓝色的,复选框背景也是蓝色的。 如何使用 CSS 更改颜色?
默认样式表 modena.css 使用一系列“查找的颜色”(本质上是 CSS 颜色变量)来定义 JavaFX 应用程序中的颜色。这些查找到的颜色的值可以被覆盖以设置应用程序的样式或“主题”。这些查找到的颜色中只有一小部分是硬编码的;其余的则依赖他人。因此,通过阅读默认的 CSS(仅顶部部分以及表格和复选框上的相关部分),您可以相当容易地确定要更改的少量颜色。
有两个不同的属性可以更改行的外观:选择和焦点。选择意味着在表格的
selectionModel
的意义上选择了该行;焦点表示该行/单元格具有键盘焦点。
聚焦并选定的行具有由查找颜色
-fx-selection-bar
定义的背景颜色,该颜色又设置为 -fx-accent
的值(硬编码的亮蓝色 #0096C9
)。
聚焦控件在
-fx-focus-color
中围绕其绘制“环”,并由 -fx-faint-focus-color
定义小边框。这两个都是硬编码的,分别为 #039ED3
和 #039ED322
(后者只是前者的部分透明版本)。
如果选择了表格行且未获得焦点,则其背景设置为
-fx-selection-bar-non-focused
,默认情况下为浅灰色。您可能也想覆盖它,尽管您没有在问题中指出是否需要更改它。下面的代码将其保留为默认值。
因此,您可以通过设置这三种查找颜色来相当简单地更改表格的颜色:
.table-view {
-fx-accent: rgb(180, 228, 156);
-fx-focus-color: #03D34E;
-fx-faint-focus-color: #03D34E22;
}
请注意,如果您使用选择器
.root
而不是 .table-view
,您会将场景中所有控件的选择突出显示更改为这种一致的颜色。
这是一个完整的可运行示例。我将样式内联放置是为了方便原型设计,但您可能希望在现实生活中将其提取到外部样式表。
package org.jamesd.examples.tableselectionstyle;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.Random;
import java.util.function.Function;
public class HelloApplication extends Application {
private final Random rng = new Random();
private static final String STYLE = "data:text/css," + """
.table-view {
-fx-accent: rgb(180, 228, 156);
-fx-focus-color: #03D34E;
-fx-faint-focus-color: #03D34E22;
}
""";
@Override
public void start(Stage stage) {
TableView<Item> table = new TableView<>();
table.setEditable(true);
for (int i = 1 ; i <= 20; i++) {
table.getItems().add(new Item("Item "+i, rng.nextInt(100)));
}
table.getColumns().add(createColumn("Item", Item::nameProperty));
table.getColumns().add(createColumn("Value", Item::valueProperty));
TableColumn<Item, Boolean> availableCol = createColumn("Available", Item::availableProperty);
availableCol.setCellFactory(CheckBoxTableCell.forTableColumn(availableCol));
table.getColumns().add(availableCol);
BorderPane root = new BorderPane(table);
Scene scene = new Scene(root);
scene.getStylesheets().add(STYLE);
stage.setScene(scene);
stage.show();
}
private static <S,T> TableColumn<S,T> createColumn(String title, Function<S, ObservableValue<T>> property) {
TableColumn<S,T> column = new TableColumn<>(title);
column.setCellValueFactory(data -> property.apply(data.getValue()));
return column;
}
private static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
private final BooleanProperty available = new SimpleBooleanProperty();
Item(String name, int value) {
setName(name);
setValue(value);
}
public final String getName() {
return nameProperty().get();
}
public StringProperty nameProperty() {
return name;
}
public final void setName(String name) {
this.nameProperty().set(name);
}
public final int getValue() {
return valueProperty().get();
}
public IntegerProperty valueProperty() {
return value;
}
public final void setValue(int value) {
this.valueProperty().set(value);
}
public final boolean isAvailable() {
return this.availableProperty().get();
}
public BooleanProperty availableProperty() {
return available;
}
public final void setAvailable(boolean available) {
this.availableProperty().set(available);
}
}
public static void main(String[] args) {
launch();
}
}