2013-10-15 1 views
0

dans JavaFX, je suis en utilisant un raccourci en utilisant setMnemonicParsing (true)JavaFX ajuster setMnemonicParsing (true) alt clé

Code

qui est de googler est inférieure à

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

voici les étapes (plate-forme de fenêtre)

  1. appuyez sur Alt touche
  2. peut voir la lettre mnémotechnique
  3. presse F touche menu déroulant
  4. et de se concentrer
  5. presse flèche (->) Erreur clé
  6. comme ci-dessous

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)

mais quand je clique sur la Menubar avec la souris, cela n'arrive pas.

une solution?

+0

'f' n'est pas un mnémonique dans votre code. Pouvez-vous modifier la question pour inclure un [sscce] (http://sscce.org)?Veuillez également inclure des informations sur vos versions OS et Java. – jewelsea

+0

Testé sur Win7 avec JavaFX 2.2. C'est définitivement un bug, vous pouvez le déposer chez Jira. –

Répondre

0

Solution de contournement automatique ci-dessous.

Je trouve que c'est un Java FX 2.2 bug sous Windows 7.

étapes ::

  1. ajouter KeyEvent à l'étape
  2. événement consume() lors de l'obtention d'un RIGHT; LEFT événement sur menu focalisé.
  3. vous mettre en œuvre

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

Je dois d'accord avec Jamal ici, il incombe à nous les programmeurs humbles de fixer jusqu'à Oracle le fixe. J'ai une extension sur son correctif qui devrait, peut-être avec juste une ou deux modifications, travailler pour un menu arbitraire.

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

Personnellement, je pense que des corrections de bugs devraient être aussi serré que possible, et cela prend une taille de barre de menu arbitraire. Donc, si, comme moi, vous rencontrez ce bug avec un programme JavaFX autrement parfaitement fonctionnel qui change ses menus dynamiquement (et à la baisse d'un chapeau), cela peut être utile.

+0

Remarque: Cela ne vous aidera pas avec les sous-menus. Je travaille sur une solution pour cela maintenant. –

0

J'ai trouvé que le seul moyen fiable pour montrer la navigation dans les menus et le soutien sans avoir un tas d'exceptions de pointeur nul ailleurs et les changements de style est de simuler le flux d'événements utilisateur réel:

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