Navigation javafx调整setMnemonicParsing(true)alt键

Navigation javafx调整setMnemonicParsing(true)alt键,navigation,javafx,menubar,arrow-keys,mnemonics,Navigation,Javafx,Menubar,Arrow Keys,Mnemonics,在JAVAFX中,我使用setMnemonicParsing(true)来使用快捷方式 下面是谷歌搜索的代码 VBox mainLayout = new VBox(); MenuBar menuBar = new MenuBar(); Menu menu1 = new Menu("_File"); menu1.setMnemonicParsing(true); menu1.getItems().addAll(new MenuItem("Menu 1"), new MenuIte

在JAVAFX中,我使用setMnemonicParsing(true)来使用快捷方式

下面是谷歌搜索的代码

VBox mainLayout = new VBox();  

MenuBar menuBar = new MenuBar();  
Menu menu1 = new Menu("_File");  
menu1.setMnemonicParsing(true);  
menu1.getItems().addAll(new MenuItem("Menu 1"), new MenuItem("Menu 2"));  

Menu menu2 = new Menu("_Other");  
menu2.setMnemonicParsing(true);  
menu2.getItems().addAll(new MenuItem("Other 1"), new MenuItem("Other 2"));  

menuBar.getMenus().setAll(menu1, menu2);  

mainLayout.getChildren().setAll(menuBar);  

Scene scene = new Scene(mainLayout, 300, 100);  

stage.setTitle("Demo of mnemonic");  
stage.setScene(scene);  
stage.sizeToScene();  
stage.show();   
这是步骤(窗口平台)

  • 按Alt键
  • 能看到助记字母吗
  • 按F键
  • 下拉菜单并获得焦点
  • 按箭头(->)键
  • 错误如下
  • java.lang.NullPointerException 位于com.sun.javafx.scene.control.skin.MenuBarSkin.ismenumempty(MenuBarSkin.java:728) 在com.sun.javafx.scene.control.skin.MenuBarSkin.showNextMenu(MenuBarSkin.java:781)上

    但是当我用鼠标点击菜单栏时,它没有发生


    有解决方案吗?

    下面的自我解决方案

    我发现这是Windows7上的一个JavaFX2.2错误

    步骤::

  • 将keyevent添加到舞台
  • consume()
    获取正确的
    时发生的事件
    <代码>左侧菜单上的事件聚焦
  • 实现你自己
  • stage.addEventFilter(按下KeyEvent.KEY,新建EventHandler()){
    @凌驾
    公共无效句柄(KeyEvent事件){
    if(menu1.isShowing()| | menu2.isShowing()| | menu2.isShowing()){
    if(event.getCode()==KeyCode.RIGHT){
    log.debug(“右”);
    event.consume();//为下一步删除事件
    if(menu1.isShowing()){
    menu1.hide();
    menu2.show();
    }
    else if(menu2.isShowing()){
    menu2.hide();
    menu3.show();
    }
    else if(menu3.isShowing()){
    menu3.hide();
    menu1.show();
    }
    }
    else if(event.getCode()==KeyCode.LEFT){
    log.debug(“左”);
    event.consume();
    if(menu1.isShowing()){
    menu1.hide();
    menu3.show();
    }
    else if(menu2.isShowing()){
    menu2.hide();
    menu1.show();
    }
    else if(menu3.isShowing()){
    menu3.hide();
    menu2.show();
    }
    }
    }
    }
    });
    
    必须同意Jamal的观点,在Oracle修复之前,我们这些低级程序员的责任在于修复它。我对他的修正有一个扩展,可能只需要一两次修改,就可以用于任意菜单

        stage.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
    
            @Override
            public void handle(KeyEvent event) {
                final int size = menuBar.getMenus().size();
    
                boolean showing = false;
                int index = 0;
                for(index = 0; index < menuBar.getMenus().size(); ++index) {
                    if(menuBar.getMenus().get(index).isShowing()) {
                        showing = true;
                        break;
                    }
                }
                index = (index < 0 ? menuBar.getMenus().size() + index : index) % size;
    
                if(showing) {
                    Menu menu1 = null, menu2 = null;
                    menu1 = menuBar.getMenus().get(index);
    
                    if(event.getCode() == KeyCode.RIGHT) {
    
                        event.consume(); // remove event for next step
                        menu2 = menuBar.getMenus().get((index + 1) % size);
    
                        menu1.hide();
                        menu2.show();
                    }
                    else if(event.getCode() == KeyCode.LEFT) {
    
                        event.consume(); // remove event for next step
    
                        menu1 = menuBar.getMenus().get(index);
                        menu2 = menuBar.getMenus().get((index - 1) < 0 ? size + (index - 1) : (index - 1));
    
                        menu1.hide();
                        menu2.show();
                    }
                }
            }
        });
    
    stage.addEventFilter(按下KeyEvent.KEY,新建EventHandler()){
    @凌驾
    公共无效句柄(KeyEvent事件){
    final int size=menuBar.getMenus().size();
    布尔值=假;
    int指数=0;
    对于(索引=0;索引

    就我个人而言,我认为bug修复应该尽可能地严格,这需要任意的菜单栏大小。因此,如果像我一样,您遇到了一个功能完善的JavaFX程序的bug,该程序可以动态地更改菜单(而且是在很短的时间内),这可能很有用。

    我发现,要显示菜单并支持导航,而不会在其他地方出现大量空指针异常和样式更改,唯一可靠的方法是模拟实际的用户事件流:

    MenuBar menuBar; // given a menuBar not null and not empty
    KeyEvent evt; // and some event hook not currently consumed
    
    boolean handled = true;
    
    HANDLED:
    do
    {
    do
    {
        // do your handling
    
        Node n = menuBar;
        try
        {
            while (!(n instanceof MenuButton) && (n instanceof Parent))
            {
                n = ((Parent)n).getChildrenUnmodifiable().get(0);
            }
        }
        catch (IndexOutOfBoundsException e)
        {
            // This should not be possible if there exists menu items in the menu bar...
            break;
        }
    
        if (!(n instanceof MenuButton))
        {
            // This should not be possible if there exists menu items in the menu bar...
            break;
        }
    
    
        // avoid null exceptions in glass pane on immediate click up/down
        // and PREVENT unwanted style changes in de-selected state display. 
        EventHandler<? super MouseEvent> mouseHandler = n.getOnMouseEntered();
        if (mouseHandler != null)
        {
            mouseHandler.handle(null);
        }
    
        // perform the "focusing and invocation" of the menu button
        Event.fireEvent(n, MouseEvent.impl_mouseEvent(0, 0, 0, 0, MouseButton.PRIMARY, 1, false, false, false, false, false, true, false, false, false, MouseEvent.MOUSE_PRESSED));
    
        // null out the state machine where the mouse is concerned
        // prevent null exceptions in glasspane handlers in subsequent navigation movements
        Event.fireEvent(n, MouseEvent.impl_mouseEvent(0, 0, 0, 0, MouseButton.PRIMARY, 0, false, false, false, false, false, false, false, false, false, MouseEvent.MOUSE_RELEASED));
    
        break HANDLED;
    } while (false);
    // non-standard termination
    handled = false;
    } while (false);
    
    if (handled)
    {
        evt.consume();
    }
    
    菜单栏菜单栏;//给定的菜单栏不为null且不为空
    KeyEvent evt;//以及一些当前未使用的事件挂钩
    布尔值=真;
    处理:
    做
    {
    做
    {
    //做你的处理
    节点n=菜单栏;
    尝试
    {
    而(!(n个菜单按钮实例)和&(n个父菜单按钮实例))
    {
    n=((父)n).getChildrenUnmodifiable().get(0);
    }
    }
    catch(IndexOutOfBoundsException e)
    {
    //如果菜单栏中存在菜单项,则不可能执行此操作。。。
    打破
    }
    如果(!(菜单按钮的n实例))
    {
    //如果菜单栏中存在菜单项,则不可能执行此操作。。。
    打破
    }
    //避免在玻璃窗格中立即单击向上/向下时出现空异常
    //并防止取消选定状态显示中出现不必要的样式更改。
    
    EventHandler
    f
    在您的代码中不是助记符。您可以编辑问题以包含一个吗?请同时包含有关您的操作系统和Java版本的信息。使用JavaFX 2.2在Win7上进行测试。这肯定是一个错误,您可以将其提交给Jira。注意:这对您的子菜单没有帮助。我现在正在对此进行修复。
    MenuBar menuBar; // given a menuBar not null and not empty
    KeyEvent evt; // and some event hook not currently consumed
    
    boolean handled = true;
    
    HANDLED:
    do
    {
    do
    {
        // do your handling
    
        Node n = menuBar;
        try
        {
            while (!(n instanceof MenuButton) && (n instanceof Parent))
            {
                n = ((Parent)n).getChildrenUnmodifiable().get(0);
            }
        }
        catch (IndexOutOfBoundsException e)
        {
            // This should not be possible if there exists menu items in the menu bar...
            break;
        }
    
        if (!(n instanceof MenuButton))
        {
            // This should not be possible if there exists menu items in the menu bar...
            break;
        }
    
    
        // avoid null exceptions in glass pane on immediate click up/down
        // and PREVENT unwanted style changes in de-selected state display. 
        EventHandler<? super MouseEvent> mouseHandler = n.getOnMouseEntered();
        if (mouseHandler != null)
        {
            mouseHandler.handle(null);
        }
    
        // perform the "focusing and invocation" of the menu button
        Event.fireEvent(n, MouseEvent.impl_mouseEvent(0, 0, 0, 0, MouseButton.PRIMARY, 1, false, false, false, false, false, true, false, false, false, MouseEvent.MOUSE_PRESSED));
    
        // null out the state machine where the mouse is concerned
        // prevent null exceptions in glasspane handlers in subsequent navigation movements
        Event.fireEvent(n, MouseEvent.impl_mouseEvent(0, 0, 0, 0, MouseButton.PRIMARY, 0, false, false, false, false, false, false, false, false, false, MouseEvent.MOUSE_RELEASED));
    
        break HANDLED;
    } while (false);
    // non-standard termination
    handled = false;
    } while (false);
    
    if (handled)
    {
        evt.consume();
    }