通过 TableView (JavaFX) 中选定行第二列的 ENTER 键显示 ContextMenu

Show ContextMenu via ENTER key on selected row 2nd column in TableView (JavaFX)

到目前为止,我只设法使上下文菜单出现在 使用此代码 contextMenu.show(tableView, Side.RIGHT, 0, 0); 按下 ENTER 按钮后的 TableView。但是这样上下文菜单只会在静态位置弹出。

1。如何获取所选行第 2 列的 x y 位置

我希望上下文菜单动态显示,即每当用户在选定行上按 ENTER 键时,上下文菜单将显示在选定行的第 2 列:请看下面给定的图片。

有这样的吗

contextMenu.show(tableView, x-SelectedRow2ndCol, y-SelectedRow2ndCol);

2。 Howto上下文菜单完全显示在可见区域

例如,如果所选行是 TableView 的最后一行,因此它的位置在屏幕的最低部分,上下文菜单仍然会弹出最后一行上方的所有项目。

lookupAll 可用于从 TableView 中获取所有 TableRow。找到所选的一个,并得到子 TableCelltableColumn 匹配的列。这会让你获得 TableCell。使用 show(Node anchor, Side side, double dx, double dy) 方法显示 ContextMenu。这也负责将菜单保持在屏幕上。

来自 javadoc:

If there is not enough room, the menu is moved to the opposite side and the offset is not applied.

TableView 上的关键侦听器示例:

ContextMenu contextMenu = ...

TableColumn secondColumn = tableView.getColumns().get(1);

tableView.setOnKeyReleased(evt -> {
    if (evt.getCode() == KeyCode.ENTER) {
        Set<Node> rows = tableView.lookupAll(".table-row-cell");
        Optional<Cell> n = rows.stream().map(r -> (Cell) r).filter(Cell::isSelected).findFirst();

        if (n.isPresent()) {
            Optional<Node> node = n.get().getChildrenUnmodifiable().stream()
                    .filter(c -> c instanceof TableCell && ((TableCell) c).getTableColumn() == secondColumn)
                    .findFirst();

            if (node.isPresent()) {
                Node cell = node.get();
                Bounds b = cell.getLayoutBounds();
                contextMenu.show(cell, Side.BOTTOM, b.getWidth() / 2, b.getHeight() / -2);
            }
        }
    }
});

请注意,如果没有选定的 table 行可见,这将不起作用。