TableView:如何在角落菜单中启用加速器?

时间:2016-09-27 09:51:49

标签: java javafx tableview contextmenu

要求: 将自定义菜单项添加到tableMenuButton(在自定义tableHeader中完成的RL中),并且这些menuItems必须可由加速器访问

问题: 添加menuItems很简单,但加速器没有工作

下面是一个示例,它将一个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());
}

几点说明:

1 个答案:

答案 0 :(得分: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);
[...]