/* * CCVisu is a tool for visual graph clustering * and general force-directed graph layout. * This file is part of CCVisu. * * Copyright (C) 2005-2012 Dirk Beyer * * CCVisu is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * CCVisu 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CCVisu; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Please find the GNU Lesser General Public License in file * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt * * Dirk Beyer (firstname.lastname@uni-passau.de) * University of Passau, Bavaria, Germany */ package org.sosy_lab.ccvisu.ui; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.EventObject; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.JColorChooser; import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import org.sosy_lab.ccvisu.Options.OptionsEnum; import org.sosy_lab.ccvisu.graph.GraphData; import org.sosy_lab.ccvisu.graph.GraphEdge; import org.sosy_lab.ccvisu.graph.GraphVertex; import org.sosy_lab.ccvisu.ui.FrameDisplay.GraphCanvas; import org.sosy_lab.util.Colors; public class FrameDisplayMenu implements ActionListener { private GraphCanvas frameDisplayCanvas; private GraphData graph; private JPopupMenu featureMenu; private JMenuItem menuItemZoomOut; private JMenuItem menuItemVertexColor; private JMenuItem menuItemVertexToBackground; private JMenuItem menuItemHideUnrelatedVertices; private JMenuItem menuItemResetHighlighting; private List<JComponent> menuItemsRelations = new ArrayList<JComponent>(); private Map<Integer, Color> edgeColors = new HashMap<Integer, Color>(); private Map<Integer, Color> vertexColors = new HashMap<Integer, Color>(); private GraphVertex featureVertex = null; public FrameDisplayMenu(GraphCanvas frameDisplay, GraphData graph) { this.frameDisplayCanvas = frameDisplay; this.graph = graph; } // Handle action on the MenuItems @Override public void actionPerformed(ActionEvent actionevent) { if (actionevent.getSource() == menuItemZoomOut) { frameDisplayCanvas.zoomOut(); } else if (actionevent.getSource() == menuItemVertexColor) { Color selectedColor = JColorChooser.showDialog(frameDisplayCanvas, "Select Color", Color.black); featureVertex.setColor(selectedColor); for (GraphEdge e : frameDisplayCanvas.getWriter().getGraphData().getAdjacent(featureVertex, "Introduces")) { e.getTarget().setColor(selectedColor); } } else if (actionevent.getSource() == menuItemHideUnrelatedVertices) { hideEdges(); for (GraphEdge e : frameDisplayCanvas.getWriter().getGraphData().getEdges()) { e.setShowEdge(false); } Set<GraphVertex> visibleVertices = new HashSet<GraphVertex>(); visibleVertices.add(featureVertex); for (GraphEdge e : frameDisplayCanvas.getWriter().getGraphData().getAdjacent(featureVertex, ".*")) { visibleVertices.add(e.getTarget()); e.setShowEdge(true); } for (GraphVertex vertex : frameDisplayCanvas.getWriter().getGraphData().getVertices()) { if (!visibleVertices.contains(vertex)) { vertex.setShowVertex(false); } } } else if (actionevent.getSource() == menuItemVertexToBackground) { // TODO: ?? System.out.println("move vertex to background"); } else if (actionevent.getSource() == menuItemResetHighlighting) { for (GraphEdge e : frameDisplayCanvas.getWriter().getGraphData().getEdges()) { e.setShowEdge(false); } for (Integer id : edgeColors.keySet()) { GraphEdge edge = frameDisplayCanvas.getWriter().getGraphData().getEdgeById(id); if (edge != null) { edge.setColor(edgeColors.get(id)); } } for (Integer id : vertexColors.keySet()) { GraphVertex vertex = frameDisplayCanvas.getWriter().getGraphData().getVertexById(id); if (vertex != null) { vertex.setColor(vertexColors.get(id)); } } resetHighlightingCache(); } else { // Highlight chosen relation if (actionevent.getSource() instanceof JMenuItem) { String relName = ((JMenuItem) actionevent.getSource()).getName(); hideEdges(); for (GraphEdge e : frameDisplayCanvas.getWriter().getGraphData().getAdjacent(featureVertex, relName)) { e.setShowEdge(true); if (!edgeColors.containsKey(e.getId())) { edgeColors.put(e.getId(), e.getColor()); } e.setColor(Colors.get("red")); if (!vertexColors.containsKey(e.getTarget().getId())) { vertexColors.put(e.getTarget().getId(), e.getTarget().getColor()); } e.getTarget().setColor(Colors.get("red")); } } } graph.notifyAboutLayoutChange(new EventObject(this)); } public void resetHighlightingCache() { edgeColors.clear(); vertexColors.clear(); } private void hideEdges() { frameDisplayCanvas.getWriter().getOptions().getOption(OptionsEnum.showEdges).set(false); } public JPopupMenu createMenu() { featureMenu = new JPopupMenu(); menuItemZoomOut = new JMenuItem("Zoom out / Reset vertex restrictions"); menuItemZoomOut.addActionListener(this); featureMenu.add(menuItemZoomOut); menuItemVertexColor = new JMenuItem("Select vertex color"); menuItemVertexColor.addActionListener(this); featureMenu.add(menuItemVertexColor); menuItemHideUnrelatedVertices = new JMenuItem("Hide unrelated vertices"); menuItemHideUnrelatedVertices.addActionListener(this); featureMenu.add(menuItemHideUnrelatedVertices); menuItemVertexToBackground = new JMenuItem("Move vertex to background"); menuItemVertexToBackground.addActionListener(this); featureMenu.add(menuItemVertexToBackground); JSeparator separator = new JSeparator(); featureMenu.add(separator); menuItemResetHighlighting = new JMenuItem("Reset highlighting"); menuItemResetHighlighting.addActionListener(this); featureMenu.add(menuItemResetHighlighting); return featureMenu; } public void updateAndShowMenu(MouseEvent evt, Set<String> vertexRelations, GraphVertex featureVertex) { // Remove out-dated menu items for (JComponent menuItem : menuItemsRelations) { featureMenu.remove(menuItem); } if (vertexRelations.size() > 0) { for (String relName : vertexRelations) { JMenuItem relMenuItem = new JMenuItem("Highlight " + relName + " relations"); relMenuItem.setName(relName); relMenuItem.addActionListener(this); menuItemsRelations.add(relMenuItem); featureMenu.add(relMenuItem); } } menuItemVertexColor.setEnabled(featureVertex != null); menuItemHideUnrelatedVertices.setEnabled((featureVertex != null) && (frameDisplayCanvas.getWriter().getGraphData().isEdgesAvailable())); menuItemVertexToBackground.setEnabled(featureVertex != null); menuItemResetHighlighting.setEnabled((edgeColors.size() > 0) && (vertexColors.size() > 0)); this.featureVertex = featureVertex; featureMenu.show(evt.getComponent(), evt.getX(), evt.getY()); } }