2013-11-01 63 views
3

我們的應用程序使用一個JavaFX用戶界面,其中包含一個單獨的Stage,其中包含頂部的MenuBar,以及其下的一些其他控件。如何停止使用KeyEvent的控件?

我們希望使用KeyCode.SPACE(即空格鍵)作爲MenuBar中MenuItem之一的加速器。是的,我知道這不是用於菜單加速器的理想關鍵。這不是我的決定。 :)

總之,起初SPACE加速器工作得很好:

menuItem.setAccelerator(KeyCombination.valueOf("SPACE")); 

但是,當我們開始添加其他控件一樣的TableView到我們的階段,即加速器停止工作。事實證明那些其他控件使用SPACE是爲了他們自己的目的,並且在它返回到MenuBar之前使用KeyEvent。

因此,我們決定我們不需要SPACE來處理其他控件,因此我通過使用事件過濾器「解決」了問題。它偷走了我的菜單項空格的KeyEvent它曾經獲得那些其他控件之前:

stage.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { 
    public void handle(KeyEvent e) { 
    if (e.getCode() == KeyCode.SPACE && 
     !(e.getTarget() instanceof TextInputControl) && 
     !menuItem.isDisable()) { 
      e.consume(); 
      menuItem.fire(); 
    } 
    } 
}); 

這似乎是工作,但我希望有可能是一個更清潔,那麼脆弱的解決方案。特別是,我真的想找到一種方法來告訴其他控件(如TableView)停止使用SPACE KeyEvent。

這可能嗎?

+0

您如何看待。假設你有一個tableVIew,它使用空間進行選擇。當您將空間用於其他目的時,它應該如何處理選擇? –

+0

正如我所提到的,失去tableview的空格鍵功能將會非常好。事實上,這正是我想要找到一種(更好的)方法。 – Xanatos

+0

試着看看這個,可能你之前沒有看到它:https://bitbucket.org/narya/jfx78/src/1a931b0f3f6d055cad62fac8bfea95a283c1cf26/modules/controls/src/main/java/com/sun/javafx/scene /control/behavior/TableViewBehaviorBase.java?at=default –

回答

1

我有類似的問題,一些控件,特別是文本輸入控件,使用定義爲菜單加速器的功能鍵。要解決這個問題,我發現了一個較籠統的方式,使菜單加速器優先控制的主要消費:因爲它不硬

control.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
     Scene scene = control.getScene(); 
     if (scene == null) { 
      return; 
     } 
     Map<KeyCombination,Runnable> accelerators = scene.getAccelerators(); 
     for (KeyCombination keyCombination : accelerators.keySet()) { 
      if (keyCombination.match(event)) { 
       accelerators.get(keyCombination).run(); 
       event.consume(); 
       return; 
      } 
     } 
    } 
}); 

這比問題提出的解決方案少一點脆弱將密鑰編碼到事件過濾器中,並讓所有菜單項處理由來自Scene.getAccelerators()的Runnables完成。這些Runnable在方法doAcceleratorInstall的實現類com.sun.javafx.scene.control.ControlAcceleratorSupport中定義。

我更喜歡將此過濾器添加到每個有問題的控件,但它當然也可以安裝在舞臺上。