テーブルの列の表示設定をするサブウィンドウを開く

JavaFX門中
TableViewのカラムを表示したり非表示したりする処理の共通化

package hoge;

import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseButton;

/**
 * テーブルを引数に取ってサブウィンドウを登録する
 */
public class ColumnVisibilityContextMenu {
    public ColumnVisibilityContextMenu(TableView tableView) {
        
        ColumnVisibilityEditAction visibilityAction = new ColumnVisibilityEditAction(tableView);
        
        MenuItem menuItem = new MenuItem("表示設定");
        menuItem.setOnAction(event -> {
            visibilityAction.doAction(event);
        });
        final ContextMenu contextMenu = extractContextMenu(tableView);
        contextMenu.getItems().add(menuItem);
        tableView.setOnMousePressed(me -> {
            if (me.getButton() == MouseButton.SECONDARY) {
                contextMenu.show(tableView.getParent(), me.getScreenX(), me.getScreenY());
            }
        });

    }
    
    private ContextMenu extractContextMenu(TableView tableView) {
        ContextMenu contextMenu = tableView.getContextMenu();
        if (contextMenu == null) {
            contextMenu = new ContextMenu();
        }
        return contextMenu;
    }
}
package hoge;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

/**
 * 処理本体
 */
public class ColumnVisibilityEditAction {

    private Stage stage;
    private ListView<String> visibleListView;
    private ObservableList<String> visibleList = FXCollections.observableArrayList();
    private ListView<String> invisibleListView;
    private ObservableList<String> invisibleList = FXCollections.observableArrayList();
    private final Button visibleButton;
    private final Button invisibleButton;
    private final Button saveButton;
    private final Button cancelButton;

    public ColumnVisibilityEditAction(TableView tableView) {
        visibleListView = new ListView<>(visibleList);
        visibleListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        invisibleListView = new ListView<>(invisibleList);
        invisibleListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        this.load(tableView);
        visibleButton = new Button("<< 表示");
        visibleButton.setMinWidth(80);
        visibleButton.setOnAction(event -> {
            ObservableList<String> selectedItems = invisibleListView.getSelectionModel().getSelectedItems();
            visibleList.addAll(selectedItems);
            invisibleListView.getItems().removeAll(selectedItems);
        });
        invisibleButton = new Button("非表示 >>");
        invisibleButton.setMinWidth(80);
        invisibleButton.setOnAction(event -> {
            ObservableList<String> selectedItems = visibleListView.getSelectionModel().getSelectedItems();
            invisibleList.addAll(selectedItems);
            visibleListView.getItems().removeAll(selectedItems);
        });
        saveButton = new Button("適用");
        saveButton.setOnAction(event -> {
            for (Object c : tableView.getColumns()) {
                TableColumn column = (TableColumn) c;
                if (visibleList.contains(column.getText())) {
                    column.setVisible(true);
                } else {
                    column.setVisible(false);
                }
            }
            this.stage.hide();
        });
        cancelButton = new Button("キャンセル");
        cancelButton.setOnAction(event -> {
            this.stage.hide();
            this.load(tableView);
        });

        FlowPane buttonPane = new FlowPane(visibleButton, invisibleButton);
        buttonPane.setOrientation(Orientation.HORIZONTAL);
        buttonPane.setAlignment(Pos.CENTER);
        buttonPane.setMaxWidth(60);
        SplitPane editPane = new SplitPane(visibleListView, buttonPane, invisibleListView);
        editPane.setOrientation(Orientation.HORIZONTAL);

        FlowPane actionPane = new FlowPane(saveButton, cancelButton);
        actionPane.setAlignment(Pos.CENTER_RIGHT);
        actionPane.setMaxHeight(30);
        SplitPane mainPane = new SplitPane(editPane, actionPane);
        mainPane.setOrientation(Orientation.VERTICAL);

        Scene scene = new Scene(mainPane, 400, 300);
        stage = new Stage();
        stage.setScene(scene);
    }

    private void load(TableView tableView) {
        visibleList.clear();
        invisibleList.clear();
        for (Object c : tableView.getColumns()) {
            TableColumn column = (TableColumn) c;
            if (column.isVisible()) {
                visibleList.add(column.getText());
            } else {
                invisibleList.add(column.getText());
            }
        }
    }

    public void doAction(ActionEvent event) {
        stage.show();
    }
}