有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在JavaFX中是否有一个完全在悬停时触发的菜单?

我已经查看了一些与菜单相关的JavaFX类,但找不到我想要的。我想实现一些类似于MenuBar的功能,除了我希望它在鼠标悬停时打开菜单,而不是单击时打开。虽然我完全可以自己从零开始构建一些东西,但如果已经有一些东西允许我做类似的事情,那将是浪费时间。有人知道我该怎么做吗


共 (2) 个答案

  1. # 1 楼答案

    如果你使用^{,这是可能的。您可以轻松地获取包含菜单的容器,然后在其上应用setOnMouseEntered()setOnMouseExited()来捕捉每个菜单上的鼠标事件

    下面是一个例子:

    import javafx.application.Application;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.Menu;
    import javafx.scene.control.MenuBar;
    import javafx.scene.control.MenuItem;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) {
    
            BorderPane mainPane = new BorderPane();
    
            MenuBar menuBar = new MenuBar();
    
            Menu editMenu = new Menu("File");
            MenuItem fileMenuItem1 = new MenuItem("Item 1");
            MenuItem fileMenuItem2 = new MenuItem("Item 2");
            MenuItem fileMenuItem3 = new MenuItem("Item 3");
            editMenu.getItems().addAll(fileMenuItem1, fileMenuItem2, fileMenuItem3);
    
            Menu fileMenu = new Menu("Edit");
            MenuItem fileMenu1 = new MenuItem("Item 1");
            MenuItem fileMenu2 = new MenuItem("Item 2");
            MenuItem fileMenu3 = new MenuItem("Item 3");
            fileMenu.getItems().addAll(fileMenu1, fileMenu2, fileMenu3);
    
            menuBar.getMenus().addAll(editMenu, fileMenu);
    
            mainPane.setTop(menuBar);
    
            Scene scene = new Scene(mainPane, 300, 300);
            Stage stage = new Stage();
            stage.setScene(scene);
            stage.show();
    
            // Find menubar HBox holding the menus
            HBox container = (HBox) menuBar.lookup("HBox");
    
            for(int i = 0 ; i < container.getChildren().size() ; i++) {
                Node parentNode = container.getChildren().get(i);
                Menu menu = menuBar.getMenus().get(i);
    
                parentNode.setOnMouseMoved(e->{
                    menu.show();
                });
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    你可能想知道为什么我用setOnMouseMoved而不是setOnMouseEntered。这是因为setOnMouseEntered在菜单之间移动鼠标时会产生一种奇怪的行为,使用setOnMouseMoved修复它

    此外,如果你想知道我是怎么知道使用lookup("HBox")的,事实是我的第一次尝试是System.out.println( menuBar.lookupAll("*"));,这给了我当前的信息:

    [MenuBar@5e57a6ce[styleClass=menu-bar], HBox@13ccf856[styleClass=container], MenuBarSkin$MenuBarButton[id=null, styleClass=menu-button menu]'File', MenuButtonSkinBase$MenuLabeledImpl@25917f7f[styleClass=label]'File', Text[text="File", x=0.0, y=0.0, alignment=LEFT, origin=BASELINE, boundsType=LOGICAL_VERTICAL_CENTER, font=Font[name=System Regular, family=System, style=Regular, size=12.0], fontSmoothingType=LCD, fill=0x333333ff], StackPane@c341eae[styleClass=arrow-button], StackPane@7b8501c0[styleClass=arrow], MenuBarSkin$MenuBarButton[id=null, styleClass=menu-button menu]'Edit', MenuButtonSkinBase$MenuLabeledImpl@4d8224b7[styleClass=label]'Edit', Text[text="Edit", x=0.0, y=0.0, alignment=LEFT, origin=BASELINE, boundsType=LOGICAL_VERTICAL_CENTER, font=Font[name=System Regular, family=System, style=Regular, size=12.0], fontSmoothingType=LCD, fill=0x333333ff], StackPane@3d75fcac[styleClass=arrow-button], StackPane@71f02eed[styleClass=arrow]]
    
  2. # 2 楼答案

    我认为您正在寻找类javafx.scene.control.ContextMenu和方法show(Node anchor, double screenX, double screenY)