【问题标题】:javafx adjust setMnemonicParsing(true) alt keyjavafx 调整 setMnemonicParsing(true) alt 键
【发布时间】: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();   

这里是步骤(窗口平台)

  1. Alt
  2. 可以看到助记符
  3. F
  4. 下拉菜单并获得焦点
  5. 按箭头(->)键
  6. 如下错误

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 上提交。

标签: navigation javafx menubar arrow-keys mnemonics


【解决方案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 错误。

步骤::

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

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

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 2016-01-12
      相关资源
      最近更新 更多