我在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;
}
}
Run Code Online (Sandbox Code Playgroud)
在计划中:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能实现这一目标?
基于行字段值禁用行的示例策略:
我创建了一个使用第二个原则的示例应用程序.
示例中的关键逻辑是在活动阶段上显示表之后执行的以下代码,它根据需要启用和禁用行(以及将样式类应用于每一行,以便在需要时可以单独设置样式).请注意,对于此方法,如果表中的行发生更改或重新排序,则在重新呈现表之后,必须在表上重新运行查找和启用/禁用代码,以便正确设置表的样式并具有正确的行禁用属性.
// 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;
}
}
Run Code Online (Sandbox Code Playgroud)
当使用fxml控制器时,lookupAll返回0"TableRow"节点.看来,在执行查找行之后,table.setItems(data)之后会填充为什么?
在回答这个问题之前,我会注意到使用rowFactory确实是这个问题的首选解决方案,而不是使用查找.其中一些原因将在本答案的其余部分中显而易见.有关rowFactory方法的示例,请参阅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.
Run Code Online (Sandbox Code Playgroud)
这将创建一个包含表格的虚拟持有人场景,应用CSS(之后基于CSS的查找操作将起作用),然后从场景中删除表格,以便您可以在以后将其添加到真实场景中,然后放置表回到原来的父母.你可能已经注意到这有点令人困惑.请注意,我没有尝试在带有FXML控制器的示例应用程序中实际执行上面概述的CSS应用程序进程,但我相信它会起作用.
在我使用查找链接的示例应用程序中,不需要上述复杂性,因为查找是在最初显示包含表的阶段之后进行的.stage.show()调用隐式运行要显示的场景上的布局和css应用程序传递(它需要这样做以根据初始场景的计算大小确定舞台的初始大小,并且可能出于其他原因).