У меня есть ситуация, когда ContextMenu
установлено для TableView
, а TableView
установлено в качестве пользовательских данных для контекстного меню, обработчик события для ActionEvent
зарегистрирован для MenuItem
s. .
ОБНОВЛЕНИЕ 1: Пример минимальной воспроизводимости
package org.example.tableview;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import java.util.Arrays;
import java.util.List;
public class TableViewExample extends Application {
@Override
public void start(Stage stage) throws Exception {
PersonTable personTable1 = new PersonTable(Arrays.asList(new Person("Max", "Muster"), new Person("John", "Doe")));
Tab tab1 = new Tab("Tab 1");
tab1.setContent(personTable1);
PersonTable personTable2 = new PersonTable(Arrays.asList(new Person("Petar", "Petrović"), new Person("Jane", "Q")));
Tab tab2 = new Tab("Tab 2");
tab2.setContent(personTable2);
TabPane tabPane = new TabPane(tab1, tab2);
stage.setScene(new Scene(tabPane));
stage.show();
}
static class Person {
final String givenName;
final String surname;
Person(String givenName, String surname) {
this.givenName = givenName;
this.surname = surname;
}
}
static class PersonTable extends TableView<Person> {
TableColumn<Person, String> columnGivenName = new TableColumn<>("Given name");
TableColumn<Person, String> surname = new TableColumn<>("Surname");
PersonTable(List<Person> persons) {
columnGivenName.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().givenName));
surname.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().surname));
getColumns().addAll(columnGivenName, surname);
getItems().addAll(persons);
setContextMenu(new ContextMenuPersonTable(this));
}
}
static class ContextMenuPersonTable extends ContextMenu {
MenuItem menuItemAlertSurname = new MenuItem("Alert Surname");
ContextMenuPersonTable(PersonTable table) {
setUserData(table);
menuItemAlertSurname.setAccelerator(KeyCombination.keyCombination("CTRL+SHIFT+S"));
menuItemAlertSurname.setOnAction(TableViewExample::handleAlertAction);
getItems().add(menuItemAlertSurname);
}
}
static void handleAlertAction(ActionEvent event) {
MenuItem menuItem = (MenuItem) event.getSource();
ContextMenu contextMenu = menuItem.getParentPopup();
PersonTable table = (PersonTable) contextMenu.getUserData();
TableView.TableViewSelectionModel<Person> selectionModel = table.getSelectionModel();
Person selectedItem = selectionModel.getSelectedItem();
if (selectedItem != null) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText(">>> " + selectedItem.surname);
alert.showAndWait();
}
}
}
Во время работы над MRE я обнаружил, что проблема должна быть связана с TabView
и количество Tab
с: если есть только одна вкладка, акселератор работает отлично. Если имеется более одной вкладки, она хорошо работает только на второй вкладке. Контекстное меню работает всегда.
ОБНОВЛЕНИЕ 2: Я думаю, что проблема связана с тем, что один и тот же X используется для MenuItem
с в нескольких ContextMenu
с. Но для меня это звучит как общая картина. Есть ли лучшее решение?