mardi 14 février 2023

JavaFX TableView with CheckBoxes: retrieve the rows whose checkboxes are checked

I've been searching for a while, but all I found seems very old and can't get it to work and I'm very confused.

I have a tableview with a checkbox in a column header (select all) and another checkbox for each row (select row). What I am trying to achieve is to get all the rows whose checkboxes are checked to perform an action.

Here's what it looks like:

enter image description here

And here's the code in my controller:

package com.comparador.controller;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.comparador.ComparadorPreciosApplication;
import com.comparador.entity.Commerce;
import com.comparador.entity.Items;
import com.comparador.entity.ShoppingListPrices;
import com.comparador.repository.CommerceRepository;
import com.comparador.repository.ProductRepository;
import com.comparador.service.ShoppingService;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.converter.IntegerStringConverter;

@Component
public class ShoppingController implements Initializable {
//    @Autowired
//    @Qualifier("lblTitulo")
    private String titulo = "Productos";

    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private CommerceRepository commerceRepository;
    @Autowired
    private ShoppingService shoppingService;

    @FXML
    private Label lblTitulo;
    @FXML
    private Button btBack;
    @FXML
    private TableView<Items> tvProducts;
    @FXML
    private TableColumn<Items, CheckBox> colSelected;       //THE CHECKBOX COLUMN
    @FXML
    private TableColumn<Items, String> colName;
    @FXML
    private TableColumn<Items, Integer> colAmount;
    @FXML
    private TableView<ShoppingListPrices> tvTotalPrices;
    @FXML
    private TableColumn<ShoppingListPrices, String> colCommerce;
    @FXML
    private TableColumn<ShoppingListPrices, Double> colTotal;

    private CheckBox selectAll;
    List<ShoppingListPrices> shoppingList = new ArrayList<>();
    
    
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        colName.setCellValueFactory(new PropertyValueFactory<>("name"));
        colAmount.setCellValueFactory(new PropertyValueFactory<>("amount"));
        colAmount.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
//      colSelected.setCellFactory(CheckBoxTableCell.forTableColumn(colSelected));
//      colSelected.setCellValueFactory(cellData -> new ReadOnlyBooleanWrapper(cellData.getValue().getChecked()));
        colSelected.setCellValueFactory(new PropertyValueFactory<>("selected"));
        colCommerce.setCellValueFactory(new PropertyValueFactory<>("commerceName"));
        colTotal.setCellValueFactory(new PropertyValueFactory<>("total"));
        lblTitulo.setText(titulo);
        tvProducts.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        reloadTableViewProducts();
        
        selectAll = new CheckBox();
        selectAll.setOnAction(event -> {
            event.consume();
            tvProducts.getItems().forEach(item -> {
                item.getSelected().setSelected(selectAll.isSelected());
            });
            
        });
        
        setShoppingList();
        
        colSelected.setGraphic(selectAll);
    }
    
    @FXML
    public void editAmount(CellEditEvent<Items, Integer> event) {
        Items item = event.getRowValue();
        if(event.getTableColumn().getText().equals("Cantidad")) {
            item.setAmount(event.getNewValue());
        }
        setShoppingList();
    }
    
    /*
     * CLICKING ON A CHECKBOX SHOULD CALL THIS METHOD AND ADD THE ROW TO "selectedItems"
     */
    @FXML
    public void setShoppingList() {
        
        List<Items> selectedItems = new ArrayList<>();

        //Before trying this I was selecting each row by Ctrl + Clicking on it
//      List<Items> selectedItems = tvProducts.getSelectionModel().getSelectedItems();
        
        //This didn't seem to work
//      List<ShoppingListItems> selectedItems = tvProducts.getItems().filtered(x->x.getSelected() == true);
        
        
        List<Commerce> commerces = commerceRepository.findByNameContaining("");
        
        ShoppingListPrices pricesMixingCommerces = shoppingService.getCheapestShoppingList(commerces, selectedItems);
        List<ShoppingListPrices> pricesByCommerce = shoppingService.getShoppingListsPerCommerce(commerces, selectedItems);
        
        shoppingList = new ArrayList<>();
        shoppingList.add(pricesMixingCommerces); 
        shoppingList.addAll(pricesByCommerce);
        
        ObservableList<ShoppingListPrices> resultOL = FXCollections.observableArrayList();
        resultOL.addAll(shoppingList);
        tvTotalPrices.setItems(resultOL);
    }
    
    
    @FXML
    public void openShoppingList() throws IOException {
        FXMLLoader loader  = new FXMLLoader(getClass().getResource("/shoppingList.fxml"));
        ShoppingListController shoppingListController = new ShoppingListController();
        loader.setControllerFactory(ComparadorPreciosApplication.applicationContext::getBean);
        loader.setController(shoppingListController);
        shoppingListController.setup(tvTotalPrices.getSelectionModel().getSelectedItem());
        try {
            Scene scene = new Scene(loader.load(), 800, 400, true, SceneAntialiasing.BALANCED);
            Stage stage = new Stage();//(Stage) btBack.getScene().getWindow();
            stage.setUserData(tvTotalPrices.getSelectionModel().getSelectedItem());
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    @FXML
    public void goBack() {
        FXMLLoader loader  = new FXMLLoader(ComparadorPreciosApplication.class.getResource("/index.fxml"));
        loader.setControllerFactory(ComparadorPreciosApplication.applicationContext::getBean);
        try {
            Scene scene = new Scene(loader.load(), 800, 800, false, SceneAntialiasing.BALANCED);
            Stage stage = (Stage) btBack.getScene().getWindow();
            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    private void reloadTableViewProducts() {
        List<String> productNames = productRepository.findOnProductPerName("");
        List<Items> items = new ArrayList<>();
        for(String name : productNames) {
            //items.add(new Items(new SimpleBooleanProperty(false), name, 1));
            Items item = new Items((CheckBox) new CheckBox(), name, 1);
            item.getSelected().setSelected(false);
            items.add(item);
        }
        ObservableList<Items> itemsOL = FXCollections.observableArrayList();
        itemsOL.addAll(items);
        tvProducts.setItems(itemsOL);
    }
}



Aucun commentaire:

Enregistrer un commentaire