How to get the rows selected with checkBox on JavaFX?

Viewed 375

I'm working on JavaFx, i have a table view created with sceneBuilder , it contains 3 columns, one of is for checkBoxes , and a button called print_tab, i want when i click on this button to get the rows selected with checkBox -> true but i don't know how to do that :

I read many exemples about callBack the table column of checkbox but can't figure out how to do that .

here is the controller :

    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.geometry.Insets;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.CheckBox;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.CheckBoxTableCell;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import javafx.util.Callback;


     public class RecapController implements Initializable{

     @FXML
     private TableView<OMission> missionTable;

    @FXML
    private TableColumn<OMission, Boolean> checkedCol; 

      private ObservableList<OMission> UserMission = 
 FXCollections.observableArrayList();
    
      private OMission mission=null;
    
    
    
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        
         
         
         try {
            load_recap();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
         
    }

    public void load_recap(){
    

      .....

     
    checkedCol.setCellFactory(
                                CheckBoxTableCell.forTableColumn(checkedCol)
                            );
                        
    checkedCol.setCellValueFactory(new PropertyValueFactory<>("remark"));

                    checkedCol.setEditable(true);


          }


    public void print_tab() throws Exception {

                  // here is the method that the button calls , i want to get here the selected rows with checkbox -> true                  

                  }

          }

On class Model i have this code :

    public class OMission {

         private String ObjMission ;
         private Boolean remark;

         public OMission(  String objMission ) {

                 This.objMission = ObjMission ;

                 remark = false;
                           
                                    }

        public Boolean getRemark() {
            return remark;
        }

        public void setRemark(Boolean remark) {
            this.remark = remark;
        }


        public String getObjMission() {
            return ObjMission;
        }



        public void setObjMission(String objMission) {
            ObjMission = objMission;
        }

}

fxml code :

<?xml version="1.0" encoding="UTF-8"?>

<?import com.jfoenix.controls.JFXButton?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane fx:id="pan" prefHeight="740.0" prefWidth="1258.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.RecapController">
   <children>
      <JFXButton layoutX="16.0" layoutY="22.0" onAction="#OpenMission" style="-fx-background-color: #0A4969;" text="Ajouter une nouvelle mission : " textFill="WHITE">
         <font>
            <Font size="14.0" />
         </font>
      </JFXButton>
      <TableView fx:id="missionTable" layoutX="16.0" layoutY="64.0" prefHeight="659.0" prefWidth="1226.0">
                    <columns>
                      <TableColumn prefWidth="612.5" text="RAPPORT DE MISSION">
                           <columns>
                                
                              
                              <TableColumn fx:id="local" prefWidth="100.0" text="Localité" />
                              <TableColumn fx:id="objmission" prefWidth="243.0" text="Objet Mission" />
                              
                           </columns>
                        </TableColumn>
                    
            <TableColumn fx:id="checkedCol"  prefWidth="75.0" text="select" /> // That's the button i want to click on 
                    </columns>
                  </TableView>
      <JFXButton layoutX="263.0" layoutY="25.0" onAction="#print_tab" text="print" />
      <CheckBox fx:id="SelectAll" layoutX="1154.0" layoutY="41.0" mnemonicParsing="false" text="Select All" />

   </children>
    

Any idea ?

EDIT :

public void print_tab() throws Exception {

         for(OMission bean : UserMission)
    {
        System.out.println(bean.getRemark()); // always getting false
        if(bean.getRemark()) {
            
            System.out.println(bean.getObjMission());
        }
    }                         

                  }

I tried this way, but even though i check some checkboxes i always get false not true , any idea ? at the same time i don't think it's a good to iterate all the collection ...

2 Answers

I would implement FX property pattern in OMission class:

public class OMission {

    private final StringProperty objMission = new SimpleStringProperty(this, "objMission");
    private final BooleanProperty remark = new SimpleBooleanProperty(this, "remark");

    public OMission(String objMission) {
        this.objMission.set(objMission);
        this.remark.set(false);
    }

    public StringProperty objMissionProperty() {
        return objMission;
    }

    public String getObjMission() {
        return objMissionProperty().get();
    }

    public void setObjMission(String objMission) {
        objMissionProperty().set(objMission);
    }

    public BooleanProperty remarkProperty() {
        return remark;
    }

    public Boolean getRemark() {
        return remarkProperty().get();
    }

    public void setRemark(Boolean remark) {
        remarkProperty().set(remark);
    }
}

Then you can replace the column CellValueFactory:

checkedCol.setCellValueFactory(new PropertyValueFactory<>("remark"));

with:

checkedCol.setCellValueFactory(cellData -> cellData.getValue().remarkProperty());

As suggested here and here, correctly defined properties are critical to a working table model. In this way, the button handler can iterate over the table's ObservableList to find selected rows. To study the problem in isolation, start from this complete example. The following changes iterate over the table model, checking the active property to produce the result shown:

Button b = new Button("Print Seleceted");
b.setOnAction((ActionEvent e) -> {
    for (Person p : table.getItems()) {
        if (p.active.get()) {
            System.out.println(p.lastName.get() + ": " + p.email.get());
        }
    }
});
vbox.getChildren().addAll(label, table, b);

Console:

Smith: jacob.smith@example.com
Williams: ethan.williams@example.com
Brown: michael.brown@example.com

image

Related