2016-09-27 37 views
1

要求: 添加自定義菜單項的tableMenuButton(在RL在自定義的tableHeader完成)和那些的菜單項必須是可訪問的加速器TableView:如何在角落菜單中啓用加速器?

問題: 添加的菜單項很簡單,但在加速器不工作

下面是一個將menuItem添加到角點菜單的例子,僅僅爲了比較 - 表格的contextMenu的另一個例子:看到後者是由按加速器觸發的,而前者不是。

我缺少什麼,錯誤或功能?任何想法如何調整,以使其工作?

import com.sun.javafx.scene.control.skin.TableHeaderRow; 
import com.sun.javafx.scene.control.skin.TableViewSkin; 

import javafx.application.Application; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.MenuItem; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.input.KeyCombination; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.FlowPane; 
import javafx.stage.Stage; 

/** 
* Problem: accelerator in table's corner menu not working. 
* 
* @author Jeanette Winzenburg, Berlin 
*/ 
public class TableViewAccelerator extends Application { 
    private Parent getContent() { 
     TableView table = new TableView<>(); 
     TableColumn first = new TableColumn<>("first"); 
     table.getColumns().addAll(first); 

     table.setTableMenuButtonVisible(true); 

     Button addMenu = new Button("add MenuItem to corner"); 
     addMenu.setOnAction(e -> { 
      TableViewSkin skin = (TableViewSkin) table.getSkin(); 
      TableHeaderRow header = skin.getTableHeaderRow(); 
      ContextMenu menu = (ContextMenu) invokeGetFieldValue(
        TableHeaderRow.class, 
        header, "columnPopupMenu"); 
      MenuItem item = new MenuItem("do stuff"); 
      item.setOnAction(me -> { 
       LOG.info("from corner"); 
      }); 
      item.setAccelerator(KeyCombination.valueOf("F3")); 
      menu.getItems().add(item); 
      addMenu.setDisable(true); 
     }); 

     ContextMenu menu = new ContextMenu(); 
     MenuItem contextItem = new MenuItem("initial"); 
     contextItem.setOnAction(e -> { 
      LOG.info("from initial"); 
     }); 
     contextItem.setAccelerator(KeyCombination.valueOf("F4")); 
     menu.getItems().addAll(contextItem); 
     table.setContextMenu(menu); 
     Button addToContext = new Button("add MenuItem to context"); 
     addToContext.setOnAction(e -> { 
      MenuItem added = new MenuItem("added"); 
      added.setOnAction(me -> LOG.info("from added")); 
      added.setAccelerator(KeyCombination.valueOf("F5")); 
      menu.getItems().addAll(added); 
      addToContext.setDisable(true); 
     }); 

     BorderPane pane = new BorderPane(table); 
     FlowPane buttons = new FlowPane(10, 10); 
     buttons.getChildren().addAll(addMenu, addToContext); 
     pane.setBottom(buttons); 
     return pane; 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     primaryStage.setScene(new Scene(getContent(), 600, 400)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    public static Object invokeGetFieldValue(Class declaringClass, Object target, String name) { 
     try { 
      Field field = declaringClass.getDeclaredField(name); 
      field.setAccessible(true); 
      return field.get(target); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @SuppressWarnings("unused") 
    private static final Logger LOG = Logger 
      .getLogger(TableViewAccelerator.class.getName()); 
} 

有兩點要注意:

回答

2

看起來像角落菜單項加速器沒有附加到場景中。可能缺少功能。爲了得到它的工作,你可以使用它們的ControlAcceleratorSupport類手動附加:

Button addMenu = new Button("add MenuItem to corner"); 
addMenu.setOnAction(e -> { 
    TableViewSkin skin = (TableViewSkin) table.getSkin(); 
    TableHeaderRow header = skin.getTableHeaderRow(); 
    ContextMenu menu = (ContextMenu) invokeGetFieldValue(
        TableHeaderRow.class, 
        header, "columnPopupMenu"); 
    ControlAcceleratorSupport.addAcceleratorsIntoScene(menu.getItems(), table); 
[...] 
+0

doooohhhh ..什麼怪誕的設計(核心FX) - 完美的工作,感謝您的解決方案:-) – kleopatra

相關問題