Botón de menú Adapt TableView

Problema

El setTableMenuButtonVisible de un TableView proporciona un mecanismo para cambiar la visibilidad de una columna de la tabla. Sin embargo, esa funcionalidad deja mucho que desear:

El menú debe permanecer abierto. Tengo e. sol. 15 columnas de la tabla y es difícil hacer clic en abrir menú -> hacer clic en columna -> hacer clic en abrir menú -> hacer clic en siguiente columna -> ... Es difícil cambiar la visibilidad de varias columnas

Debe haber una funcionalidad de seleccionar todo / deseleccionar todo

Debería haber una manera de ampliar el menú con elementos personalizados

Después de deseleccionar todas las columnas, no hay forma de volver a seleccionar una columna porque el encabezado se ha ido y con él el menú de la tabla

En otras palabras: la implementación actual del menú de la tabla es bastante inútil.

Pregunta

¿Alguien sabe de alguna manera sobre cómo reemplazar el menú de vista de tabla existente por uno adecuado? He visto una solución con una búsqueda de estilo ".show-hide-columnas-botón" y agregando un filtro de eventos. Sin embargo, eso fue hace 2 años, tal vez las cosas cambiaron.

¡Muchas gracias!

Así es como me gustaría tenerlo, demostrado a través de ContextMenu (es decir, haciendo clic con el botón derecho del mouse en la tabla):

public class TableViewSample extends Application {

    private final TableView table = new TableView();
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(300);
        stage.setHeight(500);

        // create table columns
        TableColumn firstNameCol = new TableColumn("First Name");
        TableColumn lastNameCol = new TableColumn("Last Name");
        TableColumn emailCol = new TableColumn("Email");

        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        // add context menu
        CustomMenuItem cmi;
        ContextMenu cm = new ContextMenu();

        // select all item
        Label selectAll = new Label( "Select all");
        selectAll.addEventHandler( MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                for( Object obj: table.getColumns()) {
                    ((TableColumn) obj).setVisible(true);
                }           }

        });

        cmi = new CustomMenuItem( selectAll);
        cmi.setHideOnClick(false);
        cm.getItems().add( cmi);

        // deselect all item
        Label deselectAll = new Label("Deselect all");
        deselectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent event) {
                for (Object obj : table.getColumns()) {
                    ((TableColumn) obj).setVisible(false);
                }
            }

        });

        cmi = new CustomMenuItem( deselectAll);
        cmi.setHideOnClick(false);
        cm.getItems().add( cmi);

        // separator
        cm.getItems().add( new SeparatorMenuItem());

        // menu item for all columns
        for( Object obj: table.getColumns()) {

            TableColumn tableColumn = (TableColumn) obj; 

            CheckBox cb = new CheckBox( tableColumn.getText());
            cb.selectedProperty().bindBidirectional( tableColumn.visibleProperty());

            cmi = new CustomMenuItem( cb);
            cmi.setHideOnClick(false);

            cm.getItems().add( cmi);
        }

        // set context menu
        table.setContextMenu(cm);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(table);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }
}

Respuestas a la pregunta(5)

Su respuesta a la pregunta