【问题标题】:How do I create a scrollable context menu in JavaFX?如何在 JavaFX 中创建可滚动的上下文菜单?
【发布时间】:2015-08-12 15:20:38
【问题描述】:

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

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

这是我目前拥有的代码的 sn-p:

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

有解决办法吗?

【问题讨论】:

    标签: javafx contextmenu scrollable


    【解决方案1】:

    我遇到了同样的问题,我通过使用带有 ScrollPanejavafx.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);
    

    注意:由于您不能将MenuItem 放入VBox,因此我在示例中使用了Button,因为它具有setOnAction(...) 方法。但是你可以使用任何你喜欢的东西:)

    【讨论】:

      【解决方案2】:

      要创建可滚动的ContextMenu,您首先需要限制其高度。但是 ContextMenu 的最大高度设置并没有限制高度,因为实现了 computeMaxHeight,因此它的增长受到私有 ContextMenuSkin 的限制。的解决方案是覆盖 ContextMenu:

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

      (JavaFX ContextMenu max size has no effect)

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

      例如:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-27
        • 2017-08-11
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 2011-06-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多