我从问题开始,然后更详细地描述问题:
有没有办法直接从JavaFx ComboBox的列表视图中接收事件(据我所知,ComboBox包含列表视图和文本字段)?我想知道当用户按下键盘上的键时(在列表中使用向上/向下箭头导航后),鼠标单击列表中的哪个元素或选择了哪个元素。因此,我需要在列表视图上接收鼠标单击事件或按键事件,但到目前为止我所能得到的只是组合框本身的事件,结果只是组合框的文本字段中的更改。
我有一个带有组合框的JavaFx应用程序,其中的想法是当用户单击组合框列表中的条目时(当组合框的弹出窗口打开时)将值直接添加到另一个列表中。另外,当用户使用键盘上的箭头键在组合框列表中导航并按下回车时,应该获取当前选择的值并将其添加到另一个列表中。但到目前为止,我还没有发现如何使用标准JavaFx组合框实现此功能。
所以下一个想法是使用ComboBox的addEventFilter方法向组合框本身添加一个事件过滤器,其代码类似于以下(此处也提出StackOverflow):
ComboBox comboBox = new ComboBox();
comboBox.addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
// do stuff
});
但是当组合框弹出窗口打开时,事件过滤器永远不会被调用。它仅在弹出窗口关闭时调用,这使我假设事件由listview使用。所以问题的唯一解决方案似乎是以某种方式从列表视图本身捕获事件。这导致回到本文开头的问题。很抱歉有很长的解释。: - )
答案 0 :(得分:0)
在寻找其他问题时,请问这个问题。它涉及到我之前所做的事情,因此假设我理解您要完成的工作,并且在此处仍然有意义,这里有一些想法。
要使其他列表(列表2)与鼠标单击组合框保持同步,请尝试:
ChangeListener
的{{1}}属性上的selectedItem
。单击弹出式(下拉)列表视图中的项目将更改selectionModel
值 并关闭“拥有”列表视图的selectedItem
,或者Window
的组合框的事件处理程序,该事件处理程序在列表视图关闭时触发(或者最好说“变成隐藏”)。 ComboBoxBase.ON_HIDDEN
可能有问题,因为组合框和列表视图的选择模型处于较低级别,因此列表视图的ChangeListener
值更改为使用击键进行导航时触发的触发必须由selectedItem
处理。因为您只想在按ENTER键时同步组合框和列表#2,所以这可能无法工作。但这仍然使事件处理程序的想法可以尝试。
对于ENTER键,您需要获取列表视图本身的句柄,然后根据需要添加任何行为(侦听器/事件处理程序)。为此,请获取组合框的外观,该外观应为ChangeListener
的实例,然后通过为外观调用ComboBoxListViewSkin
方法获得外观。它以getPopupContent()
的形式返回弹出列表视图,因此您将重铸返回的值,但没什么大不了的。
希望这会有所帮助。
答案 1 :(得分:0)
以下代码的想法是,一旦将组合框加载到JavaFX场景中,便创建了ListView。因此,我们在组合框上添加了一个侦听器以检查它何时出现在场景中,然后通过“ lookup”方法获得其列表视图并向其添加侦听器。
在该示例中,我设置了一个MouseEvent侦听器,但是您也可以轻松地针对键进行调整。
private EventHandler<MouseEvent> cboxMouseEventHandler;
private void initComboBox() {
ComboBox<String> comboBox = new ComboBox<String>();
comboBox.getItems().add("Item 1");
comboBox.getItems().add("Item 2");
comboBox.getItems().add("Item 3");
comboBox.sceneProperty().addListener((a,oldScene,newScene) -> {
if(newScene == null || cboxMouseEventHandler != null)
return;
ListView<?> listView = (ListView<?>) comboBox.lookup(".list-view");
if(listView != null) {
cboxMouseEventHandler = (e) -> {
Platform.runLater(()-> {
String selectedValue = (String) listView.getSelectionModel().getSelectedItem();
if(selectedValue.equals("Item 1"))
System.out.println("Item 1 clicked");
});
}; // cboxMouseEventHandler
listView.addEventFilter(MouseEvent.MOUSE_PRESSED, cboxMouseEventHandler);
} // if
});
} // initComboBox