extracted quick help interface to a separate file, moved plugin-specific quick help from quickhelp.txt to the plugins themselves
This commit is contained in:
parent
1a10fa9d58
commit
e96a375e33
|
@ -51,7 +51,7 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
import se.sics.cooja.GUI.HasQuickHelp;
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MotePlugin;
|
import se.sics.cooja.MotePlugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
|
|
|
@ -48,6 +48,7 @@ import javax.swing.JTextField;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MotePlugin;
|
import se.sics.cooja.MotePlugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
|
@ -63,7 +64,7 @@ import se.sics.mspsim.cli.LineOutputStream;
|
||||||
@ClassDescription("Msp CLI")
|
@ClassDescription("Msp CLI")
|
||||||
@PluginType(PluginType.MOTE_PLUGIN)
|
@PluginType(PluginType.MOTE_PLUGIN)
|
||||||
@SupportedArguments(motes = {MspMote.class})
|
@SupportedArguments(motes = {MspMote.class})
|
||||||
public class MspCLI extends VisPlugin implements MotePlugin {
|
public class MspCLI extends VisPlugin implements MotePlugin, HasQuickHelp {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2833218439838209672L;
|
private static final long serialVersionUID = 2833218439838209672L;
|
||||||
|
|
||||||
|
@ -222,4 +223,13 @@ public class MspCLI extends VisPlugin implements MotePlugin {
|
||||||
return mspMote;
|
return mspMote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getQuickHelp() {
|
||||||
|
return
|
||||||
|
"<b>MSPSim's Command Line Interface</b>" +
|
||||||
|
"<br><br>help<br><i>lists available commands</i>" +
|
||||||
|
"<br><br>info CC2420<br><i>shows radio chip details</i>" +
|
||||||
|
"<br><br>log CC2420 > mylog.txt<br><i>logs radio chip details to file</i>" +
|
||||||
|
"<br><br>stacktrace<br><i>shows current stacktrace</i>";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,74 +1,3 @@
|
||||||
se.sics.cooja.plugins.Visualizer = \
|
|
||||||
<b>Visualizer</b> \
|
|
||||||
<p>The visualizer shows the positions of simulated motes as viewed from above (XY-plane). \
|
|
||||||
It is possible to zoom (CRTL+Mouse drag) and pan (Shift+Mouse drag) the current view. Motes can be moved by dragging them (ALT+Mouse drag). \
|
|
||||||
Mouse right-click a mote or unoccupied space for a popup menu with more options. \
|
|
||||||
<p>The visualizer supports "visualizer skins". \
|
|
||||||
Each skin provides some specific information, such as ongoing simulated radio traffic, or the IP addresses of motes. \
|
|
||||||
Multiple skins can be active at the same time. \
|
|
||||||
Click the upper "Select visualizer skin" button to select or deselect skins. \
|
|
||||||
<p><b>Useful skins</b> \
|
|
||||||
<br>Mote IDs: prints the unique mote IDs inside motes. \
|
|
||||||
<br>Log output: prints the last printf message above motes. \
|
|
||||||
<br>Radio traffic: displays inter-mote radio communication. \
|
|
||||||
<br>Radio environment (UDGM): enables configurating the UDGM radio medium. \
|
|
||||||
<p><b>Tip</b><br> \
|
|
||||||
Right-click visualizer to show the popup menu, and click "Hide window decorations".
|
|
||||||
|
|
||||||
se.sics.cooja.plugins.LogListener = \
|
|
||||||
<b>Log Listener</b>\
|
|
||||||
<p>Listens to log output from all simulated motes. \
|
|
||||||
Right-click the main area for a popup menu with more options. \
|
|
||||||
<p>You may filter shown logs by entering regular expressions in the bottom text field. \
|
|
||||||
Filtering is performed on both the Mote and the Data columns.\
|
|
||||||
<p><b>Filter examples:</b> \
|
|
||||||
<br><br>Hello<br><i>logs containing the string 'Hello'</i>\
|
|
||||||
<br><br>^Contiki<br><i>logs starting with 'Contiki'</i>\
|
|
||||||
<br><br>^[CR]<br><i>logs starting either a C or an R</i>\
|
|
||||||
<br><br>Hello$<br><i>logs ending with 'Hello'</i>\
|
|
||||||
<br><br>^ID:[2-5]$<br><i>logs from motes 2 to 5</i>\
|
|
||||||
<br><br>^ID:[2-5] Contiki<br><i>logs from motes 2 to 5 starting with 'Contiki'</i>
|
|
||||||
|
|
||||||
se.sics.cooja.plugins.TimeLine = \
|
|
||||||
<b>Timeline</b>\
|
|
||||||
<p>The timeline arranges historical simulation events into a graphical timeline. \
|
|
||||||
The timeline can for example be used to overview the behavior of complex power-saving MAC protocols.\
|
|
||||||
<p>Events appear as colored rectangles in the timeline. For more information about a particular event, hover the mouse above it.\
|
|
||||||
<p>The checkboxes in the left pane control what event types are shown in the timeline. \
|
|
||||||
Currently, four event types are supported (see below). Note that the control pane can be hidden to save space. \
|
|
||||||
<p>All simulated motes are by default added to the timeline, however, any unwanted motes can be removed by mouse clicking the node ID (left).\
|
|
||||||
<p>To display a vertical time marker on the timeline, press and hold the mouse on the time ruler (top).\
|
|
||||||
<p>For more options, such as zooming and saving raw data to file, right-click the mouse for a popup menu.\
|
|
||||||
<p><b>Radio RX/TX</b>\
|
|
||||||
<br>Shows radio connection events. Transmissions are painted blue, receptions are green, and interfered radios are red.\
|
|
||||||
<p><b>Radio ON/OFF</b>\
|
|
||||||
<br>Shows whether the mote radio is on or off. Turned on radios are indicated with gray color.\
|
|
||||||
<p><b>LEDs</b>\
|
|
||||||
<br>Shows LED state: red, green, and blue. (Assumes all mote types have exactly three LEDs.)\
|
|
||||||
<p><b>Watchpoints</b>\
|
|
||||||
<br>Shows triggered watchpoints, currently only supported by MSPSim-based motes. To add watchpoints, use the Msp Code Watcher plugin.
|
|
||||||
|
|
||||||
se.sics.cooja.plugins.SimControl = \
|
|
||||||
<b>Control Panel</b>\
|
|
||||||
<p>The control panel controls the simulation. \
|
|
||||||
<p><i>Start</i> starts the simulation. \
|
|
||||||
<p><i>Pause</i> stops the simulation. \
|
|
||||||
<p>The keyboard shortcut for starting and pausing the simulation is <i>Ctrl+S</i>. \
|
|
||||||
<p><i>Step</i> runs the simulation for one millisecond. \
|
|
||||||
<p><i>Reload</i> reloads and restarts the simulation. \
|
|
||||||
<p>Writing simulation time in milliseconds in the <i>Stop at</i> field causes the simulation to pause at the given time. \
|
|
||||||
<p>Simulation speed is controlled via the bottom slider. \
|
|
||||||
If the slider value is zero, simulation runs at full speed. \
|
|
||||||
<p>Setting the slider to <i>Real time</i>, simulation speed is capped to not run faster than real time. \
|
|
||||||
The <i>Real time</i> slider value is to the right of <i>No simulation delay</i>: click on the slider button and press the right arrow key on the keyboard. \
|
|
||||||
|
|
||||||
se.sics.cooja.mspmote.plugins.MspCLI = \
|
|
||||||
<b>MSPSim's Command Line Interface</b>\
|
|
||||||
<br><br>help<br><i>lists available commands</i>\
|
|
||||||
<br><br>info CC2420<br><i>shows radio chip details</i>\
|
|
||||||
<br><br>log CC2420 > mylog.txt<br><i>logs radio chip details to file</i>\
|
|
||||||
<br><br>stacktrace<br><i>shows current stacktrace</i>
|
|
||||||
|
|
||||||
KEYBOARD_SHORTCUTS = \
|
KEYBOARD_SHORTCUTS = \
|
||||||
<b>Keyboard shortcuts</b><br>\
|
<b>Keyboard shortcuts</b><br>\
|
||||||
<br><i>Ctrl+N:</i> New simulation\
|
<br><i>Ctrl+N:</i> New simulation\
|
||||||
|
@ -79,3 +8,8 @@ KEYBOARD_SHORTCUTS = \
|
||||||
<br>\
|
<br>\
|
||||||
<br><i>F1:</i> Toggle quick help
|
<br><i>F1:</i> Toggle quick help
|
||||||
|
|
||||||
|
GETTING_STARTED = \
|
||||||
|
<b>Getting started</b><br>\
|
||||||
|
<br>\
|
||||||
|
<br><i>F1:</i> Toggle quick help</i>
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,6 @@ public class GUI extends Observable {
|
||||||
BorderFactory.createEmptyBorder(0, 3, 0, 0)
|
BorderFactory.createEmptyBorder(0, 3, 0, 0)
|
||||||
));
|
));
|
||||||
quickHelpScroll.setVisible(false);
|
quickHelpScroll.setVisible(false);
|
||||||
loadQuickHelp("KEYBOARD_SHORTCUTS");
|
|
||||||
loadQuickHelp("GETTING_STARTED");
|
loadQuickHelp("GETTING_STARTED");
|
||||||
|
|
||||||
// Load default and overwrite with user settings (if any)
|
// Load default and overwrite with user settings (if any)
|
||||||
|
@ -4217,14 +4216,6 @@ public class GUI extends Observable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface HasQuickHelp {
|
|
||||||
/**
|
|
||||||
* @return Quick help. May be HTML formatted, but must not include the
|
|
||||||
* document html-tags.
|
|
||||||
*/
|
|
||||||
public String getQuickHelp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load quick help for given object or identifier. Note that this method does not
|
* Load quick help for given object or identifier. Note that this method does not
|
||||||
* show the quick help pane.
|
* show the quick help pane.
|
||||||
|
|
38
tools/cooja/java/se/sics/cooja/HasQuickHelp.java
Executable file
38
tools/cooja/java/se/sics/cooja/HasQuickHelp.java
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja;
|
||||||
|
|
||||||
|
public interface HasQuickHelp {
|
||||||
|
/**
|
||||||
|
* @return Quick help. May be HTML formatted, but must not include the
|
||||||
|
* document html-tags.
|
||||||
|
*/
|
||||||
|
public String getQuickHelp();
|
||||||
|
}
|
|
@ -84,13 +84,14 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.Plugin;
|
import se.sics.cooja.Plugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
import se.sics.cooja.Simulation;
|
|
||||||
import se.sics.cooja.VisPlugin;
|
|
||||||
import se.sics.cooja.SimEventCentral.LogOutputEvent;
|
import se.sics.cooja.SimEventCentral.LogOutputEvent;
|
||||||
import se.sics.cooja.SimEventCentral.LogOutputListener;
|
import se.sics.cooja.SimEventCentral.LogOutputListener;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.dialogs.TableColumnAdjuster;
|
import se.sics.cooja.dialogs.TableColumnAdjuster;
|
||||||
import se.sics.cooja.dialogs.UpdateAggregator;
|
import se.sics.cooja.dialogs.UpdateAggregator;
|
||||||
import se.sics.cooja.util.ArrayQueue;
|
import se.sics.cooja.util.ArrayQueue;
|
||||||
|
@ -103,7 +104,7 @@ import se.sics.cooja.util.ArrayQueue;
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Log Listener")
|
@ClassDescription("Log Listener")
|
||||||
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
||||||
public class LogListener extends VisPlugin {
|
public class LogListener extends VisPlugin implements HasQuickHelp {
|
||||||
private static final long serialVersionUID = 3294595371354857261L;
|
private static final long serialVersionUID = 3294595371354857261L;
|
||||||
private static Logger logger = Logger.getLogger(LogListener.class);
|
private static Logger logger = Logger.getLogger(LogListener.class);
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ public class LogListener extends VisPlugin {
|
||||||
|
|
||||||
private boolean formatTimeString = false;
|
private boolean formatTimeString = false;
|
||||||
private boolean hasHours = false;
|
private boolean hasHours = false;
|
||||||
|
|
||||||
private final JTable logTable;
|
private final JTable logTable;
|
||||||
private TableRowSorter<TableModel> logFilter;
|
private TableRowSorter<TableModel> logFilter;
|
||||||
private ArrayQueue<LogData> logs = new ArrayQueue<LogData>();
|
private ArrayQueue<LogData> logs = new ArrayQueue<LogData>();
|
||||||
|
@ -147,9 +148,9 @@ public class LogListener extends VisPlugin {
|
||||||
|
|
||||||
private boolean hideDebug = false;
|
private boolean hideDebug = false;
|
||||||
private JCheckBoxMenuItem hideDebugCheckbox;
|
private JCheckBoxMenuItem hideDebugCheckbox;
|
||||||
|
|
||||||
private JCheckBoxMenuItem appendCheckBox;
|
private JCheckBoxMenuItem appendCheckBox;
|
||||||
|
|
||||||
private static final int UPDATE_INTERVAL = 250;
|
private static final int UPDATE_INTERVAL = 250;
|
||||||
private UpdateAggregator<LogData> logUpdateAggregator = new UpdateAggregator<LogData>(UPDATE_INTERVAL) {
|
private UpdateAggregator<LogData> logUpdateAggregator = new UpdateAggregator<LogData>(UPDATE_INTERVAL) {
|
||||||
private Runnable scroll = new Runnable() {
|
private Runnable scroll = new Runnable() {
|
||||||
|
@ -187,7 +188,7 @@ public class LogListener extends VisPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param simulation Simulation
|
* @param simulation Simulation
|
||||||
* @param gui GUI
|
* @param gui GUI
|
||||||
|
@ -394,7 +395,7 @@ public class LogListener extends VisPlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
logTable.setComponentPopupMenu(popupMenu);
|
logTable.setComponentPopupMenu(popupMenu);
|
||||||
|
|
||||||
/* Fetch log output history */
|
/* Fetch log output history */
|
||||||
|
@ -515,7 +516,7 @@ public class LogListener extends VisPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTitle() {
|
private void updateTitle() {
|
||||||
setTitle("Log Listener listening on "
|
setTitle("Log Listener listening on "
|
||||||
+ simulation.getEventCentral().getLogOutputObservationsCount() + " log interfaces");
|
+ simulation.getEventCentral().getLogOutputObservationsCount() + " log interfaces");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +656,7 @@ public class LogListener extends VisPlugin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LogData {
|
private class LogData {
|
||||||
|
@ -726,8 +727,8 @@ public class LogListener extends VisPlugin {
|
||||||
PrintWriter outStream = new PrintWriter(new FileWriter(saveFile));
|
PrintWriter outStream = new PrintWriter(new FileWriter(saveFile));
|
||||||
for(LogData data : logs) {
|
for(LogData data : logs) {
|
||||||
outStream.println(
|
outStream.println(
|
||||||
data.getTime() + "\t" +
|
data.getTime() + "\t" +
|
||||||
data.getID() + "\t" +
|
data.getID() + "\t" +
|
||||||
data.ev.getMessage());
|
data.ev.getMessage());
|
||||||
}
|
}
|
||||||
outStream.close();
|
outStream.close();
|
||||||
|
@ -817,7 +818,7 @@ public class LogListener extends VisPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private Action timeLineAction = new AbstractAction("Timeline") {
|
private Action timeLineAction = new AbstractAction("Timeline") {
|
||||||
private static final long serialVersionUID = -6358463434933029699L;
|
private static final long serialVersionUID = -6358463434933029699L;
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
@ -833,7 +834,7 @@ public class LogListener extends VisPlugin {
|
||||||
if (!(p instanceof TimeLine)) {
|
if (!(p instanceof TimeLine)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select simulation time */
|
/* Select simulation time */
|
||||||
TimeLine plugin = (TimeLine) p;
|
TimeLine plugin = (TimeLine) p;
|
||||||
plugin.trySelectTime(time);
|
plugin.trySelectTime(time);
|
||||||
|
@ -856,7 +857,7 @@ public class LogListener extends VisPlugin {
|
||||||
if (!(p instanceof RadioLogger)) {
|
if (!(p instanceof RadioLogger)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select simulation time */
|
/* Select simulation time */
|
||||||
RadioLogger plugin = (RadioLogger) p;
|
RadioLogger plugin = (RadioLogger) p;
|
||||||
plugin.trySelectTime(time);
|
plugin.trySelectTime(time);
|
||||||
|
@ -891,7 +892,7 @@ public class LogListener extends VisPlugin {
|
||||||
model.fireTableRowsDeleted(0, size - 1);
|
model.fireTableRowsDeleted(0, size - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action copyAction = new AbstractAction("Selected") {
|
private Action copyAction = new AbstractAction("Selected") {
|
||||||
private static final long serialVersionUID = -8433490108577001803L;
|
private static final long serialVersionUID = -8433490108577001803L;
|
||||||
|
|
||||||
|
@ -953,4 +954,20 @@ public class LogListener extends VisPlugin {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public String getQuickHelp() {
|
||||||
|
return
|
||||||
|
"<b>Log Listener</b>" +
|
||||||
|
"<p>Listens to log output from all simulated motes. " +
|
||||||
|
"Right-click the main area for a popup menu with more options. " +
|
||||||
|
"<p>You may filter shown logs by entering regular expressions in the bottom text field. " +
|
||||||
|
"Filtering is performed on both the Mote and the Data columns." +
|
||||||
|
"<p><b>Filter examples:</b> " +
|
||||||
|
"<br><br>Hello<br><i>logs containing the string 'Hello'</i>" +
|
||||||
|
"<br><br>^Contiki<br><i>logs starting with 'Contiki'</i>" +
|
||||||
|
"<br><br>^[CR]<br><i>logs starting either a C or an R</i>" +
|
||||||
|
"<br><br>Hello$<br><i>logs ending with 'Hello'</i>" +
|
||||||
|
"<br><br>^ID:[2-5]$<br><i>logs from motes 2 to 5</i>" +
|
||||||
|
"<br><br>^ID:[2-5] Contiki<br><i>logs from motes 2 to 5 starting with 'Contiki'</i>";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,13 +51,13 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteInterface;
|
import se.sics.cooja.MoteInterface;
|
||||||
import se.sics.cooja.MotePlugin;
|
import se.sics.cooja.MotePlugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
import se.sics.cooja.Simulation;
|
import se.sics.cooja.Simulation;
|
||||||
import se.sics.cooja.VisPlugin;
|
import se.sics.cooja.VisPlugin;
|
||||||
import se.sics.cooja.GUI.HasQuickHelp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mote Interface Viewer views information about a specific mote interface.
|
* Mote Interface Viewer views information about a specific mote interface.
|
||||||
|
@ -208,7 +208,7 @@ public class MoteInterfaceViewer extends VisPlugin implements HasQuickHelp, Mote
|
||||||
setSelectedInterface(element.getText());
|
setSelectedInterface(element.getText());
|
||||||
} else if (element.getName().equals("scrollpos")) {
|
} else if (element.getName().equals("scrollpos")) {
|
||||||
String[] scrollPos = element.getText().split(",");
|
String[] scrollPos = element.getText().split(",");
|
||||||
final Point pos = new Point(Integer.parseInt(scrollPos[0]), Integer.parseInt(scrollPos[1]));
|
final Point pos = new Point(Integer.parseInt(scrollPos[0]), Integer.parseInt(scrollPos[1]));
|
||||||
EventQueue.invokeLater(new Runnable() {
|
EventQueue.invokeLater(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
mainScrollPane.getViewport().setViewPosition(pos);
|
mainScrollPane.getViewport().setViewPosition(pos);
|
||||||
|
@ -222,7 +222,7 @@ public class MoteInterfaceViewer extends VisPlugin implements HasQuickHelp, Mote
|
||||||
public String getQuickHelp() {
|
public String getQuickHelp() {
|
||||||
String help = "<b>" + GUI.getDescriptionOf(this) + "</b>";
|
String help = "<b>" + GUI.getDescriptionOf(this) + "</b>";
|
||||||
help += "<p>Lists mote interfaces, and allows mote inspection and interaction via mote interface visualizers.";
|
help += "<p>Lists mote interfaces, and allows mote inspection and interaction via mote interface visualizers.";
|
||||||
|
|
||||||
MoteInterface intf = selectedMoteInterface;
|
MoteInterface intf = selectedMoteInterface;
|
||||||
if (intf != null) {
|
if (intf != null) {
|
||||||
if (intf instanceof HasQuickHelp) {
|
if (intf instanceof HasQuickHelp) {
|
||||||
|
|
|
@ -31,19 +31,41 @@
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.event.*;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.*;
|
import java.util.Observable;
|
||||||
import javax.swing.*;
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFormattedTextField;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSlider;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import javax.swing.event.*;
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.ClassDescription;
|
||||||
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
|
import se.sics.cooja.PluginType;
|
||||||
|
import se.sics.cooja.Simulation;
|
||||||
|
import se.sics.cooja.TimeEvent;
|
||||||
|
import se.sics.cooja.VisPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control panel for starting and pausing the current simulation.
|
* Control panel for starting and pausing the current simulation.
|
||||||
|
@ -53,7 +75,7 @@ import se.sics.cooja.*;
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Control Panel")
|
@ClassDescription("Control Panel")
|
||||||
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
||||||
public class SimControl extends VisPlugin {
|
public class SimControl extends VisPlugin implements HasQuickHelp {
|
||||||
private static final long serialVersionUID = 8452253637624664192L;
|
private static final long serialVersionUID = 8452253637624664192L;
|
||||||
private static Logger logger = Logger.getLogger(SimControl.class);
|
private static Logger logger = Logger.getLogger(SimControl.class);
|
||||||
|
|
||||||
|
@ -84,7 +106,7 @@ public class SimControl extends VisPlugin {
|
||||||
|
|
||||||
/* Update current time label when simulation is running */
|
/* Update current time label when simulation is running */
|
||||||
if (simulation.isRunning()) {
|
if (simulation.isRunning()) {
|
||||||
updateLabelTimer.start();
|
updateLabelTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Container */
|
/* Container */
|
||||||
|
@ -197,9 +219,9 @@ public class SimControl extends VisPlugin {
|
||||||
smallPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
|
smallPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
|
||||||
|
|
||||||
sliderDelay = new JSlider(
|
sliderDelay = new JSlider(
|
||||||
JSlider.HORIZONTAL,
|
JSlider.HORIZONTAL,
|
||||||
SLIDE_MIN,
|
SLIDE_MIN,
|
||||||
SLIDE_MAX,
|
SLIDE_MAX,
|
||||||
convertTimeToSlide(simulation.getDelayTime()));
|
convertTimeToSlide(simulation.getDelayTime()));
|
||||||
sliderDelay.addChangeListener(new ChangeListener() {
|
sliderDelay.addChangeListener(new ChangeListener() {
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
@ -285,9 +307,9 @@ public class SimControl extends VisPlugin {
|
||||||
return Integer.MIN_VALUE;
|
return Integer.MIN_VALUE;
|
||||||
}
|
}
|
||||||
if (slide <= 0) {
|
if (slide <= 0) {
|
||||||
return slide-2; /* Ignore special cases */
|
return slide-2; /* Ignore special cases */
|
||||||
}
|
}
|
||||||
return slide;
|
return slide;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int convertTimeToSlide(int time) {
|
private int convertTimeToSlide(int time) {
|
||||||
|
@ -341,7 +363,7 @@ public class SimControl extends VisPlugin {
|
||||||
+ " ms");
|
+ " ms");
|
||||||
|
|
||||||
long systemTimeDiff = System.currentTimeMillis() - lastSystemTimeTimestamp;
|
long systemTimeDiff = System.currentTimeMillis() - lastSystemTimeTimestamp;
|
||||||
|
|
||||||
if(systemTimeDiff > 1000) {
|
if(systemTimeDiff > 1000) {
|
||||||
|
|
||||||
long simulationTimeDiff = simulation.getSimulationTimeMillis() - lastSimulationTimeTimestamp;
|
long simulationTimeDiff = simulation.getSimulationTimeMillis() - lastSimulationTimeTimestamp;
|
||||||
|
@ -382,4 +404,19 @@ public class SimControl extends VisPlugin {
|
||||||
simulation.getGUI().reloadCurrentSimulation(simulation.isRunning());
|
simulation.getGUI().reloadCurrentSimulation(simulation.isRunning());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public String getQuickHelp() {
|
||||||
|
return "<b>Control Panel</b>" +
|
||||||
|
"<p>The control panel controls the simulation. " +
|
||||||
|
"<p><i>Start</i> starts the simulation. " +
|
||||||
|
"<p><i>Pause</i> stops the simulation. " +
|
||||||
|
"<p>The keyboard shortcut for starting and pausing the simulation is <i>Ctrl+S</i>. " +
|
||||||
|
"<p><i>Step</i> runs the simulation for one millisecond. " +
|
||||||
|
"<p><i>Reload</i> reloads and restarts the simulation. " +
|
||||||
|
"<p>Writing simulation time in milliseconds in the <i>Stop at</i> field causes the simulation to pause at the given time. " +
|
||||||
|
"<p>Simulation speed is controlled via the bottom slider. " +
|
||||||
|
"If the slider value is zero, simulation runs at full speed. " +
|
||||||
|
"<p>Setting the slider to <i>Real time</i>, simulation speed is capped to not run faster than real time. " +
|
||||||
|
"The <i>Real time</i> slider value is to the right of <i>No simulation delay</i>: click on the slider button and press the right arrow key on the keyboard. ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.Plugin;
|
import se.sics.cooja.Plugin;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
|
@ -107,7 +108,7 @@ import se.sics.cooja.motes.AbstractEmulatedMote;
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Timeline")
|
@ClassDescription("Timeline")
|
||||||
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
||||||
public class TimeLine extends VisPlugin {
|
public class TimeLine extends VisPlugin implements HasQuickHelp {
|
||||||
private static final long serialVersionUID = -883154261246961973L;
|
private static final long serialVersionUID = -883154261246961973L;
|
||||||
public static final int LED_PIXEL_HEIGHT = 2;
|
public static final int LED_PIXEL_HEIGHT = 2;
|
||||||
public static final int EVENT_PIXEL_HEIGHT = 4;
|
public static final int EVENT_PIXEL_HEIGHT = 4;
|
||||||
|
@ -242,7 +243,7 @@ public class TimeLine extends VisPlugin {
|
||||||
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||||
timelineScrollPane.getHorizontalScrollBar().setUnitIncrement(50);
|
timelineScrollPane.getHorizontalScrollBar().setUnitIncrement(50);
|
||||||
|
|
||||||
timelineMoteRuler = new MoteRuler();
|
timelineMoteRuler = new MoteRuler();
|
||||||
timelineScrollPane.setRowHeaderView(timelineMoteRuler);
|
timelineScrollPane.setRowHeaderView(timelineMoteRuler);
|
||||||
timelineScrollPane.setBackground(Color.WHITE);
|
timelineScrollPane.setBackground(Color.WHITE);
|
||||||
|
@ -2386,4 +2387,25 @@ public class TimeLine extends VisPlugin {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public String getQuickHelp() {
|
||||||
|
return
|
||||||
|
"<b>Timeline</b>" +
|
||||||
|
"<p>The timeline arranges historical simulation events into a graphical timeline. " +
|
||||||
|
"The timeline can for example be used to overview the behavior of complex power-saving MAC protocols." +
|
||||||
|
"<p>Events appear as colored rectangles in the timeline. For more information about a particular event, hover the mouse above it." +
|
||||||
|
"<p>The checkboxes in the left pane control what event types are shown in the timeline. " +
|
||||||
|
"Currently, four event types are supported (see below). Note that the control pane can be hidden to save space. " +
|
||||||
|
"<p>All simulated motes are by default added to the timeline, however, any unwanted motes can be removed by mouse clicking the node ID (left)." +
|
||||||
|
"<p>To display a vertical time marker on the timeline, press and hold the mouse on the time ruler (top)." +
|
||||||
|
"<p>For more options, such as zooming and saving raw data to file, right-click the mouse for a popup menu." +
|
||||||
|
"<p><b>Radio RX/TX</b>" +
|
||||||
|
"<br>Shows radio connection events. Transmissions are painted blue, receptions are green, and interfered radios are red." +
|
||||||
|
"<p><b>Radio ON/OFF</b>" +
|
||||||
|
"<br>Shows whether the mote radio is on or off. Turned on radios are indicated with gray color." +
|
||||||
|
"<p><b>LEDs</b>" +
|
||||||
|
"<br>Shows LED state: red, green, and blue. (Assumes all mote types have exactly three LEDs.)" +
|
||||||
|
"<p><b>Watchpoints</b>" +
|
||||||
|
"<br>Shows triggered watchpoints, currently only supported by MSPSim-based motes. To add watchpoints, use the Msp Code Watcher plugin.";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ import javax.swing.AbstractAction;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JCheckBoxMenuItem;
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
@ -89,6 +88,7 @@ import org.jdom.Element;
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.GUI;
|
import se.sics.cooja.GUI;
|
||||||
import se.sics.cooja.GUI.MoteRelation;
|
import se.sics.cooja.GUI.MoteRelation;
|
||||||
|
import se.sics.cooja.HasQuickHelp;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteInterface;
|
import se.sics.cooja.MoteInterface;
|
||||||
import se.sics.cooja.PluginType;
|
import se.sics.cooja.PluginType;
|
||||||
|
@ -127,7 +127,7 @@ import se.sics.cooja.plugins.skins.UDGMVisualizerSkin;
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Simulation visualizer")
|
@ClassDescription("Simulation visualizer")
|
||||||
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
@PluginType(PluginType.SIM_STANDARD_PLUGIN)
|
||||||
public class Visualizer extends VisPlugin {
|
public class Visualizer extends VisPlugin implements HasQuickHelp {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static Logger logger = Logger.getLogger(Visualizer.class);
|
private static Logger logger = Logger.getLogger(Visualizer.class);
|
||||||
|
|
||||||
|
@ -1434,5 +1434,24 @@ public class Visualizer extends VisPlugin {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuickHelp() {
|
||||||
|
return
|
||||||
|
"<b>Visualizer</b> " +
|
||||||
|
"<p>The visualizer shows the positions of simulated motes as viewed from above (XY-plane). " +
|
||||||
|
"It is possible to zoom (CRTL+Mouse drag) and pan (Shift+Mouse drag) the current view. Motes can be moved by dragging them (ALT+Mouse drag). " +
|
||||||
|
"Mouse right-click a mote or unoccupied space for a popup menu with more options. " +
|
||||||
|
"<p>The visualizer supports \"visualizer skins\". " +
|
||||||
|
"Each skin provides some specific information, such as ongoing simulated radio traffic, or the IP addresses of motes. " +
|
||||||
|
"Multiple skins can be active at the same time. " +
|
||||||
|
"Click the upper \"Select visualizer skin\" button to select or deselect skins. " +
|
||||||
|
"<p><b>Useful skins</b> " +
|
||||||
|
"<br>Mote IDs: prints the unique mote IDs inside motes. " +
|
||||||
|
"<br>Log output: prints the last printf message above motes. " +
|
||||||
|
"<br>Radio traffic: displays inter-mote radio communication. " +
|
||||||
|
"<br>Radio environment (UDGM): enables configurating the UDGM radio medium. " +
|
||||||
|
"<p><b>Tip</b><br> " +
|
||||||
|
"Right-click visualizer to show the popup menu, and click \"Hide window decorations\".";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue