如何设置与选定行相邻的 TableView 行的样式?
How can I style a TableView row adjacent to a selected row?
如何设置与当前所选行相邻的 TableView 行的样式?
我想这样做的原因是在选中行时更改行周围边框的颜色,包括顶部和底部。
我目前设置单元格边框(即 table 的网格)样式的方式是在单元格底部设置背景色并插入 1px。本质上,每个单元格绘制自己的底部边框。
这意味着如果我想更改选定行的“顶部”和底部边框,我还需要能够为当前选定单元格上方的单元格设置样式。
您可以向 table 行的索引和 table 的选定索引添加侦听器,这会更新 table 行上的自定义 CSS 伪类:
TableView<MyTableType> table = ... ;
PseudoClass beforeSelected = PseudoClass.getPseudoClass("before-selected");
table.setRowFactory(tv -> {
TableRow<MyTableType> row = new TableRow<>();
ChangeListener<Number> listener = (obs, oldValue, newValue) -> {
if (row.isEmpty()) {
row.pseudoClassStateChanged(beforeSelected, false);
} else {
row.pseudoClassStateChanged(beforeSelected,
row.getIndex() == table.getSelectionModel().getSelectedIndex() - 1);
}
};
row.indexProperty().addListener(listener);
table.getSelectionModel().selectedIndexProperty().addListener(listener);
return row ;
});
然后在您的 CSS 文件中,您可以使用选择器
为所选行之前的 table 行设置样式
.table-row-cell:before-selected {
/* styles here... */
}
这是一个完整的工作示例:
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
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 StyleTest extends Application {
@Override
public void start(Stage stage) throws Exception {
TableView<Item> table = new TableView<>();
PseudoClass beforeSelected = PseudoClass.getPseudoClass("before-selected");
table.setRowFactory(tv -> {
TableRow<Item> row = new TableRow<>();
ChangeListener<Number> listener = (obs, oldValue, newValue) -> {
if (row.isEmpty()) {
row.pseudoClassStateChanged(beforeSelected, false);
} else {
row.pseudoClassStateChanged(beforeSelected,
row.getIndex() == table.getSelectionModel().getSelectedIndex() - 1);
}
};
row.indexProperty().addListener(listener);
table.getSelectionModel().selectedIndexProperty().addListener(listener);
return row ;
});
table.getColumns().add(column("Item", Item::nameProperty));
table.getColumns().add(column("Value", Item::valueProperty));
for (int i=1 ; i <= 100 ; i++) {
table.getItems().add(new Item("Item "+i, i));
}
Scene scene = new Scene(new BorderPane(table));
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
private static <S,T> TableColumn<S,T> column(String title, Function<S, Property<T>> prop) {
TableColumn<S,T> column = new TableColumn<>(title);
column.setCellValueFactory(cellData -> prop.apply(cellData.getValue()));
return column ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
和一个示例 style.css
(只是将前一行涂成绿色...):
.table-row-cell:before-selected {
-fx-background: #00b140 ;
}
如何设置与当前所选行相邻的 TableView 行的样式?
我想这样做的原因是在选中行时更改行周围边框的颜色,包括顶部和底部。
我目前设置单元格边框(即 table 的网格)样式的方式是在单元格底部设置背景色并插入 1px。本质上,每个单元格绘制自己的底部边框。
这意味着如果我想更改选定行的“顶部”和底部边框,我还需要能够为当前选定单元格上方的单元格设置样式。
您可以向 table 行的索引和 table 的选定索引添加侦听器,这会更新 table 行上的自定义 CSS 伪类:
TableView<MyTableType> table = ... ;
PseudoClass beforeSelected = PseudoClass.getPseudoClass("before-selected");
table.setRowFactory(tv -> {
TableRow<MyTableType> row = new TableRow<>();
ChangeListener<Number> listener = (obs, oldValue, newValue) -> {
if (row.isEmpty()) {
row.pseudoClassStateChanged(beforeSelected, false);
} else {
row.pseudoClassStateChanged(beforeSelected,
row.getIndex() == table.getSelectionModel().getSelectedIndex() - 1);
}
};
row.indexProperty().addListener(listener);
table.getSelectionModel().selectedIndexProperty().addListener(listener);
return row ;
});
然后在您的 CSS 文件中,您可以使用选择器
为所选行之前的 table 行设置样式.table-row-cell:before-selected {
/* styles here... */
}
这是一个完整的工作示例:
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
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 StyleTest extends Application {
@Override
public void start(Stage stage) throws Exception {
TableView<Item> table = new TableView<>();
PseudoClass beforeSelected = PseudoClass.getPseudoClass("before-selected");
table.setRowFactory(tv -> {
TableRow<Item> row = new TableRow<>();
ChangeListener<Number> listener = (obs, oldValue, newValue) -> {
if (row.isEmpty()) {
row.pseudoClassStateChanged(beforeSelected, false);
} else {
row.pseudoClassStateChanged(beforeSelected,
row.getIndex() == table.getSelectionModel().getSelectedIndex() - 1);
}
};
row.indexProperty().addListener(listener);
table.getSelectionModel().selectedIndexProperty().addListener(listener);
return row ;
});
table.getColumns().add(column("Item", Item::nameProperty));
table.getColumns().add(column("Value", Item::valueProperty));
for (int i=1 ; i <= 100 ; i++) {
table.getItems().add(new Item("Item "+i, i));
}
Scene scene = new Scene(new BorderPane(table));
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
private static <S,T> TableColumn<S,T> column(String title, Function<S, Property<T>> prop) {
TableColumn<S,T> column = new TableColumn<>(title);
column.setCellValueFactory(cellData -> prop.apply(cellData.getValue()));
return column ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
和一个示例 style.css
(只是将前一行涂成绿色...):
.table-row-cell:before-selected {
-fx-background: #00b140 ;
}