亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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 屬性不是一個好主意,因為它會在數據更改時觸發,而不僅僅是在用戶單擊復選框時觸發?。?/p>

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 關注
  • 333 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號