简体   繁体   中英

javafx - checkboxes in tableview when one is selected others in row are disabled

I have a tableview with 3 columns with checkboxes. When one checkbox is selected others checkboxes in row are disabled. I have a model class (Pizza) with 3 BooleanProperty, they are linked with these checkboxes. I writed this code, but it is wrong because its disabling a row when one checkbox is selected and cant undo it. Plus observableList with model items from tableview. Code:

private ObservableList<Pizza> finalizePizzaOb =  FXCollections.observableArrayList();                   cl_lowSize.setCellFactory(CheckBoxTableCell.forTableColumn(param -> {
                    if (finalizePizzaOb.get(param).isLowSize()) {
                        row.disableProperty().bind(finalizePizzaOb.get(param).lowSizeProperty().isNotEqualTo(finalizePizzaOb.get(param).mediumSizeProperty().or(
                                finalizePizzaOb.get(param).largeSizeProperty())));

                    }
                    return finalizePizzaOb.get(param).lowSizeProperty();
                }));

                cl_mediumSize.setCellFactory(CheckBoxTableCell.forTableColumn(param -> {
                    if (finalizePizzaOb.get(param).isMediumSize()) {
                        row.disableProperty().bind(finalizePizzaOb.get(param).mediumSizeProperty().isNotEqualTo(finalizePizzaOb.get(param).lowSizeProperty().or(
                                finalizePizzaOb.get(param).largeSizeProperty())));
                    }
                    return finalizePizzaOb.get(param).mediumSizeProperty();
                }));

                cl_largeSize.setCellFactory(CheckBoxTableCell.forTableColumn(param -> {
                    if (finalizePizzaOb.get(param).isLargeSize()) {
                        row.disableProperty().bind(finalizePizzaOb.get(param).largeSizeProperty().isNotEqualTo(finalizePizzaOb.get(param).mediumSizeProperty().or(
                                finalizePizzaOb.get(param).lowSizeProperty())));
                    }
                    return finalizePizzaOb.get(param).largeSizeProperty();
                }));

Thanks!!

This example application has a table view with three columns - two of them are check boxes. When the check box in a column is selected the check box in the other is unselected, and vice-versa. This can be applied to three or more columns with check boxes as per the issue posted.

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.geometry.Insets;
import javafx.collections.*;
import java.util.*;
import javafx.beans.property.*;
public class TableCheckboxesExample extends Application {
    @Override public void start(Stage primaryStage) {
        TableView<Pizza> table = new TableView<>();
        table.setEditable(true);
        table.setItems(getDataRoutine());
        TableColumn<Pizza, String> titleCol = new TableColumn<Pizza, String>("Title");
        titleCol.setCellValueFactory(new PropertyValueFactory<Pizza, String>("title"));
        TableColumn<Pizza, Boolean> meatCol = new TableColumn<Pizza, Boolean>("Meat");
        meatCol.setEditable(true);
        meatCol.setCellValueFactory(new PropertyValueFactory<Pizza, Boolean>("meat"));
        meatCol.setCellFactory(CheckBoxTableCell.forTableColumn(meatCol));
        TableColumn<Pizza, Boolean> vegCol = new TableColumn<Pizza, Boolean>("Veg");
        vegCol.setEditable(true);
        vegCol.setCellValueFactory(new PropertyValueFactory<Pizza, Boolean>("veg"));
        vegCol.setCellFactory(CheckBoxTableCell.forTableColumn(vegCol));
        table.getColumns().addAll(titleCol, meatCol, vegCol);
        VBox vbox = new VBox();
        vbox.setPadding(new Insets(25, 25, 25, 25));
        vbox.getChildren().addAll(table);
        Scene scene = new Scene(vbox, 350, 300);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Pizza table with checkboxes");
        primaryStage.show();
        table.getSelectionModel().select(0);
    }

    private ObservableList<Pizza> getDataRoutine() {
        List<Pizza> pizzas = Arrays.asList(new Pizza("Meat lover"),
                new Pizza("Veggie lover"), new Pizza("Meditarranean"),
                new Pizza("Italian"));
        ObservableList<Pizza> data = FXCollections.observableArrayList();
        data.addAll(pizzas);
        // Add listeners to boolean properties
        for (Pizza pizza : data) {
            pizza.meatProperty().addListener((obs, wasSelected, isSelected) -> {
                pizza.setVeg(wasSelected);
            });
            pizza.vegProperty().addListener((obs, wasSelected, isSelected) -> {
                pizza.setMeat(wasSelected);
            });
        }
        return data;
    }

    public static void main(String[] args) {
        launch(args);
    }

    public class Pizza {
        private SimpleBooleanProperty veg;
        private SimpleBooleanProperty meat;
        private SimpleStringProperty title;
        public Pizza(String title) {
            this.veg = new SimpleBooleanProperty(false);
            this.meat = new SimpleBooleanProperty(false);
            this.title = new SimpleStringProperty(title);
        }
        public boolean isVeg() {
            return veg.get();
        }
        public void setVeg(boolean value) {
            veg.set(value);
        }
        public SimpleBooleanProperty vegProperty() {
            return veg;
        }
        public boolean isMeat() {
            return meat.get();
        }
        public void setMeat(boolean value) {
            meat.set(value);
        }
        public SimpleBooleanProperty meatProperty() {
            return meat;
        }
        public String getTitle() {
            return title.get();
        }
        public void setTitle(String value) {
            this.title.set(value);
        }
        public SimpleStringProperty titleProperty() {
            return title;
        }
    }
}

You probably have to do a bit of "hack" here.

cl_mediumSize.setCellFactory(new CheckBoxTableCell<Pizza, Boolean>() {
    @Override public void updateItem(Boolean item, boolean empty) {
        super.updateItem(item, empty); // Must keep this

        Pizza model = getTableRow().getItem();
        CheckBox cb = (CheckBox) getGraphic();

        if (model == null) return;

        cb.disableProperty().bind(
            Bindings.not(
                getTableView().editableProperty().and(
                getTableColumn().editableProperty()).and(
                editableProperty()))
            .and(
                model.lowSizeProperty().or(
                model.largeSizeProperty()))
            );
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM