我在此根据此答案实现自动完成文本字段:
https://stackoverflow.com/a/40369435/9047625
我使用的ContextMenu高度足够长,以便一次可以看到15个项目,而上下文菜单的底部和顶部则显示更多的可用箭头。
我的问题是,当我向下滚动项目并输入其他字词时,上下文菜单仍会向下滚动,即使只有1个项目,我也必须手动向上滚动它以显示项目。 / p>
我尝试了不同的方法来访问ContextMenu的滚动条,因此每次我在该字段中输入新字符时都可以将其滚动到顶部,但我找不到解决方法。.
每当我在字段中输入一些内容以自动完成时,是否有办法向上滚动上下文菜单或将焦点设置到第一个元素(顶部)?
我希望我能正确地解释我的问题,并感谢您的提前答复。
答案 0 :(得分:0)
ContextMenu
保持上下箭头为MenuItem
的特殊类型ArrowMenuItem
。结构如下:
ContextMenu > ContextMenuSkin > ContextMenuContent > ArrowMenuItem
ArrowMenuItem
是一个非静态的包专用类。 ContextMenuContent
有两个此类的实例:upArrow
和downArrow
,仅当项目不能放入ContextMenu
时才显示这两个实例。 ContextMenuContent
使用Timeline
滚动ContextMenu
,因此,在任何这些箭头项上触发ENTERED
类型的MouseEvent
时,Timeline
开始根据悬停的ArrowMenuItem
向上或向下滚动内容。当鼠标退出该区域时,Timeline
停止。
ContextMenuContent
拥有您所需要的方法scroll
,但不幸的是,该方法不是公开的。
可能的解决方案:
扩展ContextMenuSkin
,ContextMenuContent
以公开方法scroll
。这样,您可以从皮肤调用查找ContextMenuContent
,然后使用该方法向上或向下滚动。
使用menu-up-arrow
和menu-down-arrow
样式类查找箭头节点。一旦获得箭头节点,就可以激发鼠标ENTERED
事件,使ContextMenu
向上或向下滚动。请注意,由于Timeline
具有固定的滚动速率,因此用户必须等到滚动完成。然后,您需要在滚动结束后使用此事件。
示例代码:
ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
Node up = skin.getNode().lookup(".menu-up-arrow");
Node down = skin.getNode().lookup(".menu-down-arrow");
MouseEvent enteredEvent = new MouseEvent(MouseEvent.MOUSE_ENTERED, ...); // the remaining parameters
if (shouldScrollUp) {
up.fireEvent(enteredEvent);
} else {
down.fireEvent(enteredEvent);
}
// consume the event after scroll is over
private static void scrollContextMenuUp(ContextMenu contextMenu) {
try {
ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
ContextMenuContent content = (ContextMenuContent) skin.getNode();
Method method = content.getClass().getDeclaredMethod("scroll", double.class);
method.setAccessible(true);
method.invoke(content, 12.0); // change this double value to scroll more
} catch (Exception e) {
System.err.println("Unable to scroll due to: " + e.getMessage());
}
}