JAVAFX:表视图行选择行为
JAVAFX : Tableview row selection behaviour
我有以下代码来设置 TableRow
,
的背景颜色
column.setCellFactory((TableColumn<Model, Integer> p) -> {
ComboBoxTableCell cell = new ComboBoxTableCell(FXCollections.observableArrayList(0, 1)) {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
if(Integer.valueOf(item.toString()) == 1){
getTableRow().setStyle("-fx-background-color: khaki;");
}else if(Integer.valueOf(item.toString()) == 0){
getTableRow().setStyle(null);
}
}
}
};
return cell;
});
问题是当我 select 背景设置为某种颜色的行时,表示 selection 的默认蓝色落后。 (如下图)
如何保留默认的 selection 颜色?
内联样式比 CSS 样式表具有更高的优先级。因此,选定行的背景也被覆盖。背景的构造方式要求您使用指定 -fx-control-inner-background-alt
和 -fx-control-inner-background
代替。
[...].setStyle("-fx-control-inner-background: khaki; -fx-control-inner-background-alt: khaki;")
但是有一个问题更严重:
您从 TableCell
开始设置样式。由于 TableView
负责将项目分配给单元格,因此如果您在不同的列中使用单元格类型,则完成此操作的顺序是一个实现细节,会导致任意结果。即使您只在一列中使用这些单元格,您也永远不会处理单元格变空的情况,因此即使是空单元格也可能仍然包含新颜色。
行样式属于 table 行。
此外,如果您使用 PseudoClass
和 CSS 样式表,您将获得最大的灵活性。
例如
final PseudoClass one = PseudoClass.getPseudoClass("one");
tableView.setRowFactory(t -> new TableRow<Model>() {
private ChangeListener<Integer> listener = (o, oldValue, newValue) -> {
pseudoClassStateChanged(one, newValue == 1);
};
@Override
protected void updateItem(Model model, boolean empty) {
if (getItem() != null) {
getItem().myValueProperty().removeListener(listener);
}
super(model, empty);
if (empty || model == null) {
listener.changed(null, 0, -1);
} else {
model.myValueProperty().addListener(listener);
listener.changed(null, 0, model.getMyValue());
}
}
});
CSS 样式表
.table-row-cell:one {
-fx-control-inner-background: khaki;
-fx-control-inner-background-alt: khaki;
}
此外,您应该使用类型参数来避免将您的项目从 Integer
转换为 String
并返回 Integer
(如果需要,应将其替换为强制转换这样做。在这种情况下,最好不要使用原始类型。)。
final ObservableList<Integer> values = FXCollections.observableArrayList(0, 1);
column.setCellFactory((TableColumn<Model, Integer> p) -> {
ComboBoxTableCell<Model, Integer> cell = new ComboBoxTableCell<Model, Integer>(values) {
@Override
protected void updateItem(Integer item, boolean empty) {
...
}
};
return cell;
});
我有以下代码来设置 TableRow
,
column.setCellFactory((TableColumn<Model, Integer> p) -> {
ComboBoxTableCell cell = new ComboBoxTableCell(FXCollections.observableArrayList(0, 1)) {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
if(Integer.valueOf(item.toString()) == 1){
getTableRow().setStyle("-fx-background-color: khaki;");
}else if(Integer.valueOf(item.toString()) == 0){
getTableRow().setStyle(null);
}
}
}
};
return cell;
});
问题是当我 select 背景设置为某种颜色的行时,表示 selection 的默认蓝色落后。 (如下图)
如何保留默认的 selection 颜色?
内联样式比 CSS 样式表具有更高的优先级。因此,选定行的背景也被覆盖。背景的构造方式要求您使用指定 -fx-control-inner-background-alt
和 -fx-control-inner-background
代替。
[...].setStyle("-fx-control-inner-background: khaki; -fx-control-inner-background-alt: khaki;")
但是有一个问题更严重:
您从 TableCell
开始设置样式。由于 TableView
负责将项目分配给单元格,因此如果您在不同的列中使用单元格类型,则完成此操作的顺序是一个实现细节,会导致任意结果。即使您只在一列中使用这些单元格,您也永远不会处理单元格变空的情况,因此即使是空单元格也可能仍然包含新颜色。
行样式属于 table 行。
此外,如果您使用 PseudoClass
和 CSS 样式表,您将获得最大的灵活性。
例如
final PseudoClass one = PseudoClass.getPseudoClass("one");
tableView.setRowFactory(t -> new TableRow<Model>() {
private ChangeListener<Integer> listener = (o, oldValue, newValue) -> {
pseudoClassStateChanged(one, newValue == 1);
};
@Override
protected void updateItem(Model model, boolean empty) {
if (getItem() != null) {
getItem().myValueProperty().removeListener(listener);
}
super(model, empty);
if (empty || model == null) {
listener.changed(null, 0, -1);
} else {
model.myValueProperty().addListener(listener);
listener.changed(null, 0, model.getMyValue());
}
}
});
CSS 样式表
.table-row-cell:one {
-fx-control-inner-background: khaki;
-fx-control-inner-background-alt: khaki;
}
此外,您应该使用类型参数来避免将您的项目从 Integer
转换为 String
并返回 Integer
(如果需要,应将其替换为强制转换这样做。在这种情况下,最好不要使用原始类型。)。
final ObservableList<Integer> values = FXCollections.observableArrayList(0, 1);
column.setCellFactory((TableColumn<Model, Integer> p) -> {
ComboBoxTableCell<Model, Integer> cell = new ComboBoxTableCell<Model, Integer>(values) {
@Override
protected void updateItem(Integer item, boolean empty) {
...
}
};
return cell;
});