JavaFX: разница между действием, вызванным контекстным меню и ускорителями - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть ситуация, когда 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 с. Но для меня это звучит как общая картина. Есть ли лучшее решение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...