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;
}

}

在程序中:

    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

    }
}

我该怎么做才能做到这一点?

4

1 回答 1

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;
  }
}

使用 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.

这将创建一个包含表格的虚拟持有者场景,应用 CSS(之后基于 CSS 的查找操作将起作用),然后从场景中删除表格,以便您可以稍后将其添加到真实场景中,然后放置表回到它的原始父级。正如您可能已经注意到的那样,这有点令人困惑。请注意,我没有尝试在带有 FXML 控制器的示例应用程序中实际执行上述 CSS 应用程序过程,但我相信它会起作用。

在我链接的使用查找的示例应用程序中,不需要上述复杂性,因为查找是在最初显示包含表的阶段之后进行的。stage.show() 调用隐式运行布局和 css 应用程序传递要显示的场景(它需要这样做以根据初始场景的计算大小确定舞台的初始大小,并且可能出于其他原因)。

于 2012-06-07T06:06:01.850 回答