JavaFX的表视图行上色
问题描述:
我有这个简单的代码:JavaFX的表视图行上色
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application
{
@Override
public void start(Stage stage) throws Exception
{
TableView<Integer> table = new TableView<>();
TableColumn<Integer, Integer> column = new TableColumn<>();
column.setCellValueFactory(param -> new SimpleObjectProperty<>(param.getValue()));
ObservableList<Integer> items = FXCollections.observableArrayList();
table.getColumns().add(column);
table.setItems(items);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
for (int i = 0; i < 500; i++)
items.add((int) (Math.random() * 500));
BooleanProperty disable = new SimpleBooleanProperty();
table.setRowFactory(param ->
{
TableRow<Integer> row = new TableRow<>();
row.disableProperty().bind(disable);
row.disableProperty().addListener((observable, oldValue, newValue) ->
{
if (newValue)
row.setStyle("-fx-background-color: red");
else
row.setStyle("");
});
return row;
});
Button button = new Button("Disable all rows");
button.setOnAction(event -> disable.set(true));
stage.setScene(new Scene(new VBox(table, button)));
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
当我运行它,然后按下按钮,就应该颜色的所有行。它可以工作,直到你向下滚动表格。然后,一些奇怪的事情开始发生,有些行不会变得丰富多彩,当您向后滚动时,它们将变得丰富多彩,而其他一些行则不会。
但是当你先滚动,然后按下按钮,它会正常工作。我不知道那里发生了什么,这对我来说似乎是一个错误。
在原始代码中,我需要禁用某些行,因为我需要禁用表格复选框。尽管如此,即使我们将disable属性切换到editable属性也不起作用。
有没有人有一个想法如何解决这个问题,为什么它不工作?
答
当您滚动时,表格可能需要创建几行。如果在按下按钮后创建行,则您将第一个绑定新行的disable
属性到您创建的布尔属性(因此该行的disable属性设置为true),然后您向该行注册了一个侦听器禁用更改样式的属性。由于行的禁用属性在注册侦听器后永远不会更改,因此永远不会调用它,并且样式永远不会更改。
你可以做
table.setRowFactory(param ->
{
TableRow<Integer> row = new TableRow<>();
row.disableProperty().addListener((observable, oldValue, newValue) ->
{
if (newValue)
row.setStyle("-fx-background-color: red");
else
row.setStyle("");
});
row.disableProperty().bind(disable);
return row;
});
,或者你也可以只使用一个直接绑定:
table.setRowFactory(param ->
{
TableRow<Integer> row = new TableRow<>();
row.styleProperty().bind(Bindings
.when(disable)
.then("-fx-background-color: red;")
.otherwise(""));
row.disableProperty().bind(disable);
return row;
});
,或者你可以使用一个外部的样式表
.table-row-cell:disabled {
-fx-background-color:red ;
}
,并省略听众/完全绑定风格:
table.setRowFactory(param ->
{
TableRow<Integer> row = new TableRow<>();
row.disableProperty().bind(disable);
return row;
});