Javafx 如何基于tablerow中的布尔属性启用/禁用按钮

Javafx 如何基于tablerow中的布尔属性启用/禁用按钮,javafx,Javafx,正如标题所述,我试图根据表格行数据中的布尔值启用/禁用表格行中的按钮。以下是我目前的代码: col.setCellFactory(new Callback<TableColumn<ExampleRow, String>, TableCell<ExampleRow, String>>() { @Override public TableCell call(final TableColumn<ExampleRow, Strin

正如标题所述,我试图根据表格行数据中的布尔值启用/禁用表格行中的按钮。以下是我目前的代码:

col.setCellFactory(new Callback<TableColumn<ExampleRow, String>, TableCell<ExampleRow, String>>() {
        @Override
        public TableCell call(final TableColumn<ExampleRow, String> param){
            final Button btn = new Button("Save");
            final TableCell<ExampleRow, String> cell = new TableCell<ExampleRow, String>(){

                @Override
                public void updateItem(String item, boolean empty){
                    super.updateItem(item, empty);
                    if(empty){
                        setGraphic(null);
                        setText(null);
                    } else {
                        btn.setPrefWidth(col.getWidth());
                        btn.setPadding(Insets.EMPTY);
                        btn.setOnAction(event -> {

                        });
                        setGraphic(btn);
                        setText(null);
                    }
                }
            };
            ExampleRow row = (ExampleRow)cell.getTableRow().getItem(); //NPE here
            btn.setDisable(!row.hasChanged());
            return cell;
        }
    });
col.setCellFactory(新回调(){
@凌驾
公共TableCell调用(最终TableColumn参数){
最终按钮btn=新按钮(“保存”);
最终TableCell单元格=新TableCell(){
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
if(空){
设置图形(空);
setText(空);
}否则{
btn.setPrefWidth(col.getWidth());
btn.设置填充(插图为空);
btn.设置动作(事件->{
});
设置图形(btn);
setText(空);
}
}
};
ExampleRow row=(ExampleRow)cell.getTableRow().getItem();//此处为NPE
btn.setDisable(!row.hasChanged());
返回单元;
}
});

不幸的是,我的代码在底线的第五位出现了中断。如果我排除该行,并将下面的行更改为
btn.setDisable(true)
,它将非常有效。如何根据按钮所在的数据禁用此按钮?

您无论如何都不会使用该项,因此您可以将其设置为
布尔值,并使用
更改的
属性的值。这允许您启用/禁用
updateItem
方法中的按钮:

例如:

public static class Item {
    private final BooleanProperty changed = new SimpleBooleanProperty();

    public final boolean isChanged() {
        return this.changed.get();
    }

    public final void setChanged(boolean value) {
        this.changed.set(value);
    }

    public final BooleanProperty changedProperty() {
        return this.changed;
    }

}

@Override
public void start(Stage primaryStage) {
    TableView<Item> table = new TableView();
    table.getItems().addAll(new Item(), new Item(), new Item());

    TableColumn<Item, Boolean> column = new TableColumn<>();
    column.setCellValueFactory(cd -> cd.getValue().changedProperty());
    column.setCellFactory(col -> new TableCell<Item, Boolean>() {

        final Button btn = new Button("Save");

        {
            btn.setOnAction(evt -> {
                Item item = (Item) getTableRow().getItem();
                item.setChanged(false);
            });
        }

        @Override
        protected void updateItem(Boolean item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setGraphic(null);
            } else {
                btn.setDisable(!item);
                setGraphic(btn);
            }
        }

    });

    table.getColumns().add(column);

    Button btn = new Button("change");
    btn.setOnAction((ActionEvent event) -> {
        Item item = table.getSelectionModel().getSelectedItem();
        if (item != null) {
            item.setChanged(true);
        }
    });

    VBox root = new VBox(btn, table);

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}
公共静态类项{
private final BooleanProperty changed=新的SimpleBoleanProperty();
公共最终布尔值isChanged(){
返回此.changed.get();
}
公共最终作废集已更改(布尔值){
此.changed.set(值);
}
公共最终布尔属性更改属性(){
返回此文件。已更改;
}
}
@凌驾
公共无效开始(阶段primaryStage){
TableView table=新TableView();
table.getItems().addAll(新项(),新项(),新项());
TableColumn column=新的TableColumn();
column.setCellValueFactory(cd->cd.getValue().changedProperty());
column.setCellFactory(col->new TableCell(){
最终按钮btn=新按钮(“保存”);
{
btn.设置动作(evt->{
Item Item=(Item)getTableRow().getItem();
项目设置已更改(错误);
});
}
@凌驾
受保护的void updateItem(布尔项,布尔空){
super.updateItem(项,空);
if(空| |项==null){
设置图形(空);
}否则{
btn.setDisable(!项);
设置图形(btn);
}
}
});
table.getColumns().add(列);
按钮btn=新按钮(“更改”);
btn.setOnAction((ActionEvent事件)->{
Item=table.getSelectionModel().getSelectedItem();
如果(项!=null){
item.setChanged(真);
}
});
VBox根=新的VBox(btn,表格);
场景=新场景(根);
初级阶段。场景(场景);
primaryStage.show();
}


顺便说一句:
TableView
使用
cellFactory
创建单元格。
表行
属性稍后更新。因此,在
cellFactory
调用
方法本身中检索任何这些值都是没有意义的,因为当时没有分配任何这些值。

您没有以任何方式使用该项,因此您可以将其设置为
布尔值
并使用
更改的
属性的值。这允许您启用/禁用
updateItem
方法中的按钮:

例如:

public static class Item {
    private final BooleanProperty changed = new SimpleBooleanProperty();

    public final boolean isChanged() {
        return this.changed.get();
    }

    public final void setChanged(boolean value) {
        this.changed.set(value);
    }

    public final BooleanProperty changedProperty() {
        return this.changed;
    }

}

@Override
public void start(Stage primaryStage) {
    TableView<Item> table = new TableView();
    table.getItems().addAll(new Item(), new Item(), new Item());

    TableColumn<Item, Boolean> column = new TableColumn<>();
    column.setCellValueFactory(cd -> cd.getValue().changedProperty());
    column.setCellFactory(col -> new TableCell<Item, Boolean>() {

        final Button btn = new Button("Save");

        {
            btn.setOnAction(evt -> {
                Item item = (Item) getTableRow().getItem();
                item.setChanged(false);
            });
        }

        @Override
        protected void updateItem(Boolean item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setGraphic(null);
            } else {
                btn.setDisable(!item);
                setGraphic(btn);
            }
        }

    });

    table.getColumns().add(column);

    Button btn = new Button("change");
    btn.setOnAction((ActionEvent event) -> {
        Item item = table.getSelectionModel().getSelectedItem();
        if (item != null) {
            item.setChanged(true);
        }
    });

    VBox root = new VBox(btn, table);

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}
公共静态类项{
private final BooleanProperty changed=新的SimpleBoleanProperty();
公共最终布尔值isChanged(){
返回此.changed.get();
}
公共最终作废集已更改(布尔值){
此.changed.set(值);
}
公共最终布尔属性更改属性(){
返回此文件。已更改;
}
}
@凌驾
公共无效开始(阶段primaryStage){
TableView table=新TableView();
table.getItems().addAll(新项(),新项(),新项());
TableColumn column=新的TableColumn();
column.setCellValueFactory(cd->cd.getValue().changedProperty());
column.setCellFactory(col->new TableCell(){
最终按钮btn=新按钮(“保存”);
{
btn.设置动作(evt->{
Item Item=(Item)getTableRow().getItem();
项目设置已更改(错误);
});
}
@凌驾
受保护的void updateItem(布尔项,布尔空){
super.updateItem(项,空);
if(空| |项==null){
设置图形(空);
}否则{
btn.setDisable(!项);
设置图形(btn);
}
}
});
table.getColumns().add(列);
按钮btn=新按钮(“更改”);
btn.setOnAction((ActionEvent事件)->{
Item=table.getSelectionModel().getSelectedItem();
如果(项!=null){
item.setChanged(真);
}
});
VBox根=新的VBox(btn,表格);
场景=新场景(根);
初级阶段。场景(场景);
primaryStage.show();
}

顺便说一句:
TableView
使用
cellFactory
创建单元格。
表行
属性稍后更新。因此,在
cellFactory
调用
方法本身中检索任何这些值都没有意义,因为这些值都没有