【发布时间】:2016-01-06 22:21:25
【问题描述】:
我从问题开始,然后更详细地描述问题:
问题:
有没有办法直接从 JavaFx ComboBox 的列表视图接收事件(据我所知,ComboBox 由列表视图和文本字段组成)?我想找出列表中的哪个元素已被鼠标单击,或者当用户在键盘上按下 enter 时选择了哪个元素(在列表中使用向上/向下箭头导航之后)。因此,我需要在列表视图上接收鼠标单击事件或按键事件,但到目前为止,我所能得到的只是组合框本身上的事件,结果只是组合框文本字段中的更改。
详细问题描述:
我有一个带有组合框的 JavaFx 应用程序,其想法是当用户单击组合框列表中的条目时(当组合框的弹出窗口打开时),该值会直接添加到另一个列表中。此外,当用户使用键盘上的箭头键在组合框列表中导航并按下回车键时,应采用当前选择的值并将其添加到另一个列表中。但是到目前为止,我还没有发现如何使用标准的 JavaFx 组合框来实现此功能。
试过了:
- 我尝试的第一个解决方案是在组合框的valueProperty 上添加一个更改侦听器(这是关闭弹出窗口时在文本字段中显示的值)。因此,当用户单击列表条目时,弹出窗口关闭并将单击的条目放入值字段中,更改值并因此触发我的更改侦听器。这适用于鼠标,但键盘导航无法正常工作,因为每次用户在列表中向下或向上导航时,组合框的 value 字段都会使用当前选择的 listentry 更新,因此每次都会触发我的 changelistener(反过来将该值添加到我的其他列表中,而它应该只在输入键时添加)。
- 下一个解决方案是不向valueProperty 添加侦听器,而是向showingProperty 添加侦听器。每次组合框弹出窗口关闭时,都会获取 value 字段的当前值并将其添加到另一个列表中。这同样适用于鼠标,但仍然存在键盘导航问题。虽然它现在可以正确处理列表中的向上/向下导航并输入按键,但现在问题出在您尝试取消选择时。当您按下 Escape 时,该值也会被获取并添加到另一个列表中,就像您按下 Enter 键一样。这种方法的问题是我无法确定弹出窗口是通过哪个按键关闭的。
所以我的下一个想法是使用 ComboBox 的 addEventFilter 方法向组合框本身添加一个事件过滤器,其代码类似于以下(这里也建议 StackOverflow):
ComboBox comboBox = new ComboBox();
comboBox.addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
// do stuff
});
但是当组合框弹出窗口打开时,事件过滤器永远不会被调用。它仅在弹出窗口关闭时调用,这导致我假设事件被列表视图消耗。因此,问题的唯一解决方案似乎是以某种方式从列表视图本身捕获事件。这又回到了本文开头的问题。抱歉解释太长了。:-)
【问题讨论】:
-
嗯...也许提供一个
cellFactory并向每个ComboBoxListCell的selected属性添加一个侦听器?不确定它是否会起作用,但也许值得一试。 -
有趣的问题。我找不到办法做到这一点。最重要的是,在您关闭弹出窗口之前,组合框实际上会在您使用键导航时设置值。 (我想这只是观察列表视图的选定项属性。)您对
showingProperty的想法确实是正确的,请注意,转义键的问题基本上只是由于转义键没有似乎没有在任何意义上取消选择。 (如果您打开组合框,用键导航,然后按 Escape,键选择的最后一项将显示在组合框中。) -
你能用
ChoiceBox代替ComboBox吗? -
@sillyfly:好主意。但最后,我仍然需要知道用户是否取消了输入(使用 selected 属性我只知道最后选择的项目)。
-
@James_D:ChoiceBox 并不是我所需要的(应该可以不选择任何值并改为显示“选择值...”)。但也许可以对其进行调整以使其像这样工作。我考虑了一下。