4

TableView在 JavaFX 中创建。我想Context Menu在tableView中右键单击鼠标显示。所以我在表上添加了一个 EventHandler,如下所示:

    TableView tableView=new TableView();

    EventHandler event = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent me) {
            if (me.getButton() == MouseButton.SECONDARY) {
                tableView.getContextMenu().show(tableView, me.getSceneX(), me.getSceneY());
            }
        }
    };
    tableView.addEventHandler(MouseEvent.MOUSE_CLICKED, event);

但我的问题是,Context Menu无论我右键单击表格的任何部分,都可以看到它。

我想这样做Context Menu应该只有在我单击TableView.

即我将如何在特定点获得 TableView 中的行号,这样我Context Menu应该只可见,如果我点击任何行TableView

4

3 回答 3

1

我发现的最佳解决方案是检查 y 坐标是否超出列标题的范围,然后显式显示菜单。

ContextMenu visibleMenu = null;
tableView.setOnMouseClicked((MouseEvent e) -> {
    if (visibleMenu !=null) {
        visibleMenu.hide();
        visibleMenu = null;
    }
    if (e.getButton()==MouseButton.SECONDARY) {
        double columnHeaderHeight = tableView.lookup(".column-header-background").getBoundsInLocal().getHeight();
        if (e.getY()>columnHeaderHeight) {
            visibleMenu = getContextMenu(); // build on the fly or use a prebuild menu
            visibleMenu.show(tableView, e.getScreenX(), e.getScreenY());
        } else {
            // you could show a header specific context menu here
        }
    }
});

额外的好处是您可以使用上下文相关的项目动态构建上下文菜单(例如,仅在选择某种类型的单元格时才会出现),或者只是像 setContextMenu 那样重用预构建的上下文菜单,由您决定。

于 2016-09-14T23:14:34.037 回答
0

可能是较老的问题。有一个解决方案,比如获取表格鼠标事件的目标并检查例如 TableCellSkin 类并将上下文菜单显示为,

table.addEventHandler(MouseEvent.MOUSE_CLICKED,
                new EventHandler<MouseEvent>() {

                    @Override
                    public void handle(MouseEvent e) {
                        if (e.getButton() == MouseButton.SECONDARY
                                && !isRowEmpty) {
                            EventTarget target = e.getTarget();
                            if (target instanceof TableCellSkin
                                    || ((Node) target).getParent() instanceof TableCellSkin) {
                                    // do your stuff. Context menu will be displayed by default
                            } else {
                                // hide the context menu when click event is outside table row
                                table.getContextMenu().hide();
                            }
                        }
                    }
                });
于 2014-04-16T11:17:14.747 回答
0

将上下文菜单添加到特定单元格,CellFactory而不是整个表。

例如使用Oracle 教程中的表:

    TableColumn firstNameCol = new TableColumn();
    firstNameCol.setText("First");
    firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
firstNameCol.setCellFactory(new Callback<TableColumn, TableCell>() {
    @Override
    public TableCell call(final TableColumn param) {

        final TableCell cell = new TableCell() {

            @Override
            public void updateItem(Object item, boolean empty) {
                super.updateItem(item, empty);
                if (empty) {
                    setText(null);
                } else {
                    if (isEditing()) {
                        setText(null);
                    } else {
                        setText(getItem().toString());
                        setGraphic(null);
                    }
                }
            }
        };
        // This way I will have context menu only for specific column
        cell.setContextMenu(ContextMenuBuilder.create().items(MenuItemBuilder.create().text("menu").build()).build());
        return cell;
    }
});
于 2012-12-21T12:25:41.373 回答