根据数据禁用TableRow [英] Disable TableRow based on data

查看:68
本文介绍了根据数据禁用TableRow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JavaFX 2.1中遇到TableView问题.我想基于数据禁用TableRow.

I face a problem with TableView in JavaFX 2.1. I want to disable TableRow based on data.

例如:

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

    }
}

我该怎么做?

推荐答案

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

Example strategies for disabling a row based on the value of a row field:

  1. 使用 lookupAll TableRows,并根据需要将其呈现为禁用状态.
  1. Use a rowFactory which renders the row content as disabled as needed.
  2. After the table has been shown, lookupAll the TableRows and render them as disabled as appropriate.

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

I create a sample app which uses the second principle.

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

The key logic in the sample is the following code executed after the table has been shown on an active stage, which enables and disables rows as needed (as well as applying style classes to each row so that they can be styled separately if required). Note, for this approach, if the rows in the table change or are reordered, then the lookup and enabling/disabling code will have to be re-run over the table after the table has been re-rendered so that the table is correctly styled and has the correct disabled properties for rows.

// 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)之后执行查找行时会填充为什么?

When using a fxml controller the lookupAll return 0 "TableRow" nodes. It seems that after table.setItems(data) when doing lookup rows are populated why ?

在回答这个问题之前,我会注意到,使用rowFactory实际上是此问题的首选解决方案,而不是使用查找.在该答案的其余部分中,为什么会变得显而易见的一些原因.有关rowFactory方法的示例,请参阅以下通过james-d链接的示例代码

Before answering this, I will note that using a rowFactory is really the preferred solution to this question, rather than using a lookup. Some of the reasons why will become apparent in the rest of this answer. For a sample of a rowFactory approach, please refer to this linked sample code by james-d.

查找是一项CSS操作,它要求将css应用于要查找的节点.要明确应用CSS,请调用 applyCss 将节点放置到场景中之后.

A lookup is a CSS operation and it requires that css has been applied to the nodes being looked up. To explicitly apply css, call applyCss after the node has been placed in a scene.

控制器的一个困难是,在初始化调用中,该节点可能尚未出现在场景中.要变通解决此问题,您可以应用以下模式:

A difficulty with a controller is that, in the initialize call, the node might not yet be in a scene. To work around that issue you can apply the following pattern:

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

This creates a dummy holder scene with the table in it, applies CSS (after which CSS based lookup operations will work) and then removes the table from the scene so that you can add it to the real scene at a later time and afterwards places the table back in it's original parent. As you may have noted this is a bit confusing. Note that I didn't try to actually execute the CSS application process outlined above in an example application with an FXML controller, however I believe it will work.

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

In the sample app I linked which uses lookups, the above complexity is not needed because the lookup is made after the stage containing the table has been initially shown. The stage.show() call implicitly runs layout and css application passes on the scene to be shown (it needs to do this to determine the initial size of the stage based upon the calculated size of the initial scene and perhaps for other reasons).

这篇关于根据数据禁用TableRow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆