首页 > 代码库 > JavaFX 2.0+ -- Menu显示超过一个屏幕滚动条Bug
JavaFX 2.0+ -- Menu显示超过一个屏幕滚动条Bug
背景
在JavaFX中,当MenuBar的Menu或者其Sub-Menu包含的MenuItem合计超过一个屏幕所能显示的高度时,菜单能够滚动显示。此时有一个Bug,滚动的位置会被记录,同一个层级的所有ContextMenu都会使用同一个滚动位置,也就是说当在一个ContextMenu中向下滚动超过一些距离后,另一个ContextMenu可能就完全无法看到ContextMenu。
分析
这个Bug根本的原因就是不同的ContextMenu共用了同一个滚动位置,按理来说,不同的ContextMenu应该有各自的滚动位置记录。可以想办法看能否让各个ContextMenu独自维护滚动位置,不过我这里没有找到办法。
我现在的方案是:当菜单显示后,立刻重置滚动位置到0,并通过隐藏菜单再次显示的方式来刷新,这个方案有个缺陷就是离开菜单之后再回来滚动位置被重置(这个方案也是经过打印,调试查看类的层次,刷新处理等多个环节的调研才找到...)。
代码
//在菜单显示之后立刻校正滚动条位置curMenu.setOnShown(new EventHandler<Event>() { private boolean firedBySelf = false;//用于标识是方案本身触发的刷新,还是外部操作触发的刷新 @Override public void handle(Event t) { if (firedBySelf) { firedBySelf = false; return; } //找到最核心的显示皮肤类ContextMenuContent ContextMenu parentPopup = curMenu.getItems().get(0).getParentPopup(); final Scene scene = parentPopup.getScene(); Parent root = scene.getRoot(); Group group = (Group) root.getChildrenUnmodifiable().get(0); ContextMenuContent content = (ContextMenuContent) group.getChildren().get(0); Class cla = ContextMenuContent.class; try { //通过反射修改滚动位置——私有变量ty Field field; field = cla.getDeclaredField("ty"); field.setAccessible(true); field.set(content, 0); //刷新——隐藏再显示 curMenu.hide(); firedBySelf = true; curMenu.show(); } catch (SecurityException ex) { log.error("", ex); } catch (IllegalArgumentException ex) { log.error("", ex); } catch (IllegalAccessException ex) { log.error("", ex); } catch (NoSuchFieldException ex) { log.error("", ex); } }});
复制去Google翻译翻译结果
ContextMenuContent
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。