有没有一种方法可以访问ContextMenu滚动箭头(滚动条)? JavaFX

时间:2020-01-10 19:36:56

标签: java javafx autocomplete contextmenu

我在此根据此答案实现自动完成文本字段:

https://stackoverflow.com/a/40369435/9047625

我使用的ContextMenu高度足够长,以便一次可以看到15个项目,而上下文菜单的底部和顶部则显示更多的可用箭头。

我的问题是,当我向下滚动项目并输入其他字词时,上下文菜单仍会向下滚动,即使只有1个项目,我也必须手动向上滚动它以显示项目。 / p>

我尝试了不同的方法来访问ContextMenu的滚动条,因此每次我在该字段中输入新字符时都可以将其滚动到顶部,但我找不到解决方法。.

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

我希望我能正确地解释我的问题,并感谢您的提前答复。

1 个答案:

答案 0 :(得分:0)

ContextMenu保持上下箭头为MenuItem的特殊类型ArrowMenuItem。结构如下:

ContextMenu > ContextMenuSkin > ContextMenuContent > ArrowMenuItem

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

可能的解决方案:

  1. 扩展ContextMenuSkinContextMenuContent以公开方法scroll。这样,您可以从皮肤调用查找ContextMenuContent,然后使用该方法向上或向下滚动。

  2. 使用menu-up-arrowmenu-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
  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());
    }
}