/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM 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 3 of the License, or * any later version. * * PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see . * */ package de.tud.kom.p2psim.impl.topology.views.visualization.world; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import de.tud.kom.p2psim.api.common.SimHost; import de.tud.kom.p2psim.api.topology.social.SocialView; import de.tud.kom.p2psim.impl.topology.util.PositionVector; import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector; import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector.MouseClickListener; import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent; /** * This component draw the Social connections. * * @author Christoph Muenker * @version 1.0, 22.06.2013 */ public class SocialViewComponentVis extends JComponent implements MouseClickListener, VisualizationComponent { private static Vector CLUSTER_COLOR = new Vector(); static { CLUSTER_COLOR.add(Color.BLUE); CLUSTER_COLOR.add(Color.GREEN); CLUSTER_COLOR.add(new Color(1f, 0.27f, 0f)); // OrangeRed CLUSTER_COLOR.add(Color.CYAN); CLUSTER_COLOR.add(Color.RED); CLUSTER_COLOR.add(Color.YELLOW); } private SocialView view; private Map posVecs = new HashMap(); private Map> clusterMap = new HashMap>(); private JMenu customMenu; private SimHost selectedHost = null; private boolean showCluster = false; private boolean showRelationship = false; public SocialViewComponentVis(SocialView view) { this.view = view; int i = 0; for (Set cluster : view.getClusters()) { for (SimHost host : cluster) { posVecs.put(host, host.getTopologyComponent().getRealPosition()); } if (i < CLUSTER_COLOR.size()) { clusterMap.put(CLUSTER_COLOR.get(i), cluster); i++; } } setBounds(0, 0, VisualizationInjector.getWorldX(), VisualizationInjector.getWorldY()); setOpaque(true); setVisible(true); VisualizationInjector.addMouseListener(this); customMenu = new JMenu("Social View"); customMenu.add(createRelationshipCheckBox()); customMenu.add(createClusterCheckBox()); } private JCheckBoxMenuItem createRelationshipCheckBox() { final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem("Connections", showRelationship); checkBox.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { showRelationship = checkBox.isSelected(); SocialViewComponentVis.this.repaint(); } }); return checkBox; } private JCheckBoxMenuItem createClusterCheckBox() { final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem("Cluster", showCluster); checkBox.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { showCluster = checkBox.isSelected(); SocialViewComponentVis.this.repaint(); } }); return checkBox; } protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (showRelationship) { for (Entry entry : posVecs.entrySet()) { SimHost source = entry.getKey(); Point sourcePos = entry.getValue().asPoint(); // neighbors for (SimHost dest : view.getNeighbors(source)) { if (selectedHost == null || source.equals(selectedHost) || dest.equals(selectedHost)) { g2.setColor(new Color(0, 0, 0)); } else { g2.setColor(new Color(0, 0, 0, 32)); } Point destPos = posVecs.get(dest).asPoint(); g2.drawLine(sourcePos.x, sourcePos.y, destPos.x, destPos.y); } } } if (showCluster) { for (Entry> clusters : clusterMap.entrySet()) { for (SimHost host : clusters.getValue()) { Point center = posVecs.get(host).asPoint(); // for a black border around the circle g2.setColor(Color.BLACK); g2.setStroke(new BasicStroke(4.5f)); g2.drawOval(center.x - 7, center.y - 7, 14, 14); // draw the circle g2.setColor(clusters.getKey()); g2.setStroke(new BasicStroke(3.5f)); g2.drawOval(center.x - 7, center.y - 7, 14, 14); } } } } @Override public void mouseClicked(int x, int y) { List inNear = new Vector(); for (Entry e : posVecs.entrySet()) { if (e.getValue().distanceTo(new PositionVector(x, y)) < 4) { inNear.add(e.getKey()); } } if (inNear.size() == 1) { selectedHost = inNear.iterator().next(); } else if (inNear.size() > 1) { Collections.shuffle(inNear); selectedHost = inNear.iterator().next(); } else { selectedHost = null; } this.repaint(); } @Override public JComponent getComponent() { return this; } @Override public JMenu getCustomMenu() { return customMenu; } @Override public boolean isHidden() { return false; } @Override public String getDisplayName() { return view.getIdentifier(); } }