2

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 ...

dEs12ZER
  • 788
  • 4
  • 24
  • 51
  • I can't test stuff at the moment myself, but have you tried the solutions on iterating `TableColumn`s proposed [here](https://stackoverflow.com/questions/26815442/javafx-8-iterate-through-tableview-cells-and-get-graphics)? – Doombringer Sep 12 '21 at 22:05
  • Thank you i'm gonna read it now – dEs12ZER Sep 12 '21 at 22:33
  • ahh ... just seen that your sample code is very similar to that on your last quesiton - same naming violations, still not compileable .. please make it a [mcve], that is runnable as-ist (nothing to do for potential helpers but throw the code into an IDE, run and see what's wrong). And you didn't apply what you learned: table's editable is false by default, so you must set it to true somewhere. ;) On the other hand, TableColumn's editable is true by default - which you could have learned by reading the api doc ;) – kleopatra Sep 13 '21 at 09:58
  • @kleopatra i agree with you, i'm new to javaFX that's why , i will respect java naming this time :) Thank you – dEs12ZER Sep 13 '21 at 21:07
  • "i don't think it's a good to iterate all the collection" -> unless your collection is absolutely huge (e.g. 1 million + rows), this is a non-issue. – jewelsea Sep 13 '21 at 21:18
  • I see, i was thinking about using calllBack to the column , but as you said it's not a problem if it's not a huge one, which is not the case absolutely , Thank you for help :) – dEs12ZER Sep 13 '21 at 21:21

2 Answers2

3

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());
Oboe
  • 2,643
  • 2
  • 9
  • 17
3

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

trashgod
  • 203,806
  • 29
  • 246
  • 1,045