/* * Copyright 2006-2016 The MZmine 3 Development Team * * This file is part of MZmine 3. * * MZmine 3 is free software; you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * MZmine 3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along with MZmine 3; if not, * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ package io.github.mzmine.modules.featuretable; import com.sun.javafx.scene.control.skin.TableHeaderRow; import com.sun.javafx.scene.control.skin.TreeTableViewSkin; import io.github.msdk.datamodel.featuretables.FeatureTableRow; import javafx.application.Platform; import javafx.collections.ObservableList; import javafx.event.EventHandler; import javafx.geometry.Side; import javafx.scene.Node; import javafx.scene.control.CheckBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Label; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; import javafx.scene.input.MouseEvent; public class FeatureTableMenu { /** * Make a custom table menu for the feature table. * * @param treeTableView */ public static void addCustomTableMenu(TreeTableView<FeatureTableRow> treeTableView) { // Enable table menu treeTableView.setTableMenuButtonVisible(true); // Replace internal mouse listener with custom listener setCustomContextMenu(treeTableView); } private static void setCustomContextMenu(TreeTableView<FeatureTableRow> table) { // Check that table has been populated TreeTableViewSkin<?> tableSkin = (TreeTableViewSkin<?>) table.getSkin(); if (tableSkin == null) { Platform.runLater(new Runnable() { @Override public void run() { setCustomContextMenu(table); } }); } else { // Get all children of the skin ObservableList<Node> children = tableSkin.getChildren(); // Find the TableHeaderRow child for (int i = 0; i < children.size(); i++) { Node node = children.get(i); if (node instanceof TableHeaderRow) { TableHeaderRow tableHeaderRow = (TableHeaderRow) node; // Make sure that the header row always has a height and // thus is visible double defaultHeight = tableHeaderRow.getHeight(); tableHeaderRow.setPrefHeight(defaultHeight); for (Node child : tableHeaderRow.getChildren()) { if (child.getStyleClass().contains("show-hide-columns-button")) { // Create a context menu ContextMenu columnPopupMenu = createContextMenu(table); // Replace the mouse listener child.setOnMousePressed(me -> { columnPopupMenu.show(child, Side.BOTTOM, 0, 0); me.consume(); }); } } } } } } /** * Create a custom menu. * * @param table * @return contextMenu */ private static ContextMenu createContextMenu(TreeTableView<FeatureTableRow> table) { // New context menu ContextMenu cm = new ContextMenu(); CustomMenuItem cmi; // 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()) { ((TreeTableColumn<?, ?>) 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()) { ((TreeTableColumn<?, ?>) obj).setVisible(false); } } }); cmi = new CustomMenuItem(deselectAll); cmi.setHideOnClick(false); cm.getItems().add(cmi); // Separator cm.getItems().add(new SeparatorMenuItem()); // Variables Boolean sampleColumns = false; // menu item for each of the available columns for (Object obj : table.getColumns()) { TreeTableColumn<?, ?> tableColumn = (TreeTableColumn<?, ?>) obj; int childrenColumns = tableColumn.getColumns().size(); CheckBox cb; if (childrenColumns != 0 && !sampleColumns) { sampleColumns = true; // Separator cm.getItems().add(new SeparatorMenuItem()); // Sample specific columns for (TreeTableColumn<?, ?> col : tableColumn.getColumns()) { cb = new CheckBox("Sample: " + col.getText()); // Bind to all equal sample specific columns for (Object obj2 : table.getColumns()) { TreeTableColumn<?, ?> tableColumn2 = (TreeTableColumn<?, ?>) obj2; int childrenColumns2 = tableColumn2.getColumns().size(); if (childrenColumns2 != 0) { for (TreeTableColumn<?, ?> col2 : tableColumn2.getColumns()) { if (col.getText().equals(col2.getText())) { cb.selectedProperty().bindBidirectional(col2.visibleProperty()); // cb.setSelected(true); // cb.selectedProperty().addListener( // new ChangeListener<Boolean>() { // public void changed( // ObservableValue<? extends Boolean> ov, // Boolean old_val, // Boolean new_val) { // col2.setVisible(new_val); // } // }); } } } } cmi = new CustomMenuItem(cb); cmi.setHideOnClick(false); cm.getItems().add(cmi); } // Separator cm.getItems().add(new SeparatorMenuItem()); } if (childrenColumns == 0) { cb = new CheckBox(tableColumn.getText()); cb.selectedProperty().bindBidirectional(tableColumn.visibleProperty()); cmi = new CustomMenuItem(cb); cmi.setHideOnClick(false); cm.getItems().add(cmi); } } return cm; } }