有没有一种方法可以访问ContextMenu滚动箭头(滚动条)?JavaFX [英] Is there a way to access ContextMenu scroll arrows (scroll bar) ? 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
方法,但不幸的是,该方法不是公共的.
可能的解决方案:
-
扩展
ContextMenuSkin
,ContextMenuContent
,以显示方法scroll
.这样,您可以从外观调用查找ContextMenuContent
并使用该方法向上或向下滚动. -
使用
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);}//滚动结束后使用事件
- 使用反射:
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:
Extend
ContextMenuSkin
,ContextMenuContent
to expose the methodscroll
. In this way, you can call lookupContextMenuContent
from the skin and use that method to scroll all the way up or down.Use
menu-up-arrow
andmenu-down-arrow
style classes to lookup the arrow nodes. Once you get the arrow node, you can stimulate a mouseENTERED
event to make theContextMenu
scroll up or down. Note that in this way the user has to wait until the scrolling finishes since theTimeline
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
- 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屋!