我在JavaFX 2.1中面临TableView的问题。我想根据数据禁用TableRow。
例如:
public class RowData() {
private String name;
private boolean used;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isUsed(){
return this.used;
}
public void setUsed(boolean used) {
this.used = used;
}
}
在节目中:
public class ViewController implements Initializable {
@FXML
private TableView<RowData> tableAttribute;
public void initialize(URL location, ResourceBundle resources) {
List<RowData> data = new ArrayList<RowData>();
// datatype col
TableColumn<DataRow, String> attNameCol = new TableColumn<DataRow, DataRow>(
"Name");
attNameCol
.setCellValueFactory(new PropertyValueFactory<DataRow, String>(
"name"));
attNameCol .setMinWidth(110.0);
tableComponent.getColumns().addAll(attNameCol );
loadData(data);
tableAttribute.setItems(FXCollections.observableList(data));
//I want to disable row which used = true, enable otherwise
}
}
我该如何做到这一点?
答案 0 :(得分:6)
根据行字段的值禁用行的示例策略:
我创建了一个使用第二个原则的sample app。
示例中的关键逻辑是在活动阶段上显示表之后执行的以下代码,它根据需要启用和禁用行(以及将样式类应用于每一行,以便如果需要,他们可以单独设置样式)。请注意,对于此方法,如果表中的行发生更改或重新排序,则在重新呈现表之后,必须在表上重新运行查找和启用/禁用代码,以便正确设置表的样式并且具有正确的行禁用属性。
// highlight the table rows depending upon whether we expect to get paid.
int i = 0;
for (Node n: table.lookupAll("TableRow")) {
if (n instanceof TableRow) {
TableRow row = (TableRow) n;
if (table.getItems().get(i).getWillPay()) {
row.getStyleClass().add("willPayRow");
row.setDisable(false);
} else {
row.getStyleClass().add("wontPayRow");
row.setDisable(true);
}
i++;
if (i == table.getItems().size())
break;
}
}
当使用fxml控制器时,lookupAll返回0“TableRow”节点。似乎在执行查找行之后,在table.setItems(data)之后填充了为什么?
在回答这个问题之前,我会注意到使用rowFactory确实是这个问题的首选解决方案,而不是使用查找。其中一些原因将在本答案的其余部分中显而易见。有关rowFactory方法的示例,请参阅此linked sample code by james-d。
查找是一种CSS操作,它要求将css应用于正在查找的节点。要明确应用css,请在将节点放入场景后调用applyCss。
控制器的一个难点是,在初始化调用中,节点可能还不在场景中。要解决该问题,您可以应用以下模式:
Pane parent = (Pane) table.getParent();
parent.getChildren().remove(table);
Scene applyCssScene = new Scene(table);
table.applyCss();
table.layout();
applyCssScene.setRoot(null);
if (parent != null) {
// Assumes that the original order in the parent does not matter.
// If it did, you would also need to keep track of the child list position.
parent.getChildren().add(table);
}
. . .
// perform css based lookup operation on the table.
这将创建一个包含表格的虚拟持有人场景,应用CSS(之后基于CSS的查找操作将起作用)然后从场景中删除表格,以便您可以在以后将其添加到真实场景中之后将桌子放回原来的父母身边。你可能已经注意到这有点令人困惑。请注意,我没有尝试在带有FXML控制器的示例应用程序中实际执行上面概述的CSS应用程序进程,但我相信它会起作用。
在我使用查找链接的示例应用程序中,不需要上述复杂性,因为在最初显示包含该表的阶段之后进行查找。 stage.show()调用隐式运行要显示的场景上的布局和css应用程序传递(它需要这样做以根据初始场景的计算大小确定舞台的初始大小,并且可能出于其他原因)。