为了账号安全,请及时绑定邮箱和手机立即绑定

JavaFx:ListView CheckBoxListCell 选择

JavaFx:ListView CheckBoxListCell 选择

阿波罗的战车 2023-02-23 10:10:45
ListView我在使用 a时遇到问题CheckBoxListCell。当我选中/取消选中某个项目时,该项目未被选中/聚焦,这是预期的,因为 CheckBox 也是该项目的一部分,而不仅仅是文本部分。这是一个简单的代码,您可以验证它。import javafx.beans.property.BooleanProperty;import javafx.beans.property.SimpleBooleanProperty;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.fxml.FXML;import javafx.fxml.Initializable;import javafx.scene.control.CheckBox;import javafx.scene.control.ListView;import javafx.scene.control.cell.CheckBoxListCell;import lombok.Getter;import java.net.URL;import java.util.ResourceBundle;public class Controller implements Initializable {    @FXML private ListView<Model> listView;    @Override    public void initialize(URL location, ResourceBundle resources) {//      without selection//      listView.setCellFactory(CheckBoxListCell.forListView(Model::getSelected));        // actual "bad" solution        listView.setCellFactory(factory -> {            CheckBoxListCell<Model> cell = new CheckBoxListCell<Model>() {                @Override                public void updateItem(Model item, boolean empty) {                    super.updateItem(item, empty);                    if (empty) {                        setText(null);                        setGraphic(null);                        return;                    }                    ((CheckBox) getGraphic()).selectedProperty().addListener(                            (observable, oldValue, newValue) -> listView.getSelectionModel().select(getItem()));                }            };            cell.setSelectedStateCallback(Model::getSelected);            return cell;        });        ObservableList<Model> items = FXCollections.observableArrayList();        items.add(new Model("A", true));        items.add(new Model("B", true));        items.add(new Model("C", false));        listView.setItems(items);    }如您所见,我找到了一个解决方案,或者更确切地说是一个肮脏的解决方法,但我不太喜欢它,因为它在每个 updateItem 时都会被调用,并且它会添加 n 次监听器,这不是很好。任何其他想法/解决方案,当我选中/取消选中组合框时,我如何才能实现这一点,整个项目都被选中/聚焦。
查看完整描述

1 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

这个答案只涵盖了问题的一部分:如何确保单元格图形属性的侦听器只注册一次(如果我们无法控制何时设置图形)。

涉及的步骤:

  1. 定义一个安装“真实”监听器的 InvalidationListener(注意:必须是一个可以稍后删除的字段)

  2. 在实例化时在单元格的图形属性上注册监听器

  3. 实施“真实”方法的注册以删除初始图形侦听器以及安装所需的任何东西

代码片段(注意:监听 selected 属性不是一个好主意,因为它会在数据更改时触发,而不仅仅是在用户单击复选框时触发!):

listView.setCellFactory(factory -> {

    CheckBoxListCell<Model> cell = new CheckBoxListCell<Model>() {

        // a listener on the graphicProperty: it installs the "real" listener

        InvalidationListener graphicListener = g -> {

            // installs the "real" listener on the graphic control once it is available 

            registerUIListener();

        };


        {

            // install the graphic listener at instantiation

            graphicProperty().addListener(graphicListener);

        }


        /** method to install a listener on a property of the graphic control

         * and unregisters the initially installed listener

         */

        private void registerUIListener() {

            if (!(getGraphic() instanceof CheckBox)) throw new IllegalStateException("checkBox expected");

            graphicProperty().removeListener(graphicListener);

            ((CheckBox) getGraphic()).selectedProperty().addListener(

                    (observable, oldValue, newValue) -> listView.getSelectionModel().select(getItem()));

        }

    };

    cell.setSelectedStateCallback(Model::selectedProperty);

    return cell;

});


查看完整回答
反对 回复 2023-02-23
  • 1 回答
  • 0 关注
  • 377 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号