Display context menu in TableView JavaFX

I am creating a TableView in JavaFX. In which I want to show the Context Menu right mouse button in the tableView. Therefore, I add an EventHandler to the table as shown below:

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

But my problem is that the Context Menu displayed wherever I right-click on any part of the table.

I want to do this so that the Context Menu displayed only if I clicked on any rows in the TableView .

i.e. How can I get the row number in the TableView at a specific point, so that my Context Menu should only be visible if I clicked on any row in the TableView .

+4
source share
3 answers

Add context menu to specific cells using CellFactory not for the whole table.

eg. using the table from 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; } }); 
0
source

may be an older question. There is a solution, such as getting the target of a table mouse event and checking an instance of the TableCellSkin class and displaying a context menu like

 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(); } } } }); 
0
source

The best solution I have found is to check if the y coordinate is outside the bounds of the column heading and then display the menu explicitly.

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

An additional advantage is that you can create a context menu on the fly with context sensitive elements (which, for example, are displayed only if a certain cell type is selected) or simply reuse the prebuild context menu, as indicated in SetContextMenu up to you

0
source

All Articles