如何在 JavaFX 上使用复选框选择行?

Posted

技术标签:

【中文标题】如何在 JavaFX 上使用复选框选择行?【英文标题】:How to get the rows selected with checkBox on JavaFX? 【发布时间】:2021-11-08 07:41:30 【问题描述】:

我正在研究 JavaFx,我有一个使用 sceneBuilder 创建的表视图,它包含 3 列,其中之一是 checkBoxes 和一个名为 print_tab 的按钮,当我单击此按钮时,我希望使用复选框 -> true 选择 行,但我不知道该怎么做:

我阅读了许多关于回调复选框的表格列的示例,但无法弄清楚如何做到这一点。

这里是控制器:

    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                  

                  

          

在模型类我有这个代码:

    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 代码:

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

有什么想法吗?

编辑:

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());
        
                             

                  

我试过这种方式,但即使我检查了一些复选框,我总是得到 false 不是 true ,知道吗?同时我不认为迭代所有集合是一件好事......

【问题讨论】:

我自己目前无法测试东西,但是您是否尝试过迭代TableColumns 提出的here 的解决方案? 谢谢你,我现在就去读 minimal reproducible example 请 .. 遵守 java 命名约定 ahh ...刚刚看到您的示例代码与您上一个问题的示例代码非常相似 - 相同的命名违规,仍然无法编译.. 请将其设为minimal reproducible example,它可以运行为 - ist(对潜在的帮助者无能为力,但将代码放入 IDE,运行并查看问题所在)。而且你没有应用你学到的东西:table 的 editable 默认情况下是 false,所以你必须在某处将它设置为 true。 ;) 另一方面,TableColumn 的可编辑性默认为 true - 您可以通过阅读 api 文档了解到这一点;) @kleopatra 我同意你的观点,我是 javaFX 的新手,这就是为什么,这次我会尊重 java 命名:) 谢谢 【参考方案1】:

正如here 和here 建议的那样,正确定义的属性对于工作表模型至关重要。这样,按钮处理程序可以遍历表的ObservableList 以查找选定的行。要单独研究这个问题,请从这个完整的example 开始。以下更改遍历表模型,检查active 属性以生成显示的结果:

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);

控制台:

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

【讨论】:

【参考方案2】:

我会在 OMission 类中实现 FX 属性模式:

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);
    

那你就可以替换列CellValueFactory

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

与:

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

【讨论】:

以上是关于如何在 JavaFX 上使用复选框选择行?的主要内容,如果未能解决你的问题,请参考以下文章

JavaFx CheckBoxTreeItem 选择根项目错误

带有复选框的 JavaFX 组合框

JavaFX 8,带有复选框的 ListView

如何使用行ID在gridx网格中选择一个复选框?

如何从dataTable行集合中获取复选框输入值?

如何使用 jQuery DataTables 和复选框作为行选择器访问列元素数据