有没有一种方法可以访问ContextMenu滚动箭头(滚动条)?JavaFX [英] Is there a way to access ContextMenu scroll arrows (scroll bar) ? JavaFX

查看:58
本文介绍了有没有一种方法可以访问ContextMenu滚动箭头(滚动条)?JavaFX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

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

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

解决方案

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

  ContextMenu>ContextMenuSkin>ContextMenuContent>ArrowMenuItem 

ArrowMenuItem 是一个非静态的包专用类. ContextMenuContent 具有此类的两个实例: upArrow downArrow ,并且仅当项目不能容纳在 ContextMenu . ContextMenuContent 使用 Timeline 滚动 ContextMenu ,因此,当 ENTERED 键入 MouseEvent 时,在任何这些箭头项上触发时, Timeline 会根据悬停的 ArrowMenuItem 开始向上或向下滚动内容.当鼠标退出该区域时,时间轴将停止. ContextMenuContent 具有所需的 scroll 方法,但不幸的是,该方法不是公共的.

可能的解决方案:

  1. 扩展 ContextMenuSkin ContextMenuContent ,以显示方法 scroll .这样,您可以从外观调用查找 ContextMenuContent 并使用该方法向上或向下滚动.

  2. 使用 menu-up-arrow menu-down-arrow 样式类查找箭头节点.一旦获得箭头节点,就可以刺激鼠标 ENTERED 事件,以使 ContextMenu 向上或向下滚动.请注意,由于 Timeline 具有固定的滚动速率,因此用户必须等到滚动完成.然后,您需要在滚动结束后使用此事件.示例代码:

  ContextMenuSkin skin =(ContextMenuSkin)contextMenu.getSkin();节点向上= skin.getNode().lookup(.menu-up-arrow");节点向下= skin.getNode().lookup(.menu-down-arrow");MouseEvent enterEvent = new MouseEvent(MouseEvent.MOUSE_ENTERED,...);//其余参数如果(shouldScrollUp){up.fireEvent(enteredEvent);} 别的 {down.fireEvent(enteredEvent);}//滚动结束后使用事件 

  1. 使用反射:

  private static void scrollContextMenuUp(ContextMenu contextMenu){尝试 {ContextMenuSkin皮肤=(ContextMenuSkin)contextMenu.getSkin();ContextMenuContent content =(ContextMenuContent)skin.getNode();方法method = content.getClass().getDeclaredMethod("scroll",double.class);method.setAccessible(true);method.invoke(content,12.0);//更改此double值以滚动更多} catch(Exception e){System.err.println(由于以下原因而无法滚动:" + e.getMessage());}} 

I implement autocomplete textfield based on this answer here:

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

I use ContextMenu which height is long enough so ~15 items can be visible at a time, when there are more items available arrows show at the bottom and on the top of the contextmenu.

The problem i have is that when i scroll down on the items and i input some other words my context menu remains scrolled down, and i have to scroll it up manually to show the items even if there is only 1 item.

I tried on different ways to access the scroll bar of ContextMenu, so i can scroll it to top every time i input a new character in the field, but i couldn't figure a way to do so..

Is there any way to scroll up the contextmenu or to set the focus to the first element (top) whenever i input something in the field for auto completion ?

I hope i managed to explain my problem correctly and i'm thankful for the replies in advance..

解决方案

ContextMenu keeps an up and down arrows as a special type of MenuItem called ArrowMenuItem. The structure goes like this:

ContextMenu > ContextMenuSkin > ContextMenuContent > ArrowMenuItem

ArrowMenuItem is a non-static package-private class. ContextMenuContent has two instances of this class: upArrow and downArrow and these two instances are shown only when the items can't fit in the ContextMenu. ContextMenuContent uses a Timeline to scroll the ContextMenu, so when an ENTERED type MouseEvent is fired on any of those arrow items, the Timeline starts scrolling the content up or down based on hovered ArrowMenuItem. The Timeline stops when the mouse exits that region. ContextMenuContent has a method scroll that is all you need, but unfortunately, this method is not public.

Possible solutions:

  1. Extend ContextMenuSkin, ContextMenuContent to expose the method scroll. In this way, you can call lookup ContextMenuContent from the skin and use that method to scroll all the way up or down.

  2. Use menu-up-arrow and menu-down-arrow style classes to lookup the arrow nodes. Once you get the arrow node, you can stimulate a mouse ENTERED event to make the ContextMenu scroll up or down. Note that in this way the user has to wait until the scrolling finishes since the Timeline has a fixed scrolling rate. Then you need to consume this event after the scrolling is over. Sample code:

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. Using Reflection:

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());
    }
}

这篇关于有没有一种方法可以访问ContextMenu滚动箭头(滚动条)?JavaFX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆