【问题标题】:How do i add event handlers to checkboxes in a listview checkbox cell?如何将事件处理程序添加到列表视图复选框单元格中的复选框?
【发布时间】:2013-11-10 07:11:18
【问题描述】:

我正在创建一个可供用户选择以开始游戏的卡片列表。用户通过卡片名称旁边的复选框来选择卡片,他们只能选择 10 张卡片。我希望能够通过在单击复选框时调用事件处理程序来限制可以选择的复选框的数量,并确定是否允许单击复选框。我如何为每个复选框添加一个事件处理程序来做到这一点?如果有更好的方法,我绝对愿意接受建议。这是我设置列表视图和复选框回调的代码:

ListView<Card> cards;
Callback<Card, ObservableValue<Boolean>> checkBoxCallback = new Callback<Card, ObservableValue<Boolean>>() {
        @Override
        public BooleanProperty call(Card card) {
            return card.selectedProperty();
        }
    };

    StringConverter<Card> cardToStringConverter = new StringConverter<Card>() {
        @Override
        public Card fromString(String card) {
            try {
                return CardFactory.createCard(card);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public String toString(Card card) {
            return card.toString();
        }

    };

    Callback<ListView<Card>, ListCell<Card>> listViewCallback = CheckBoxListCell.forListView(checkBoxCallback, cardToStringConverter);
    cards.setCellFactory(listViewCallback);
    cards.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Card>() {
        @Override
        public void changed(ObservableValue<? extends Card> obsValue,
                Card oldValue, Card newValue) {
            cardImageView.setImage(newValue.getCardImage());
        }
    });

【问题讨论】:

  • 你不能使用静态全局变量来计算所检查的卡片,你也可以检查计数变量是否小于 10..??这将是我的选择
  • 我如何知道在没有附加事件处理程序的情况下单击复选框?

标签: java user-interface checkbox event-handling javafx


【解决方案1】:

CheckBoxListCell.forListView()的getSelectedPropertyCallback参数是双向绑定的,

(表示单元格中的 CheckBox 将设置/取消设置此属性 基于用户交互,CheckBox 将反映 ObservableValue,如果它在外部发生变化)。

因此向Card.selectedProperty() 添加更改侦听器可能更准确,涵盖复选框和其他控件/设置器的外部修改。

final IntegerProperty count = new SimpleIntegerProperty(0);
Text text = new Text("-");
// Bind count to text, to show on scene.
text.textProperty().bind(count.asString());

ChangeListener listener = new ChangeListener<Boolean>() {
    @Override
    public void changed(final ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        count.set(count.get() + (newValue ? 1 : -1));
        if (count.get() >= 10) {
            System.out.println("exceeded max limit");
            // Revert selection
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    ((BooleanProperty) observable).set(false);
                }
            });
        }
    }
};
for (final Card card : cards.getItems()) {
    card.selectedProperty().addListener(listener);
}

在用户工作结束时,移除监听器。

for (final Card card : cards.getItems()) {
    card.selectedProperty().removeListener(listener);
}

或者,如果您只想将侦听器添加到复选框,您可以在内部创建具有复选框的自定义 ListCell 并设置 ListView.cellFactory()。

【讨论】:

  • ChangeListener 的 javafx api 指出,“通常认为修改此方法中的观察值是不好的做法。” -docs.oracle.com/javafx/2/api/javafx/beans/value/… 是否有其他方法可以编辑可观察值,或者这是最好的选择?
  • @jwill,方法中的值没有被改变。它在一个新的 Runnable 中发生变化,稍后在退出该方法后。 Runnable 中的代码触发另一个 changelistener 事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多