/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.viewer.collection; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Collections; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingConstants; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import com.rapidminer.gui.actions.StoreInRepositoryAction; import com.rapidminer.gui.actions.export.PrintableComponent; import com.rapidminer.gui.actions.export.PrintableComponentContainer; import com.rapidminer.gui.look.Colors; import com.rapidminer.gui.processeditor.results.ResultDisplayTools; import com.rapidminer.gui.tools.ExtendedJScrollPane; import com.rapidminer.gui.tools.PrintingTools; import com.rapidminer.gui.tools.ResourceLabel; import com.rapidminer.gui.tools.SwingTools; import com.rapidminer.operator.GroupedModel; import com.rapidminer.operator.IOContainer; import com.rapidminer.operator.IOObject; import com.rapidminer.operator.IOObjectCollection; import com.rapidminer.operator.ResultObject; import com.rapidminer.operator.learner.meta.MetaModel; /** * Can be used to display the models of a ContainerModel. * * @author Ingo Mierswa, Nils Woehler */ public class CollectionViewer extends JPanel implements PrintableComponentContainer { private static final long serialVersionUID = -322963469866592863L; /** The currently used visualization component. */ private Component current; private final IOObject collection; public CollectionViewer(final GroupedModel model, final IOContainer container) { this((IOObject) model, container); } public CollectionViewer(final MetaModel model, final IOContainer container) { this((IOObject) model, container); } public CollectionViewer(IOObjectCollection<IOObject> collection, final IOContainer container) { this((IOObject) collection, container); } private CollectionViewer(IOObject collection, final IOContainer container) { this.collection = collection; constructPanel(container); } private void constructPanel(final IOContainer container) { this.current = null; setLayout(new BorderLayout()); int size; IOObject first = null; if (collection instanceof GroupedModel) { size = ((GroupedModel) collection).getNumberOfModels(); if (size > 0) { first = ((GroupedModel) collection).getModel(0); } } else if (collection instanceof MetaModel) { size = ((MetaModel) collection).getModels().size(); if (size > 0) { first = ((MetaModel) collection).getModels().get(0); } } else if (collection instanceof IOObjectCollection) { size = ((IOObjectCollection<?>) collection).size(); if (size > 0) { first = ((IOObjectCollection<?>) collection).getElement(0, false); } } else { size = 1; first = collection; } switch (size) { case 0: current = new JLabel("No elements in this collection"); add(current, BorderLayout.CENTER); break; case 1: IOObject currentObject = first; current = ResultDisplayTools.createVisualizationComponent(currentObject, container, currentObject instanceof ResultObject ? ((ResultObject) currentObject).getName() : currentObject .getClass().getName()); add(current, BorderLayout.CENTER); break; default: final JTree tree = new JTree(new CollectionTreeModel(new CollectionTreeElement(collection))); tree.setCellRenderer(new CollectionTreeCellRenderer(collection)); // enables a PopupMenu to store single IOOBjects out of the collection tree.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { showPopup(e); } @Override public void mousePressed(MouseEvent e) { showPopup(e); } @Override public void mouseReleased(MouseEvent e) { showPopup(e); } private void showPopup(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON3) { int row = tree.getRowForLocation(e.getX(), e.getY()); if (row < 0) { return; } tree.setSelectionInterval(row, row); if (e.isPopupTrigger()) { IOObject currentObject = ((CollectionTreeElement) tree.getLastSelectedPathComponent()) .getIOObject(); if (currentObject != collection && // prevent recursive trees !(currentObject instanceof IOObjectCollection) && !(currentObject instanceof GroupedModel) && !(currentObject instanceof MetaModel)) { JPopupMenu menu = new JPopupMenu(); menu.add(new JMenuItem(new StoreInRepositoryAction(currentObject))); menu.show(tree, e.getX(), e.getY()); } } } } }); tree.addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { if (e.getPath() != null && e.getPath().getLastPathComponent() != null) { if (current != null) { remove(current); } IOObject currentObject = ((CollectionTreeElement) e.getPath().getLastPathComponent()) .getIOObject(); if (currentObject != collection && // prevent recursive trees !(currentObject instanceof IOObjectCollection) && !(currentObject instanceof GroupedModel) && !(currentObject instanceof MetaModel)) { current = ResultDisplayTools.createVisualizationComponent(currentObject, container, currentObject instanceof ResultObject ? ((ResultObject) currentObject).getName() : currentObject.getClass().getName()); } else { current = new ResourceLabel("collectionviewer.select_leaf"); ((JLabel) current).setHorizontalAlignment(SwingConstants.CENTER); ((JLabel) current).setIcon(SwingTools.createIcon("16/information.png")); } add(current, BorderLayout.CENTER); revalidate(); } }; }); JScrollPane listScrollPane = new ExtendedJScrollPane(tree); listScrollPane.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder(0, 0, 0, 1, Colors.TAB_BORDER), BorderFactory.createEmptyBorder(10, 0, 0, 0))); add(listScrollPane, BorderLayout.WEST); // select first model tree.setSelectionRow(0); break; } } /** * @return the Component which displays the actual result */ public Component getResultViewComponent() { return current; } @Override public List<PrintableComponent> getPrintableComponents() { if (current != null) { return PrintingTools.findExportComponents(current); } return Collections.emptyList(); } }