有没有办法访问 ContextMenu 滚动箭头(滚动条)? JavaFX

Is there a way to access ContextMenu scroll arrows (scroll bar) ? JavaFX

我根据这里的答案实现了自动完成文本字段:

我使用高度足够长的 ContextMenu,因此一次可以看到约 15 个项目,当有更多项目可用时,上下文菜单的底部和顶部会显示箭头。

我遇到的问题是,当我向下滚动项目并输入一些其他词时,我的上下文菜单仍然向下滚动,即使只有 1 个项目,我也必须手动向上滚动以显示项目.

我尝试了不同的方法来访问 ContextMenu 的滚动条,所以每次我在该字段中输入一个新字符时我都可以将它滚动到顶部,但我想不出办法这样做..

每当我在字段中输入内容以自动完成时,是否有任何方法可以向上滚动上下文菜单或将焦点设置到第一个元素(顶部)?

希望我能正确解释我的问题,感谢您提前回复..

ContextMenu 将向上和向下箭头作为一种特殊类型的 MenuItem 称为 ArrowMenuItem。结构如下:

ContextMenu > ContextMenuSkin > ContextMenuContent > ArrowMenuItem

ArrowMenuItem 是非静态包私有 class。 ContextMenuContent 有此 class 的两个实例:upArrowdownArrow,这两个实例仅在项目无法放入 ContextMenu 时显示。 ContextMenuContent 使用 Timeline 来滚动 ContextMenu,因此当 ENTERED 类型 MouseEvent 在任何这些箭头项上触发时, Timeline开始根据悬停 ArrowMenuItem 向上或向下滚动内容。 Timeline 在鼠标离开该区域时停止。 ContextMenuContent 有一个方法 scroll 是你所需要的,但不幸的是,这个方法不是 public。

可能的解决方案:

  1. 扩展 ContextMenuSkinContextMenuContent 以公开方法 scroll。这样就可以从皮肤调用lookupContextMenuContent,用那个方法一直向上或向下滚动。

  2. 使用 menu-up-arrowmenu-down-arrow 样式 classes 查找箭头节点。获得箭头节点后,您可以激发鼠标 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
  1. 使用反射:
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());
    }
}