visualizer update: enabling selecting multiple visualizer skins

This commit is contained in:
fros4943 2009-04-14 15:40:26 +00:00
parent 3f205a1413
commit 906e341a65
7 changed files with 224 additions and 184 deletions

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: Visualizer.java,v 1.3 2009/04/01 13:51:50 fros4943 Exp $ * $Id: Visualizer.java,v 1.4 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -56,9 +56,8 @@ import org.jdom.Element;
import se.sics.cooja.*; import se.sics.cooja.*;
import se.sics.cooja.GUI.MoteRelation; import se.sics.cooja.GUI.MoteRelation;
import se.sics.cooja.interfaces.*; import se.sics.cooja.interfaces.*;
import se.sics.cooja.plugins.skins.BasicVisualizerSkin; import se.sics.cooja.plugins.skins.IDVisualizerSkin;
import se.sics.cooja.plugins.skins.LEDVisualizerSkin; import se.sics.cooja.plugins.skins.LEDVisualizerSkin;
import se.sics.cooja.plugins.skins.LogLEDVisualizerSkin;
import se.sics.cooja.plugins.skins.LogVisualizerSkin; import se.sics.cooja.plugins.skins.LogVisualizerSkin;
/** /**
@ -72,7 +71,6 @@ import se.sics.cooja.plugins.skins.LogVisualizerSkin;
* @see #registerMoteMenuAction(MoteMenuAction) * @see #registerMoteMenuAction(MoteMenuAction)
* @see #registerSimulationMenuAction(SimulationMenuAction) * @see #registerSimulationMenuAction(SimulationMenuAction)
* @see #registerVisualizerSkin(Class) * @see #registerVisualizerSkin(Class)
* @see BasicVisualizerSkin
* @see UDGMVisualizerSkin * @see UDGMVisualizerSkin
* @author Fredrik Osterlind * @author Fredrik Osterlind
*/ */
@ -86,6 +84,8 @@ public class Visualizer extends VisPlugin {
private static final int CANVAS_BORDER_WIDTH = 25; private static final int CANVAS_BORDER_WIDTH = 25;
public static final int MOTE_RADIUS = 8; public static final int MOTE_RADIUS = 8;
private static final Color[] DEFAULT_MOTE_COLORS = { Color.WHITE };
private GUI gui = null; private GUI gui = null;
private Simulation simulation = null; private Simulation simulation = null;
private final JPanel canvas; private final JPanel canvas;
@ -103,17 +103,16 @@ public class Visualizer extends VisPlugin {
private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR); private Cursor moveCursor = new Cursor(Cursor.MOVE_CURSOR);
/* Visualizer skins */ /* Visualizer skins */
private final JButton skinButton = new JButton("Select visualizer skins");
private static ArrayList<Class<? extends VisualizerSkin>> visualizerSkins = private static ArrayList<Class<? extends VisualizerSkin>> visualizerSkins =
new ArrayList<Class<? extends VisualizerSkin>>(); new ArrayList<Class<? extends VisualizerSkin>>();
static { static {
/* Register default visualizer skins */ /* Register default visualizer skins */
registerVisualizerSkin(BasicVisualizerSkin.class); registerVisualizerSkin(IDVisualizerSkin.class);
registerVisualizerSkin(LogVisualizerSkin.class); registerVisualizerSkin(LogVisualizerSkin.class);
registerVisualizerSkin(LEDVisualizerSkin.class); registerVisualizerSkin(LEDVisualizerSkin.class);
registerVisualizerSkin(LogLEDVisualizerSkin.class);
} }
private JComboBox skinBox = null; private ArrayList<VisualizerSkin> currentSkins = new ArrayList<VisualizerSkin>();
private VisualizerSkin currentSkin = null;
/* Generic visualization */ /* Generic visualization */
private Observer simObserver = null; private Observer simObserver = null;
@ -151,8 +150,9 @@ public class Visualizer extends VisPlugin {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) { public void paintComponent(Graphics g) {
super.paintComponent(g); super.paintComponent(g);
if (currentSkin != null) { paintSkinGeneric(g);
currentSkin.paintSkin(g); for (VisualizerSkin skin: currentSkins) {
skin.paintSkin(g);
} }
} }
}; };
@ -160,19 +160,74 @@ public class Visualizer extends VisPlugin {
calculateTransformations(); calculateTransformations();
/* Skin selector */ /* Skin selector */
skinBox = new JComboBox(); skinButton.addActionListener(new ActionListener() {
skinBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (skinBox.getSelectedIndex() < 0 || Point mouse = MouseInfo.getPointerInfo().getLocation();
skinBox.getSelectedIndex() > visualizerSkins.size()) { JCheckBoxMenuItem item;
JPopupMenu skinPopupMenu = new JPopupMenu();
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
String description = GUI.getDescriptionOf(skinClass);
item = new JCheckBoxMenuItem(description, false);
item.putClientProperty("skinclass", skinClass);
/* Select skin if active */
for (VisualizerSkin skin: currentSkins) {
if (skin.getClass() == skinClass) {
item.setSelected(true);
break;
}
}
item.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
JCheckBoxMenuItem menuItem = ((JCheckBoxMenuItem)e.getItem());
if (menuItem == null) {
logger.fatal("No menu item");
return; return;
} }
Class<? extends VisualizerSkin> skinClass = visualizerSkins.get(skinBox.getSelectedIndex());
selectSkin(skinClass); Class<VisualizerSkin> skinClass =
(Class<VisualizerSkin>) menuItem.getClientProperty("skinclass");
if (skinClass == null) {
logger.fatal("Unknown visualizer skin class: " + skinClass);
return;
}
if (menuItem.isSelected()) {
/* Create and activate new skin */
generateAndActivateSkin(skinClass);
} else {
/* Deactivate skin */
VisualizerSkin skinToDeactivate = null;
for (VisualizerSkin skin: currentSkins) {
if (skin.getClass() == skinClass) {
skinToDeactivate = skin;
break;
}
}
if (skinToDeactivate == null) {
logger.fatal("Unknown visualizer skin to deactivate: " + skinClass);
return;
}
skinToDeactivate.setInactive();
repaint();
currentSkins.remove(skinToDeactivate);
skinButton.setText("Select visualizer skins " +
"(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
}
} }
}); });
this.add(BorderLayout.NORTH, skinBox); skinPopupMenu.add(item);
}
skinPopupMenu.setLocation(mouse);
skinPopupMenu.setInvoker(skinButton);
skinPopupMenu.setVisible(true);
}
});
this.add(BorderLayout.NORTH, skinButton);
this.add(BorderLayout.CENTER, canvas); this.add(BorderLayout.CENTER, canvas);
/* Observe simulation and mote positions */ /* Observe simulation and mote positions */
@ -405,71 +460,38 @@ public class Visualizer extends VisPlugin {
new DropTarget(canvas, DnDConstants.ACTION_COPY_OR_MOVE, dTargetListener, true, null) new DropTarget(canvas, DnDConstants.ACTION_COPY_OR_MOVE, dTargetListener, true, null)
); );
repopulateSkinBox();
this.setSize(300, 300); this.setSize(300, 300);
setLocation(gui.getDesktopPane().getWidth() - getWidth(), 0); setLocation(gui.getDesktopPane().getWidth() - getWidth(), 0);
setVisible(true); setVisible(true);
} }
private void selectSkin(Class<? extends VisualizerSkin> skinClass) { private void generateAndActivateSkin(Class<? extends VisualizerSkin> skinClass) {
for (VisualizerSkin skin: currentSkins) {
if (currentSkin != null && if (skinClass == skin.getClass()) {
skinClass == currentSkin.getClass()) { logger.warn("Selected skin already active: " + skinClass);
return; return;
} }
/* Deactive current skin */
if (currentSkin != null) {
currentSkin.setInactive();
} }
/* Create and activate new skin */ /* Create and activate new skin */
try { try {
VisualizerSkin newSkin = skinClass.newInstance(); VisualizerSkin newSkin = skinClass.newInstance();
newSkin.setActive(Visualizer.this.simulation, Visualizer.this); newSkin.setActive(Visualizer.this.simulation, Visualizer.this);
currentSkin = newSkin; currentSkins.add(newSkin);
} catch (InstantiationException e1) { } catch (InstantiationException e1) {
e1.printStackTrace(); e1.printStackTrace();
} catch (IllegalAccessException e1) { } catch (IllegalAccessException e1) {
e1.printStackTrace(); e1.printStackTrace();
} }
/* Update skin selector box */ skinButton.setText("Select visualizer skins " +
for (int i=0; i < skinBox.getItemCount(); i++) { "(" + currentSkins.size() + "/" + visualizerSkins.size() + ")");
String desc = (String) skinBox.getItemAt(i);
if (desc.equals(GUI.getDescriptionOf(skinClass))) {
if (skinBox.getSelectedIndex() != i) {
skinBox.setSelectedIndex(i);
}
break;
}
}
repaint(); repaint();
} }
public VisualizerSkin getCurrentSkin() { public VisualizerSkin[] getCurrentSkins() {
return currentSkin; VisualizerSkin[] skins = new VisualizerSkin[currentSkins.size()];
} return currentSkins.toArray(skins);
protected void repopulateSkinBox() {
String selected = (String) skinBox.getSelectedItem();
int previousSelectionIndex = -1;
/* Repopulate box */
skinBox.removeAllItems();
for (Class<? extends VisualizerSkin> skin: visualizerSkins) {
String description = GUI.getDescriptionOf(skin);
skinBox.addItem(description);
if (selected != null && selected.equals(description)) {
previousSelectionIndex = skinBox.getItemCount();
}
}
if (previousSelectionIndex >= 0) {
skinBox.setSelectedIndex(previousSelectionIndex);
}
} }
/** /**
@ -504,7 +526,7 @@ public class Visualizer extends VisPlugin {
moteMenuActions.add(menuAction); moteMenuActions.add(menuAction);
} }
public void unregisterMoteMenuAction(Class<? extends SimulationMenuAction> menuAction) { public void unregisterMoteMenuAction(Class<? extends MoteMenuAction> menuAction) {
moteMenuActions.remove(menuAction); moteMenuActions.remove(menuAction);
} }
@ -681,7 +703,19 @@ public class Visualizer extends VisPlugin {
public void paintSkinGeneric(Graphics g) { public void paintSkinGeneric(Graphics g) {
Mote[] allMotes = simulation.getMotes(); Mote[] allMotes = simulation.getMotes();
for (Mote mote: allMotes) { for (Mote mote: allMotes) {
Color moteColors[] = currentSkin.getColorOf(mote);
/* Use the first skin's non-null mote colors */
Color moteColors[] = null;
for (VisualizerSkin skin: currentSkins) {
moteColors = skin.getColorOf(mote);
if (moteColors != null) {
break;
}
}
if (moteColors == null) {
moteColors = DEFAULT_MOTE_COLORS;
}
Position motePos = mote.getInterfaces().getPosition(); Position motePos = mote.getInterfaces().getPosition();
Point pixelCoord = transformPositionToPixel(motePos); Point pixelCoord = transformPositionToPixel(motePos);
@ -861,11 +895,10 @@ public class Visualizer extends VisPlugin {
} }
public void closePlugin() { public void closePlugin() {
skinBox.removeAllItems(); for (VisualizerSkin skin: currentSkins) {
skin.setInactive();
if (currentSkin != null) {
currentSkin.setInactive();
} }
currentSkins.clear();
if (moteHighligtObserver != null) { if (moteHighligtObserver != null) {
gui.deleteMoteHighlightObserver(moteHighligtObserver); gui.deleteMoteHighlightObserver(moteHighligtObserver);
} }
@ -897,9 +930,11 @@ public class Visualizer extends VisPlugin {
Vector<Element> config = new Vector<Element>(); Vector<Element> config = new Vector<Element>();
Element element; Element element;
for (VisualizerSkin skin: currentSkins) {
element = new Element("skin"); element = new Element("skin");
element.setText(GUI.getDescriptionOf(currentSkin.getClass())); element.setText(GUI.getDescriptionOf(skin.getClass()));
config.add(element); config.add(element);
}
return config; return config;
} }
@ -910,10 +945,14 @@ public class Visualizer extends VisPlugin {
String wanted = element.getText(); String wanted = element.getText();
for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) { for (Class<? extends VisualizerSkin> skinClass: visualizerSkins) {
if (wanted.equals(GUI.getDescriptionOf(skinClass))) { if (wanted.equals(GUI.getDescriptionOf(skinClass))) {
selectSkin(skinClass); generateAndActivateSkin(skinClass);
wanted = null;
break; break;
} }
} }
if (wanted != null) {
logger.warn("Could not load skin: " + element.getText());
}
} }
} }
return true; return true;

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: VisualizerSkin.java,v 1.1 2009/03/24 15:46:18 fros4943 Exp $ * $Id: VisualizerSkin.java,v 1.2 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins; package se.sics.cooja.plugins;
@ -84,4 +84,9 @@ public interface VisualizerSkin {
*/ */
public void paintSkin(Graphics g); public void paintSkin(Graphics g);
/**
* @return Visualizer plugin where this skin is showing
*/
public Visualizer getVisualizer();
} }

View file

@ -26,34 +26,40 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: BasicVisualizerSkin.java,v 1.1 2009/03/24 15:46:29 fros4943 Exp $ * $Id: IDVisualizerSkin.java,v 1.1 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins.skins; package se.sics.cooja.plugins.skins;
import java.awt.Color; import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Point;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import se.sics.cooja.ClassDescription; import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote; import se.sics.cooja.Mote;
import se.sics.cooja.Simulation; import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.MoteID;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.plugins.Visualizer; import se.sics.cooja.plugins.Visualizer;
import se.sics.cooja.plugins.VisualizerSkin; import se.sics.cooja.plugins.VisualizerSkin;
/** /**
* Basic visualizer skin. Paints all motes black. * Visualizer skin for mote IDs.
* *
* @author Fredrik Osterlind * @author Fredrik Osterlind
*/ */
@ClassDescription("[select visualizer skin]") @ClassDescription("Mote IDs")
public class BasicVisualizerSkin implements VisualizerSkin { public class IDVisualizerSkin implements VisualizerSkin {
private static Logger logger = Logger.getLogger(BasicVisualizerSkin.class); private static Logger logger = Logger.getLogger(IDVisualizerSkin.class);
private Simulation simulation = null;
private Visualizer visualizer = null; private Visualizer visualizer = null;
public void setActive(Simulation simulation, Visualizer vis) { public void setActive(Simulation simulation, Visualizer vis) {
this.simulation = simulation;
this.visualizer = vis; this.visualizer = vis;
} }
@ -61,11 +67,30 @@ public class BasicVisualizerSkin implements VisualizerSkin {
} }
public Color[] getColorOf(Mote mote) { public Color[] getColorOf(Mote mote) {
return new Color[] { Color.BLACK }; return null;
} }
public void paintSkin(Graphics g) { public void paintSkin(Graphics g) {
/* Just paint motes */ FontMetrics fm = g.getFontMetrics();
visualizer.paintSkinGeneric(g);
/* Paint ID inside each mote */
Mote[] allMotes = simulation.getMotes();
for (Mote mote: allMotes) {
MoteID id = mote.getInterfaces().getMoteID();
if (id == null) {
continue;
}
Position pos = mote.getInterfaces().getPosition();
Point pixel = visualizer.transformPositionToPixel(pos);
String msg = "" + id.getMoteID();
int msgWidth = fm.stringWidth(msg);
g.drawString(msg, pixel.x - msgWidth/2, pixel.y + 5);
}
}
public Visualizer getVisualizer() {
return visualizer;
} }
} }

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: LEDVisualizerSkin.java,v 1.1 2009/03/24 15:46:29 fros4943 Exp $ * $Id: LEDVisualizerSkin.java,v 1.2 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins.skins; package se.sics.cooja.plugins.skins;
@ -134,6 +134,9 @@ public class LEDVisualizerSkin implements VisualizerSkin {
} }
public void paintSkin(Graphics g) { public void paintSkin(Graphics g) {
visualizer.paintSkinGeneric(g); }
public Visualizer getVisualizer() {
return visualizer;
} }
} }

View file

@ -1,75 +0,0 @@
/*
* Copyright (c) 2009, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: LogLEDVisualizerSkin.java,v 1.1 2009/03/24 15:46:29 fros4943 Exp $
*/
package se.sics.cooja.plugins.skins;
import java.awt.Color;
import java.awt.Graphics;
import org.apache.log4j.Logger;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.Simulation;
import se.sics.cooja.plugins.Visualizer;
import se.sics.cooja.plugins.VisualizerSkin;
/**
* Visualizer skin for both Log output and LEDs.
*
* @see LEDVisualizerSkin
* @see LogVisualizerSkin
* @author Fredrik Osterlind
*/
@ClassDescription("printf()'s + LEDs")
public class LogLEDVisualizerSkin implements VisualizerSkin {
private static Logger logger = Logger.getLogger(LogLEDVisualizerSkin.class);
private LEDVisualizerSkin ledSkin = new LEDVisualizerSkin();
private LogVisualizerSkin logSkin = new LogVisualizerSkin();
public void setActive(Simulation simulation, Visualizer vis) {
ledSkin.setActive(simulation, vis);
logSkin.setActive(simulation, vis);
}
public void setInactive() {
ledSkin.setInactive();
logSkin.setInactive();
}
public Color[] getColorOf(Mote mote) {
return ledSkin.getColorOf(mote);
}
public void paintSkin(Graphics g) {
logSkin.paintSkin(g);
}
}

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: LogVisualizerSkin.java,v 1.1 2009/03/24 15:46:29 fros4943 Exp $ * $Id: LogVisualizerSkin.java,v 1.2 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins.skins; package se.sics.cooja.plugins.skins;
@ -100,12 +100,10 @@ public class LogVisualizerSkin implements VisualizerSkin {
} }
public Color[] getColorOf(Mote mote) { public Color[] getColorOf(Mote mote) {
return new Color[] { Color.BLACK }; return null;
} }
public void paintSkin(Graphics g) { public void paintSkin(Graphics g) {
visualizer.paintSkinGeneric(g);
FontMetrics fm = g.getFontMetrics(); FontMetrics fm = g.getFontMetrics();
/* Paint last output below motes */ /* Paint last output below motes */
@ -127,4 +125,8 @@ public class LogVisualizerSkin implements VisualizerSkin {
g.drawString(msg, pixel.x - msgWidth/2, pixel.y - Visualizer.MOTE_RADIUS); g.drawString(msg, pixel.x - msgWidth/2, pixel.y - Visualizer.MOTE_RADIUS);
} }
} }
public Visualizer getVisualizer() {
return visualizer;
}
} }

View file

@ -26,13 +26,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: UDGMVisualizerSkin.java,v 1.3 2009/03/26 16:24:31 fros4943 Exp $ * $Id: UDGMVisualizerSkin.java,v 1.4 2009/04/14 15:40:26 fros4943 Exp $
*/ */
package se.sics.cooja.plugins.skins; package se.sics.cooja.plugins.skins;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point; import java.awt.Point;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
@ -65,7 +66,7 @@ import se.sics.cooja.radiomediums.UDGM;
* Allows a user to change the collective TX/interference ranges, * Allows a user to change the collective TX/interference ranges,
* and the TX/RX success ratio. * and the TX/RX success ratio.
* *
* Transmitting motes are painted blue. * Transmitting motes are painted blue. XXXXXXXX
* Receiving motes are painted green. * Receiving motes are painted green.
* Interfered motes are painted red. * Interfered motes are painted red.
* Motes without radios are painted gray. * Motes without radios are painted gray.
@ -118,6 +119,10 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
}; };
public void setActive(Simulation simulation, Visualizer vis) { public void setActive(Simulation simulation, Visualizer vis) {
if (!(simulation.getRadioMedium() instanceof UDGM)) {
logger.fatal("Cannot activate UDGM skin for unknown radio medium: " + simulation.getRadioMedium());
return;
}
this.simulation = simulation; this.simulation = simulation;
this.visualizer = vis; this.visualizer = vis;
this.radioMedium = (UDGM) simulation.getRadioMedium(); this.radioMedium = (UDGM) simulation.getRadioMedium();
@ -244,6 +249,11 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
} }
public void setInactive() { public void setInactive() {
if (simulation == null) {
/* Skin was never activated */
return;
}
/* Remove mouse listener */ /* Remove mouse listener */
visualizer.getCurrentCanvas().removeMouseListener(selectMoteMouseListener); visualizer.getCurrentCanvas().removeMouseListener(selectMoteMouseListener);
@ -268,13 +278,18 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
} }
public Color[] getColorOf(Mote mote) { public Color[] getColorOf(Mote mote) {
Radio moteRadio = mote.getInterfaces().getRadio(); if (simulation == null) {
if (moteRadio == null) { /* Skin was never activated */
return new Color[] { Color.BLACK }; return null;
} }
if (mote.getState() == Mote.State.DEAD) { if (mote.getState() == Mote.State.DEAD) {
return new Color[] { Color.BLACK }; return null;
}
Radio moteRadio = mote.getInterfaces().getRadio();
if (moteRadio == null) {
return null;
} }
if (selectedMote != null && mote == selectedMote) { if (selectedMote != null && mote == selectedMote) {
@ -297,12 +312,30 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
return new Color[] { Color.GREEN }; return new Color[] { Color.GREEN };
} }
return new Color[] { Color.WHITE }; return null;
} }
private static Color COLOR_INTERFERENCE = new Color(
Color.DARK_GRAY.getRed(),
Color.DARK_GRAY.getGreen(),
Color.DARK_GRAY.getBlue(),
100
);
private static Color COLOR_TX = new Color(
Color.GREEN.getRed(),
Color.GREEN.getGreen(),
Color.GREEN.getBlue(),
100
);
public void paintSkin(Graphics g) { public void paintSkin(Graphics g) {
if (simulation == null) {
/* Skin was never activated */
return;
}
/* Paint transmission and interference range for select mote */ /* Paint transmission and interference range for select mote */
if (selectedMote != null) { if (selectedMote != null) {
Graphics2D g2 = (Graphics2D) g;
Position motePos = selectedMote.getInterfaces().getPosition(); Position motePos = selectedMote.getInterfaces().getPosition();
Point pixelCoord = visualizer.transformPositionToPixel(motePos); Point pixelCoord = visualizer.transformPositionToPixel(motePos);
@ -331,7 +364,7 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
translatedTransmission.y = Math.abs(translatedTransmission.y - translatedZero.y); translatedTransmission.y = Math.abs(translatedTransmission.y - translatedZero.y);
/* Interference range */ /* Interference range */
g.setColor(Color.DARK_GRAY); g.setColor(COLOR_INTERFERENCE);
g.fillOval( g.fillOval(
x - translatedInterference.x, x - translatedInterference.x,
y - translatedInterference.y, y - translatedInterference.y,
@ -339,7 +372,7 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
2 * translatedInterference.y); 2 * translatedInterference.y);
/* Transmission range */ /* Transmission range */
g.setColor(Color.GREEN); g.setColor(COLOR_TX);
g.fillOval( g.fillOval(
x - translatedTransmission.x, x - translatedTransmission.x,
y - translatedTransmission.y, y - translatedTransmission.y,
@ -348,9 +381,6 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
} }
} }
/* Skin generic visualization */
visualizer.paintSkinGeneric(g);
/* Paint active connections in black */ /* Paint active connections in black */
RadioConnection[] conns = radioMedium.getActiveConnections(); RadioConnection[] conns = radioMedium.getActiveConnections();
if (conns != null) { if (conns != null) {
@ -391,11 +421,15 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
} }
public void doAction(Visualizer visualizer, Simulation simulation) { public void doAction(Visualizer visualizer, Simulation simulation) {
UDGMVisualizerSkin skin = (UDGMVisualizerSkin) visualizer.getCurrentSkin(); VisualizerSkin[] skins = visualizer.getCurrentSkins();
skin.txRangeSpinner.setVisible(true); for (VisualizerSkin skin: skins) {
skin.interferenceRangeSpinner.setVisible(true); if (skin instanceof UDGMVisualizerSkin) {
((UDGMVisualizerSkin)skin).txRangeSpinner.setVisible(true);
((UDGMVisualizerSkin)skin).interferenceRangeSpinner.setVisible(true);
visualizer.repaint(); visualizer.repaint();
} }
}
}
}; };
public static class SuccessRatioMenuAction implements SimulationMenuAction { public static class SuccessRatioMenuAction implements SimulationMenuAction {
@ -408,11 +442,18 @@ public class UDGMVisualizerSkin implements VisualizerSkin {
} }
public void doAction(Visualizer visualizer, Simulation simulation) { public void doAction(Visualizer visualizer, Simulation simulation) {
UDGMVisualizerSkin skin = (UDGMVisualizerSkin) visualizer.getCurrentSkin(); VisualizerSkin[] skins = visualizer.getCurrentSkins();
skin.successRatioTxSpinner.setVisible(true); for (VisualizerSkin skin: skins) {
skin.successRatioRxSpinner.setVisible(true); if (skin instanceof UDGMVisualizerSkin) {
((UDGMVisualizerSkin)skin).successRatioTxSpinner.setVisible(true);
((UDGMVisualizerSkin)skin).successRatioRxSpinner.setVisible(true);
visualizer.repaint(); visualizer.repaint();
} }
}
}
}; };
public Visualizer getVisualizer() {
return visualizer;
}
} }