Search code examples
javajavafxtableviewfxml

Button icon that changes according to the row of a TableView javafx


I wanted to add a column if the line wasn't empty. In this one I wanted to put buttons with different ImageView to be able to go to an add or view page. I'm trying to change the icon of a button according to the content of my row in a TableView (here if dateR (string) is null) I manage to move it to such and such a page depending on the dateR value, but I can't change the imageView... Thanks

TableColumn<ModelTab4, Void> visualiserAjouter = new TableColumn<ModelTab4, Void>("Visualiser/Ajouter");

        Callback<TableColumn<ModelTab4, Void>, TableCell<ModelTab4, Void>> cellFactory1 = (final TableColumn<ModelTab4, Void> param) -> {
            final TableCell<ModelTab4, Void> cell = new TableCell<ModelTab4, Void>() {
                private String dateR;

                private final Button btn1 = new Button();

                {
                    btn1.setOnAction(click -> {
                        try {
                            ModelTab4 analyse = getTableView().getItems().get(getIndex());
                            dateR = analyse.getDateR();
                            setDate(dateR);
                            idAnalyse = analyse.getNum1();
                            if (dateR!=null){
                                mainApp.goConsultResult(idPerso, idPatient, idAnalyse);
                            }
                            else {
                                mainApp.goAjoutResult(idPerso, idPatient, idAnalyse);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                }
                public void setDate(String date) {
                    this.dateR = date;
                }
                public String getDate() {
                    return dateR;
                }
                public void updateItem(Void item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty) {
                        setGraphic(null);
                    }
                    else {
                        if (getDate()!=null){
                            setGraphic(btn1);
                            ImageView icone1 = new ImageView("consult.png");
                            icone1.setFitHeight(20);
                            icone1.setFitWidth(20);
                            btn1.setGraphic(icone1);
                            setStyle("-fx-alignment : CENTER;");
                        }
                        else if (getDate()==null){
                            setGraphic(btn1);
                            ImageView icone2 = new ImageView("ajout.png");
                            icone2.setFitHeight(20);
                            icone2.setFitWidth(20);
                            btn1.setGraphic(icone2);
                            setStyle("-fx-alignment : CENTER;");
                        }
                    }
                }
            };

            return cell;
        };

Solution

  • Assuming your ModelTab4 class includes the following:

    public class ModelTab4 {
    
        private final StringProperty dateR = new SimpleStringProperty() ;
    
        public StringProperty dateRProperty() {
            return dateR ;
        }
    
        public final String getDateR() {
            return dateRProperty().get();
        }
    
        public final void setDateR(String dateR) {
            dateRProperty().set(dateR);
        }
    
        // other properties ...
    }
    

    you should make the value in the visualiserAjouter column the dateR property:

    TableColumn<ModelTab4, String> visualiserAjouter = new TableColumn<>("Visualiser/Ajouter");
    visualiserAjouter.setCellValueFactory(cellData -> cellData.getValue().dateRProperty());
    

    Now the item in the cell implementation is the dateR property. The issue with the code the way you had it, is that the only way the property changes is after the button is pressed, and there is no notification back to the cell that the value has changed. So in updateItem() you're checking the value of dateR before is has had a chance to change. With the setup above, you can now do:

    final TableCell<ModelTab4, Void> cell = new TableCell<ModelTab4, Void>() {
    
        private final Button btn1 = new Button();
    
        {
            btn1.setOnAction(click -> {
                try {
                    ModelTab4 analyse = getTableView().getItems().get(getIndex());
                    idAnalyse = analyse.getNum1();
                    if (getItem()!=null){
                        mainApp.goConsultResult(idPerso, idPatient, idAnalyse);
                    }
                    else {
                        mainApp.goAjoutResult(idPerso, idPatient, idAnalyse);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        public void updateItem(String dateR, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setGraphic(null);
            }
            else {
                if (dateR!=null){
                    setGraphic(btn1);
                    ImageView icone1 = new ImageView("consult.png");
                    icone1.setFitHeight(20);
                    icone1.setFitWidth(20);
                    btn1.setGraphic(icone1);
                    setStyle("-fx-alignment : CENTER;");
                }
                else if (dateR==null){
                    setGraphic(btn1);
                    ImageView icone2 = new ImageView("ajout.png");
                    icone2.setFitHeight(20);
                    icone2.setFitWidth(20);
                    btn1.setGraphic(icone2);
                    setStyle("-fx-alignment : CENTER;");
                }
            }
        }
    };