JavaFX为TableView添加监听器获取选中行邮箱并加入模型邮件列表
实现方案
第一步:修复现有代码潜在问题
- Data类的emails列表未初始化,存在空指针风险,修改Data类成员变量定义:
// 将原代码private List<String> emails;替换为以下任意一种 // 1. 如需可观察列表选这个 private List<String> emails = FXCollections.observableArrayList(); // 2. 普通列表选这个 // private List<String> emails = new ArrayList<>();
- Show类的initialize方法中重复设置了select列的cellFactory,删除多余的
select.setCellFactory(CheckBoxTableCell.forTableColumn(select));,仅保留后面带自定义回调的那段即可。
第二步:实现勾选状态与emails列表的同步
两种实现方式可根据场景选择:
方式1:加载数据时绑定监听器(适合数据仅通过loadData加载的场景)
修改Data类的loadData方法,在新增People对象时直接绑定check属性的变化监听:
public void loadData() { try { con=getConnect(); data.clear(); String query = "SELECT * FROM " + mychoice; ps = con.prepareStatement(query); rs = ps.executeQuery(); while (rs.next()) { People p = new People( rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4) ); // 绑定勾选状态变化监听 p.checkProperty().addListener((obs, oldVal, newVal) -> { if (newVal) { // 勾选时添加邮箱,去重避免重复添加 if (!emails.contains(p.getMail())) { emails.add(p.getMail()); } } else { // 取消勾选时移除邮箱 emails.remove(p.getMail()); } }); data.add(p); } rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } }
方式2:给数据源添加列表监听器(适合列表会动态增删元素的场景)
在Show类的initialize方法末尾添加以下代码,统一处理所有新增元素的监听绑定:
model.getData().addListener((ListChangeListener<People>) change -> { while (change.next()) { // 处理新增元素,绑定监听 if (change.wasAdded()) { for (People p : change.getAddedSubList()) { p.checkProperty().addListener((obs, oldVal, newVal) -> { if (newVal) { if (!model.getEmails().contains(p.getMail())) { model.getEmails().add(p.getMail()); } } else { model.getEmails().remove(p.getMail()); } }); } } // 处理移除元素,同步删除邮箱避免脏数据 if (change.wasRemoved()) { for (People p : change.getRemoved()) { model.getEmails().remove(p.getMail()); } } } });
可选初始化逻辑
如果需要页面加载时就同步默认勾选的邮箱到列表,可在所有监听器绑定完成后添加以下代码:
model.getEmails().clear(); for (People p : model.getData()) { if (p.getCheck()) { model.getEmails().add(p.getMail()); } }
内容的提问来源于stack exchange,提问作者happyness
相关产品推荐
相关产品推荐

