根据数据禁用TableRow

Thi*_*hbk 2 javafx-2

我在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)

我该怎么做才能实现这一目标?

jew*_*sea 6

基于行字段值禁用行的示例策略:

  1. 使用rowFactory,根据需要将行内容呈现为已禁用.
  2. 显示表后,查找所有TableRows并根据需要将它们渲染为禁用.

我创建了一个使用第二个原则的示例应用程序.

示例中的关键逻辑是在活动阶段上显示表之后执行的以下代码,它根据需要启用和禁用行(以及将样式类应用于每一行,以便在需要时可以单独设置样式).请注意,对于此方法,如果表中的行发生更改或重新排序,则在重新呈现表之后,必须在表上重新运行查找和启用/禁用代码,以便正确设置表的样式并具有正确的行禁用属性.

// 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应用程序传递(它需要这样做以根据初始场景的计算大小确定舞台的初始大小,并且可能出于其他原因).