如何在JavaFX中创建可滚动的上下文菜单?

如何在JavaFX中创建可滚动的上下文菜单?,javafx,contextmenu,scrollable,Javafx,Contextmenu,Scrollable,我遇到的情况是,上下文菜单可能会添加数百个菜单项。默认情况下,上下文菜单将在弹出窗口的顶部/底部显示滚动按钮,但它占据整个屏幕的高度。我尝试设置maxHeight和prefHeight值,但没有效果 理想情况下,我希望在顶部和底部显示滚动条,而不是滚动按钮(即将其放在滚动窗格中) 以下是我目前拥有的代码片段: ContextMenu menu = new ContextMenu(); menu.setMaxHeight(500); menu.setPrefHeight(500); for(Tab

我遇到的情况是,上下文菜单可能会添加数百个菜单项。默认情况下,上下文菜单将在弹出窗口的顶部/底部显示滚动按钮,但它占据整个屏幕的高度。我尝试设置maxHeight和prefHeight值,但没有效果

理想情况下,我希望在顶部和底部显示滚动条,而不是滚动按钮(即将其放在滚动窗格中)

以下是我目前拥有的代码片段:

ContextMenu menu = new ContextMenu();
menu.setMaxHeight(500);
menu.setPrefHeight(500);
for(TabFX<T> tab : overflowTabs) {
  MenuItem item = new MenuItem(tab.getTabName());
  if (tab.getGraphic() != null) item.setGraphic(tab.getGraphic());
  item.setOnAction(e -> {
    select(tab);
    layoutTabs();
  });
  menu.getItems().add(item);
}
Point2D p = overflowBtn.localToScreen(0, overflowBtn.getHeight());
menu.show(overflowBtn, p.getX(), p.getY());
ContextMenu=newcontextmenu();
菜单。设置最大高度(500);
菜单。设置高度(500);
用于(TabFX选项卡:溢出选项卡){
MenuItem item=new MenuItem(tab.getTabName());
if(tab.getGraphic()!=null)item.setGraphic(tab.getGraphic());
项目.设置操作(e->{
选择(选项卡);
layoutTabs();
});
menu.getItems().add(项);
}
Point2D p=overflowBtn.localToScreen(0,overflowBtn.getHeight());
show(overflowBtn,p.getX(),p.getY());

有解决方法吗?

我也遇到了同样的问题,我使用
javafx.stage.Popup
类解决了这个问题,该类带有
滚动窗格,其中包含
VBox
,并保存菜单项

Popup popup = new Popup();
VBox vBox = new VBox();
for (int i = 0; i < 4; i++)
{
    Button item = new Button("item " + i);
    item.setOnAction(...);
    vBox.getChildren().add(item);
}
ScrollPane scrollPane = new ScrollPane(vBox);
scrollPane.setMaxHeight(500);//Adjust max height of the popup here
scrollPane.setMaxWidth(200);//Adjust max width of the popup here
popup.getContent().add(scrollPane);
popup.show(rootWindow);
Popup Popup=new Popup();
VBox VBox=新的VBox();
对于(int i=0;i<4;i++)
{
按钮项目=新按钮(“项目”+i);
项目.设定动作(……);
vBox.getChildren().add(项);
}
ScrollPane ScrollPane=新的ScrollPane(vBox);
滚动窗格。设置最大高度(500)//在此调整弹出窗口的最大高度
滚动窗格。设置最大宽度(200)//在此调整弹出窗口的最大宽度
popup.getContent().add(滚动窗格);
显示(根窗口);
注意:由于无法将
菜单项
放入
VBox
,因此我在示例中使用了
按钮
,因为它具有
设置动作(…)
方法。但是你可以使用你喜欢的任何东西:)

来创建一个可滚动文件,你需要首先限制它的高度。但是ContextMenu的最大高度设置并不限制高度,因为它实现了computeMaxHeight,因此其增长受到ContextMenuSkin的限制,ContextMenuSkin是私有的。解决方案是覆盖上下文菜单:

public class MaxSizedContextMenu extends ContextMenu {

    public MaxSizedContextMenu() {
        addEventHandler(Menu.ON_SHOWING, e -> {
            Node content = getSkin().getNode();
            if (content instanceof Region) {
                ((Region) content).setMaxHeight(getMaxHeight());
            }
        });
   }
}
()

其次,您会发现,如果向ContextMenu添加许多项,它将忽略ancher位置(例如:entriesPopup.show(this,Side.BOTTOM,0,0))。幸运的是,可以解决这个问题。首先需要将其中一个项目添加到ContextMenu,然后显示它,最后显示其余项目。这将为您提供一个wokring可滚动上下文菜单

例如:

contextMenu.getItems().add(items.get(0)));
contextMenu.show(this, Side.BOTTOM, 0, 0);
contextMenu.getItems().addAll(items.stream().skip(1).collect(Collectors.toList()));