rewrote tools menu code to allow access to mote tools directly from the main menu
mote tools can still be started from the network visualizer
This commit is contained in:
parent
a523127b6f
commit
26d7a8b492
|
@ -39,6 +39,7 @@ import java.awt.Dimension;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.GraphicsDevice;
|
import java.awt.GraphicsDevice;
|
||||||
import java.awt.GraphicsEnvironment;
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.GridLayout;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
@ -296,12 +297,12 @@ public class GUI extends Observable {
|
||||||
|
|
||||||
protected GUIEventHandler guiEventHandler = new GUIEventHandler();
|
protected GUIEventHandler guiEventHandler = new GUIEventHandler();
|
||||||
|
|
||||||
private JMenu toolsMenu, menuMoteTypeClasses, menuMoteTypes;
|
private JMenu menuMoteTypeClasses, menuMoteTypes;
|
||||||
|
|
||||||
private JMenu menuOpenSimulation;
|
private JMenu menuOpenSimulation;
|
||||||
private boolean hasFileHistoryChanged;
|
private boolean hasFileHistoryChanged;
|
||||||
|
|
||||||
private Vector<Class<? extends Plugin>> menuMotePluginClasses;
|
private Vector<Class<? extends Plugin>> menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
||||||
|
|
||||||
private JDesktopPane myDesktopPane;
|
private JDesktopPane myDesktopPane;
|
||||||
|
|
||||||
|
@ -369,17 +370,6 @@ public class GUI extends Observable {
|
||||||
myGUI = this;
|
myGUI = this;
|
||||||
mySimulation = null;
|
mySimulation = null;
|
||||||
myDesktopPane = desktop;
|
myDesktopPane = desktop;
|
||||||
if (toolsMenu == null) {
|
|
||||||
toolsMenu = new JMenu("Tools");
|
|
||||||
toolsMenu.removeAll();
|
|
||||||
|
|
||||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
|
||||||
/*toolsMenu.addSeparator();
|
|
||||||
toolsMenu.addSeparator();*/
|
|
||||||
}
|
|
||||||
if (menuMotePluginClasses == null) {
|
|
||||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Help panel */
|
/* Help panel */
|
||||||
quickHelpTextPane = new JTextPane();
|
quickHelpTextPane = new JTextPane();
|
||||||
|
@ -703,7 +693,7 @@ public class GUI extends Observable {
|
||||||
JMenu fileMenu = new JMenu("File");
|
JMenu fileMenu = new JMenu("File");
|
||||||
JMenu simulationMenu = new JMenu("Simulation");
|
JMenu simulationMenu = new JMenu("Simulation");
|
||||||
JMenu motesMenu = new JMenu("Motes");
|
JMenu motesMenu = new JMenu("Motes");
|
||||||
/* toolsMenu = new JMenu("Tools"); */
|
final JMenu toolsMenu = new JMenu("Tools");
|
||||||
JMenu settingsMenu = new JMenu("Settings");
|
JMenu settingsMenu = new JMenu("Settings");
|
||||||
JMenu helpMenu = new JMenu("Help");
|
JMenu helpMenu = new JMenu("Help");
|
||||||
|
|
||||||
|
@ -931,56 +921,118 @@ public class GUI extends Observable {
|
||||||
|
|
||||||
motesMenu.add(new JMenuItem(removeAllMotesAction));
|
motesMenu.add(new JMenuItem(removeAllMotesAction));
|
||||||
|
|
||||||
// Tools menu
|
/* Tools menu */
|
||||||
toolsMenu.addMenuListener(new MenuListener() {
|
toolsMenu.addMenuListener(new MenuListener() {
|
||||||
public void menuSelected(MenuEvent e) {
|
private ActionListener menuItemListener = new ActionListener() {
|
||||||
for (Component menuComponent: toolsMenu.getMenuComponents()) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (!(menuComponent instanceof JMenuItem)) {
|
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||||
continue;
|
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||||
}
|
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
}
|
||||||
Class<? extends Plugin> pluginClass = (Class<? extends Plugin>) menuItem.getClientProperty("class");
|
};
|
||||||
int pluginType;
|
private JMenuItem createMenuItem(Class<? extends Plugin> newPluginClass, int pluginType) {
|
||||||
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
String description = getDescriptionOf(newPluginClass);
|
||||||
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
JMenuItem menuItem = new JMenuItem(description + "...");
|
||||||
} else {
|
menuItem.putClientProperty("class", newPluginClass);
|
||||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
menuItem.addActionListener(menuItemListener);
|
||||||
}
|
|
||||||
|
|
||||||
/* No simulation -> deactivate non-GUI plugins */
|
String tooltip = "<html><pre>";
|
||||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
menuItem.setEnabled(true);
|
tooltip += "Cooja plugin: ";
|
||||||
continue;
|
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
}
|
tooltip += "Simulation plugin: ";
|
||||||
/* Mote plugin -> not accessed from this menu */
|
|
||||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
|
||||||
/* Unknown */
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (getSimulation() == null) {
|
if (getSimulation() == null) {
|
||||||
menuItem.setEnabled(false);
|
menuItem.setEnabled(false);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||||
|
tooltip += "Mote plugin: ";
|
||||||
|
}
|
||||||
|
tooltip += description + " (" + newPluginClass.getName() + ")";
|
||||||
|
|
||||||
/* Check if simulation plugin depends on any particular radio medium */
|
/* Check if simulation plugin depends on any particular radio medium */
|
||||||
if (pluginClass.getAnnotation(SupportedArguments.class) != null) {
|
if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
menuItem.setEnabled(false);
|
if (newPluginClass.getAnnotation(SupportedArguments.class) != null) {
|
||||||
Class<? extends RadioMedium>[] radioMediums = pluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
boolean active = false;
|
||||||
|
Class<? extends RadioMedium>[] radioMediums = newPluginClass.getAnnotation(SupportedArguments.class).radioMediums();
|
||||||
for (Class<? extends Object> o: radioMediums) {
|
for (Class<? extends Object> o: radioMediums) {
|
||||||
if (o.isAssignableFrom(getSimulation().getRadioMedium().getClass())) {
|
if (o.isAssignableFrom(getSimulation().getRadioMedium().getClass())) {
|
||||||
menuItem.setEnabled(true);
|
active = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (!active) {
|
||||||
menuItem.setEnabled(true);
|
menuItem.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if plugin was imported by a extension directory */
|
||||||
|
File project =
|
||||||
|
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
||||||
|
if (project != null) {
|
||||||
|
tooltip += "\nLoaded by extension: " + project.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip += "</html>";
|
||||||
|
/*menuItem.setToolTipText(tooltip);*/
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void menuSelected(MenuEvent e) {
|
||||||
|
/* Populate tools menu */
|
||||||
|
toolsMenu.removeAll();
|
||||||
|
|
||||||
|
/* Cooja plugins */
|
||||||
|
boolean hasCoojaPlugins = false;
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.COOJA_PLUGIN && pluginType != PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||||
|
hasCoojaPlugins = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulation plugins */
|
||||||
|
boolean hasSimPlugins = false;
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
if (pluginClass.equals(SimControl.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
if (pluginClass.equals(SimInformation.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
if (pluginClass.equals(MoteTypeInformation.class)) {
|
||||||
|
continue; /* ignore */
|
||||||
|
}
|
||||||
|
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.SIM_PLUGIN && pluginType != PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCoojaPlugins) {
|
||||||
|
hasCoojaPlugins = false;
|
||||||
|
toolsMenu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsMenu.add(createMenuItem(pluginClass, pluginType));
|
||||||
|
hasSimPlugins = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Class<? extends Plugin> pluginClass: pluginClasses) {
|
||||||
|
int pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
|
if (pluginType != PluginType.MOTE_PLUGIN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSimPlugins) {
|
||||||
|
hasSimPlugins = false;
|
||||||
|
toolsMenu.addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
toolsMenu.add(createMotePluginsSubmenu(pluginClass));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void menuDeselected(MenuEvent e) {
|
public void menuDeselected(MenuEvent e) {
|
||||||
}
|
}
|
||||||
|
@ -1051,10 +1103,6 @@ public class GUI extends Observable {
|
||||||
menuItem.setEnabled(false);
|
menuItem.setEnabled(false);
|
||||||
helpMenu.add(menuItem);
|
helpMenu.add(menuItem);
|
||||||
|
|
||||||
// Mote plugins popup menu (not available via menu bar)
|
|
||||||
if (menuMotePluginClasses == null) {
|
|
||||||
menuMotePluginClasses = new Vector<Class<? extends Plugin>>();
|
|
||||||
}
|
|
||||||
return menuBar;
|
return menuBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,9 +1552,9 @@ public class GUI extends Observable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register plugins
|
// Register plugins
|
||||||
registerPlugin(SimControl.class, false); // Not in menu
|
registerPlugin(SimControl.class);
|
||||||
registerPlugin(SimInformation.class, false); // Not in menu
|
registerPlugin(SimInformation.class);
|
||||||
registerPlugin(MoteTypeInformation.class, false); // Not in menu
|
registerPlugin(MoteTypeInformation.class);
|
||||||
String[] pluginClassNames = projectConfig.getStringArrayValue(GUI.class,
|
String[] pluginClassNames = projectConfig.getStringArrayValue(GUI.class,
|
||||||
"PLUGINS");
|
"PLUGINS");
|
||||||
if (pluginClassNames != null) {
|
if (pluginClassNames != null) {
|
||||||
|
@ -1816,155 +1864,54 @@ public class GUI extends Observable {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a plugin to be included in the GUI. The plugin will be visible in
|
|
||||||
* the menubar.
|
|
||||||
*
|
|
||||||
* @param newPluginClass
|
|
||||||
* New plugin to register
|
|
||||||
* @return True if this plugin was registered ok, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean registerPlugin(Class<? extends Plugin> newPluginClass) {
|
|
||||||
return registerPlugin(newPluginClass, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister a plugin class. Removes any plugin menu items links as well.
|
* Unregister a plugin class. Removes any plugin menu items links as well.
|
||||||
*
|
*
|
||||||
* @param pluginClass Plugin class
|
* @param pluginClass Plugin class
|
||||||
*/
|
*/
|
||||||
public void unregisterPlugin(Class<? extends Plugin> pluginClass) {
|
public void unregisterPlugin(Class<? extends Plugin> pluginClass) {
|
||||||
/* Remove from menu */
|
|
||||||
for (Component menuComponent : toolsMenu.getMenuComponents()) {
|
|
||||||
if (!(menuComponent instanceof JMenuItem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
JMenuItem menuItem = (JMenuItem) menuComponent;
|
|
||||||
if (menuItem.getClientProperty("class").equals(pluginClass)) {
|
|
||||||
toolsMenu.remove(menuItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuMotePluginClasses.remove(pluginClass);
|
|
||||||
pluginClasses.remove(pluginClass);
|
pluginClasses.remove(pluginClass);
|
||||||
|
menuMotePluginClasses.remove(pluginClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a plugin to be included in the GUI.
|
* Register a plugin to be included in the GUI.
|
||||||
*
|
*
|
||||||
* @param newPluginClass
|
* @param pluginClass New plugin to register
|
||||||
* New plugin to register
|
|
||||||
* @param addToMenu
|
|
||||||
* Should this plugin be added to the dedicated plugins menubar?
|
|
||||||
* @return True if this plugin was registered ok, false otherwise
|
* @return True if this plugin was registered ok, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean registerPlugin(final Class<? extends Plugin> newPluginClass,
|
public boolean registerPlugin(final Class<? extends Plugin> pluginClass) {
|
||||||
boolean addToMenu) {
|
|
||||||
|
|
||||||
// Get description annotation (if any)
|
/* Check plugin type */
|
||||||
final String description = getDescriptionOf(newPluginClass);
|
|
||||||
|
|
||||||
// Get plugin type annotation (required)
|
|
||||||
final int pluginType;
|
final int pluginType;
|
||||||
if (newPluginClass.isAnnotationPresent(PluginType.class)) {
|
if (pluginClass.isAnnotationPresent(PluginType.class)) {
|
||||||
pluginType = newPluginClass.getAnnotation(PluginType.class).value();
|
pluginType = pluginClass.getAnnotation(PluginType.class).value();
|
||||||
} else {
|
} else {
|
||||||
pluginType = PluginType.UNDEFINED_PLUGIN;
|
logger.fatal("Could not register plugin, no plugin type found: " + pluginClass);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that plugin type is valid and constructor exists
|
/* Check plugin constructor */
|
||||||
try {
|
try {
|
||||||
if (pluginType == PluginType.MOTE_PLUGIN) {
|
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
||||||
newPluginClass.getConstructor(new Class[] { Mote.class,
|
pluginClass.getConstructor(new Class[] { GUI.class });
|
||||||
Simulation.class, GUI.class });
|
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
||||||
} else if (pluginType == PluginType.SIM_PLUGIN
|
pluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
||||||
|| pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
||||||
newPluginClass.getConstructor(new Class[] { Simulation.class, GUI.class });
|
pluginClass.getConstructor(new Class[] { Mote.class, Simulation.class, GUI.class });
|
||||||
} else if (pluginType == PluginType.COOJA_PLUGIN
|
menuMotePluginClasses.add(pluginClass);
|
||||||
|| pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
|
||||||
newPluginClass.getConstructor(new Class[] { GUI.class });
|
|
||||||
} else {
|
} else {
|
||||||
logger.fatal("Could not find valid plugin type annotation in class " + newPluginClass);
|
logger.fatal("Could not register plugin, bad plugin type: " + pluginType);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pluginClasses.add(pluginClass);
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
logger.fatal("No plugin class: " + newPluginClass + ": " + e.getMessage());
|
logger.fatal("No plugin class: " + pluginClass + ": " + e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
logger.fatal("No plugin class constructor: " + newPluginClass + ": " + e.getMessage());
|
logger.fatal("No plugin class constructor: " + pluginClass + ": " + e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addToMenu && toolsMenu != null) {
|
|
||||||
new RunnableInEDT<Boolean>() {
|
|
||||||
public Boolean work() {
|
|
||||||
// Create 'start plugin'-menu item
|
|
||||||
JMenuItem menuItem;
|
|
||||||
String tooltip = "<html><pre>";
|
|
||||||
|
|
||||||
/* Sort menu according to plugin type */
|
|
||||||
int itemIndex=0;
|
|
||||||
if (pluginType == PluginType.COOJA_PLUGIN || pluginType == PluginType.COOJA_STANDARD_PLUGIN) {
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tooltip += "Cooja plugin: " + newPluginClass.getName();
|
|
||||||
menuItem = new JMenuItem(description);
|
|
||||||
menuItem.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
tryStartPlugin(newPluginClass, myGUI, null, null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (pluginType == PluginType.SIM_PLUGIN || pluginType == PluginType.SIM_STANDARD_PLUGIN) {
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemIndex++;
|
|
||||||
for (; itemIndex < toolsMenu.getItemCount(); itemIndex++) {
|
|
||||||
if (toolsMenu.getItem(itemIndex) == null /* separator */) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tooltip += "Simulation plugin: " + newPluginClass.getName();
|
|
||||||
GUIAction guiAction = new StartPluginGUIAction(description);
|
|
||||||
menuItem = new JMenuItem(guiAction);
|
|
||||||
guiActions.add(guiAction);
|
|
||||||
} else if (pluginType == PluginType.MOTE_PLUGIN) {
|
|
||||||
// Disable previous menu item and add new item to mote plugins menu
|
|
||||||
menuItem = new JMenuItem(description);
|
|
||||||
menuItem.setEnabled(false);
|
|
||||||
tooltip += "Mote plugin: " + newPluginClass.getName();
|
|
||||||
tooltip += "\nStart mote plugins by right-clicking a mote in the simulation visualizer";
|
|
||||||
menuMotePluginClasses.add(newPluginClass);
|
|
||||||
itemIndex = toolsMenu.getItemCount();
|
|
||||||
} else {
|
|
||||||
logger.warn("Unknown plugin type: " + pluginType);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if plugin was imported by a extension directory */
|
|
||||||
File project =
|
|
||||||
getProjectConfig().getUserProjectDefining(GUI.class, "PLUGINS", newPluginClass.getName());
|
|
||||||
if (project != null) {
|
|
||||||
tooltip += "\nLoaded by extension: " + project.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip += "</html>";
|
|
||||||
/*menuItem.setToolTipText(tooltip); */
|
|
||||||
menuItem.putClientProperty("class", newPluginClass);
|
|
||||||
|
|
||||||
toolsMenu.add(menuItem, itemIndex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}.invokeAndWait();
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginClasses.add(newPluginClass);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,16 +1919,7 @@ public class GUI extends Observable {
|
||||||
* Unregister all plugin classes
|
* Unregister all plugin classes
|
||||||
*/
|
*/
|
||||||
public void unregisterPlugins() {
|
public void unregisterPlugins() {
|
||||||
if (toolsMenu != null) {
|
menuMotePluginClasses.clear();
|
||||||
toolsMenu.removeAll();
|
|
||||||
|
|
||||||
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
|
|
||||||
toolsMenu.addSeparator();
|
|
||||||
toolsMenu.addSeparator();
|
|
||||||
}
|
|
||||||
if (menuMotePluginClasses != null) {
|
|
||||||
menuMotePluginClasses.clear();
|
|
||||||
}
|
|
||||||
pluginClasses.clear();
|
pluginClasses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2016,6 +1954,107 @@ public class GUI extends Observable {
|
||||||
return startedPlugins.toArray(new Plugin[0]);
|
return startedPlugins.toArray(new Plugin[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isMotePluginCompatible(Class<? extends Plugin> motePluginClass, Mote mote) {
|
||||||
|
if (motePluginClass.getAnnotation(SupportedArguments.class) == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check mote interfaces */
|
||||||
|
boolean moteInterfacesOK = true;
|
||||||
|
Class<? extends MoteInterface>[] moteInterfaces =
|
||||||
|
motePluginClass.getAnnotation(SupportedArguments.class).moteInterfaces();
|
||||||
|
StringBuilder moteTypeInterfacesError = new StringBuilder();
|
||||||
|
moteTypeInterfacesError.append(
|
||||||
|
"The plugin:\n" +
|
||||||
|
getDescriptionOf(motePluginClass) +
|
||||||
|
"\nrequires the following mote interfaces:\n"
|
||||||
|
);
|
||||||
|
for (Class<? extends MoteInterface> requiredMoteInterface: moteInterfaces) {
|
||||||
|
moteTypeInterfacesError.append(getDescriptionOf(requiredMoteInterface) + "\n");
|
||||||
|
if (mote.getInterfaces().getInterfaceOfType(requiredMoteInterface) == null) {
|
||||||
|
moteInterfacesOK = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check mote type */
|
||||||
|
boolean moteTypeOK = false;
|
||||||
|
Class<? extends Mote>[] motes =
|
||||||
|
motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
||||||
|
StringBuilder moteTypeError = new StringBuilder();
|
||||||
|
moteTypeError.append(
|
||||||
|
"The plugin:\n" +
|
||||||
|
getDescriptionOf(motePluginClass) +
|
||||||
|
"\ndoes not support motes of type:\n" +
|
||||||
|
getDescriptionOf(mote) +
|
||||||
|
"\n\nIt only supports motes of types:\n"
|
||||||
|
);
|
||||||
|
for (Class<? extends Mote> supportedMote: motes) {
|
||||||
|
moteTypeError.append(getDescriptionOf(supportedMote) + "\n");
|
||||||
|
if (supportedMote.isAssignableFrom(mote.getClass())) {
|
||||||
|
moteTypeOK = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (!moteInterfacesOK) {
|
||||||
|
menuItem.setToolTipText(
|
||||||
|
"<html><pre>" + moteTypeInterfacesError + "</html>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!moteTypeOK) {
|
||||||
|
menuItem.setToolTipText(
|
||||||
|
"<html><pre>" + moteTypeError + "</html>"
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return moteInterfacesOK && moteTypeOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JMenu createMotePluginsSubmenu(Class<? extends Plugin> pluginClass) {
|
||||||
|
JMenu menu = new JMenu(getDescriptionOf(pluginClass));
|
||||||
|
if (getSimulation() == null || getSimulation().getMotesCount() == 0) {
|
||||||
|
menu.setEnabled(false);
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionListener menuItemListener = new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Object pluginClass = ((JMenuItem)e.getSource()).getClientProperty("class");
|
||||||
|
Object mote = ((JMenuItem)e.getSource()).getClientProperty("mote");
|
||||||
|
tryStartPlugin((Class<? extends Plugin>) pluginClass, myGUI, getSimulation(), (Mote)mote);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final int MAX_PER_ROW = 30;
|
||||||
|
final int MAX_COLUMNS = 5;
|
||||||
|
|
||||||
|
int added = 0;
|
||||||
|
for (Mote mote: getSimulation().getMotes()) {
|
||||||
|
if (!isMotePluginCompatible(pluginClass, mote)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JMenuItem menuItem = new JMenuItem(mote.toString() + "...");
|
||||||
|
menuItem.putClientProperty("class", pluginClass);
|
||||||
|
menuItem.putClientProperty("mote", mote);
|
||||||
|
menuItem.addActionListener(menuItemListener);
|
||||||
|
|
||||||
|
menu.add(menuItem);
|
||||||
|
added++;
|
||||||
|
|
||||||
|
if (added == MAX_PER_ROW) {
|
||||||
|
menu.getPopupMenu().setLayout(new GridLayout(MAX_PER_ROW, MAX_COLUMNS));
|
||||||
|
}
|
||||||
|
if (added >= MAX_PER_ROW*MAX_COLUMNS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (added == 0) {
|
||||||
|
menu.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a mote plugins submenu for given mote.
|
* Return a mote plugins submenu for given mote.
|
||||||
*
|
*
|
||||||
|
@ -2026,62 +2065,15 @@ public class GUI extends Observable {
|
||||||
JMenu menuMotePlugins = new JMenu("Mote tools for " + mote);
|
JMenu menuMotePlugins = new JMenu("Mote tools for " + mote);
|
||||||
|
|
||||||
for (Class<? extends Plugin> motePluginClass: menuMotePluginClasses) {
|
for (Class<? extends Plugin> motePluginClass: menuMotePluginClasses) {
|
||||||
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass));
|
if (!isMotePluginCompatible(motePluginClass, mote)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIAction guiAction = new StartPluginGUIAction(getDescriptionOf(motePluginClass) + "...");
|
||||||
JMenuItem menuItem = new JMenuItem(guiAction);
|
JMenuItem menuItem = new JMenuItem(guiAction);
|
||||||
menuItem.putClientProperty("class", motePluginClass);
|
menuItem.putClientProperty("class", motePluginClass);
|
||||||
menuItem.putClientProperty("mote", mote);
|
menuItem.putClientProperty("mote", mote);
|
||||||
|
|
||||||
/* Check mote plugin requirements */
|
|
||||||
boolean enableMenuItem = true;
|
|
||||||
if (motePluginClass.getAnnotation(SupportedArguments.class) != null) {
|
|
||||||
/* Check mote interfaces */
|
|
||||||
boolean moteInterfacesOK = true;
|
|
||||||
Class<? extends MoteInterface>[] moteInterfaces = motePluginClass.getAnnotation(SupportedArguments.class).moteInterfaces();
|
|
||||||
StringBuilder moteTypeInterfacesError = new StringBuilder();
|
|
||||||
moteTypeInterfacesError.append(
|
|
||||||
"The plugin:\n" +
|
|
||||||
getDescriptionOf(motePluginClass) +
|
|
||||||
"\nrequires the following mote interfaces:\n"
|
|
||||||
);
|
|
||||||
for (Class<? extends MoteInterface> requiredMoteInterface: moteInterfaces) {
|
|
||||||
moteTypeInterfacesError.append(getDescriptionOf(requiredMoteInterface) + "\n");
|
|
||||||
if (mote.getInterfaces().getInterfaceOfType(requiredMoteInterface) == null) {
|
|
||||||
moteInterfacesOK = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check mote type */
|
|
||||||
boolean moteTypeOK = false;
|
|
||||||
Class<? extends Mote>[] motes = motePluginClass.getAnnotation(SupportedArguments.class).motes();
|
|
||||||
StringBuilder moteTypeError = new StringBuilder();
|
|
||||||
moteTypeError.append(
|
|
||||||
"The plugin:\n" +
|
|
||||||
getDescriptionOf(motePluginClass) +
|
|
||||||
"\ndoes not support motes of type:\n" +
|
|
||||||
getDescriptionOf(mote) +
|
|
||||||
"\n\nIt only supports motes of types:\n"
|
|
||||||
);
|
|
||||||
for (Class<? extends Mote> supportedMote: motes) {
|
|
||||||
moteTypeError.append(getDescriptionOf(supportedMote) + "\n");
|
|
||||||
if (supportedMote.isAssignableFrom(mote.getClass())) {
|
|
||||||
moteTypeOK = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moteInterfacesOK) {
|
|
||||||
menuItem.setToolTipText(
|
|
||||||
"<html><pre>" + moteTypeInterfacesError + "</html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!moteTypeOK) {
|
|
||||||
menuItem.setToolTipText(
|
|
||||||
"<html><pre>" + moteTypeError + "</html>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
enableMenuItem = moteInterfacesOK && moteTypeOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuItem.setEnabled(enableMenuItem);
|
|
||||||
menuMotePlugins.add(menuItem);
|
menuMotePlugins.add(menuItem);
|
||||||
}
|
}
|
||||||
return menuMotePlugins;
|
return menuMotePlugins;
|
||||||
|
@ -4528,8 +4520,8 @@ public class GUI extends Observable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class StartPluginGUIAction extends GUIAction {
|
class StartPluginGUIAction extends GUIAction {
|
||||||
private static final long serialVersionUID = 7368495576372376196L;
|
private static final long serialVersionUID = 7368495576372376196L;
|
||||||
public StartPluginGUIAction(String name) {
|
public StartPluginGUIAction(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
public void actionPerformed(final ActionEvent e) {
|
public void actionPerformed(final ActionEvent e) {
|
||||||
|
@ -4546,6 +4538,7 @@ public class GUI extends Observable {
|
||||||
return getSimulation() != null;
|
return getSimulation() != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GUIAction removeAllMotesAction = new GUIAction("Remove all motes") {
|
GUIAction removeAllMotesAction = new GUIAction("Remove all motes") {
|
||||||
private static final long serialVersionUID = 4709776747913364419L;
|
private static final long serialVersionUID = 4709776747913364419L;
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
Loading…
Reference in a new issue