TableView JavaFX中的上下文菜单可见性

时间:2012-12-21 04:53:58

标签: java contextmenu tableview javafx-2 javafx

我在JavaFX中创建TableView。我想在tableView中右键单击鼠标来显示Context Menu。所以我在表上添加了一个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应该只是可见的。

3 个答案:

答案 0 :(得分:0)

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

E.g。使用Oracle tutorial中的表格:

    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;
    }
});

答案 1 :(得分: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();
                            }
                        }
                    }
                });

答案 2 :(得分:0)

我找到的最佳解决方案是检查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一样重用预构建上下文菜单,由您决定。

相关问题