javafx 调整 setMnemonicParsing(true) alt 键

Posted

技术标签:

【中文标题】javafx 调整 setMnemonicParsing(true) alt 键【英文标题】:javafx adjust setMnemonicParsing(true) alt key 【发布时间】:2013-10-15 03:09:11 【问题描述】:

在 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.isMenuEmpty(MenuBarSkin.java:728) 在 com.sun.javafx.scene.control.skin.MenuBarSkin.showNextMenu(MenuBarSkin.java:781)

但是当我用鼠标单击菜单栏时,它不会发生。

有什么办法吗?

【问题讨论】:

f 在您的代码中不是助记符。您可以编辑问题以包含sscce 吗?还请提供有关您的操作系统和 Java 版本的信息。 在 Win7 上使用 JavaFX 2.2 测试。这绝对是一个 bug,你可以在 Jira 上提交。 【参考方案1】:

这里必须同意 Jamal 的观点,在甲骨文修复它之前,我们这些卑微的程序员有责任修复它。我对他的修复进行了扩展,也许只需要一两次修改,就可以用于任意菜单。

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

就我个人而言,我认为应该尽可能严格地修复错误,这需要任意的菜单栏大小。因此,如果像我一样,您遇到了这个错误,因为 JavaFX 程序功能非常完善,可以动态更改其菜单(并且一举两得),它可能会很有用。

【讨论】:

注意:这对子菜单没有帮助。我正在努力解决这个问题。【参考方案2】:

下面的自我解决方法。

我发现这是 Windows 7 上的 Java FX 2.2 错误。

步骤::

    向舞台添加关键事件 获得RIGHT 时的consume() 事件; LEFT 菜单焦点事件。 实现自己

stage.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() 

    @Override
    public void handle(KeyEvent event) 
        if(menu1 .isShowing() || menu2 .isShowing() || menu2 .isShowing()) 

            if(event.getCode() == KeyCode.RIGHT) 

                log.debug("right");
                event.consume(); // remove event for next step

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于javafx 调整 setMnemonicParsing(true) alt 键的主要内容,如果未能解决你的问题,请参考以下文章

javafx 调整 setMnemonicParsing(true) alt 键

JavaFX TextArea - 调整大小时不需要的滚动条

JavaFX:通过窗口大小调整来调整GridPane的大小

如果节点超出 javafx 的边界,是不是可以自动调整窗格大小

JAvaFX元素调整大小以适应Window

JavaFX:GridPane 中的 ComboBox 导致不必要的大小调整