Javafx 2 基于数据禁用TableRow

Javafx 2 基于数据禁用TableRow,javafx-2,Javafx 2,我在JavaFX2.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 t

我在JavaFX2.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

    }
}
公共类ViewController实现可初始化{
@FXML
私有表视图表属性;
公共void初始化(URL位置、ResourceBundle资源){
列表数据=新的ArrayList();
//数据类型列
TableColumn attNameCol=新TableColumn(
“名称”);
阿特纳梅科尔
.setCellValueFactory(新属性ValueFactory(
"姓名);;
attNameCol.setMinWidth(110.0);
tableComponent.getColumns().addAll(attNameCol);
装载数据(数据);
setItems(FXCollections.observableList(数据));
//我想禁用used=true的行,否则启用
}
}

如何实现这一点?

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

  • 使用可根据需要将行内容呈现为禁用的
  • 在显示表后,将显示表行,并根据需要将其呈现为禁用状态 我创建了一个使用第二个原则的

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

    // 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(数据)之后进行查找时会填充行,为什么

    在回答这个问题之前,我会注意到使用rowFactory确实是解决这个问题的首选方法,而不是使用查找。其中的一些原因将在本答案的其余部分变得显而易见。有关rowFactory方法的示例,请参考此

    查找是一种CSS操作,它要求已将CSS应用于正在查找的节点。要显式应用css,请在将节点放置到场景中后调用

    控制器的一个困难是,在初始化调用中,节点可能还不在场景中。要解决该问题,您可以应用以下模式:

    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应用程序过程,但是我相信它会起作用


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

    我想您的解决方案应该在正常情况下有效,但在我的情况下,它不起作用,因为我在表格单元格中有2个Combobox和1个checkbox。我尝试使用你提供的两种方法设置,但没有成功。我错过了什么吗?我链接的示例应用程序是否如您所期望的那样禁用行?如果是这样,我相信这种方法应该适合您的代码,因为单元格的内容对于基于查找的方法并不重要。对于rowFactory方法,您只需要注意通过row factory正确呈现行。不幸的是,这些行未按预期禁用。我使用了第一种方法(设置cellFactory)。我将尝试使用第二种方法,稍后再通知您。事实上,您是正确的,基于FXML控制器的方法将比原始示例稍微复杂一些。我添加了一些解释,解释了为什么以及如何调整解决方案以在FXML控制器中执行。Hassam,在没有看到代码的情况下,很难回答您的调试问题。我也不是基于row工厂方法的专家。也许你可以问一个新的问题,并在其中加入一个问题,这样你就可以得到更多的帮助。