2006-08-21 12:11:16 +00:00
/ *
2007-01-10 14:57:42 +00:00
* Copyright ( c ) 2006 , Swedish Institute of Computer Science . All rights
* reserved .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* Redistribution and use in source and binary forms , with or without
2007-01-10 14:57:42 +00:00
* 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 .
2007-08-22 11:23:50 +00:00
*
2007-01-10 14:57:42 +00:00
* 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 .
2007-08-22 11:23:50 +00:00
*
2009-06-15 18:13:45 +00:00
* $Id : GUI . java , v 1 . 137 2009 / 06 / 15 18 : 13 : 45 fros4943 Exp $
2006-08-21 12:11:16 +00:00
* /
package se.sics.cooja ;
2008-12-08 10:26:21 +00:00
import java.awt.BorderLayout ;
import java.awt.Component ;
import java.awt.Container ;
import java.awt.Dialog ;
import java.awt.Dimension ;
import java.awt.Frame ;
import java.awt.GraphicsDevice ;
import java.awt.GraphicsEnvironment ;
import java.awt.Point ;
import java.awt.Rectangle ;
import java.awt.Window ;
2008-02-12 15:20:56 +00:00
import java.awt.Dialog.ModalityType ;
2008-12-08 10:26:21 +00:00
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListener ;
import java.awt.event.KeyEvent ;
import java.awt.event.WindowEvent ;
import java.awt.event.WindowListener ;
2007-01-09 10:27:53 +00:00
import java.beans.PropertyVetoException ;
2008-12-08 10:26:21 +00:00
import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileNotFoundException ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.InputStream ;
import java.io.PrintStream ;
import java.io.StringReader ;
2008-11-04 14:32:32 +00:00
import java.lang.reflect.InvocationTargetException ;
2006-08-21 12:11:16 +00:00
import java.net.URL ;
import java.net.URLClassLoader ;
2008-02-18 08:18:01 +00:00
import java.security.AccessControlException ;
2008-12-08 10:26:21 +00:00
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Enumeration ;
2007-01-09 10:27:53 +00:00
import java.util.List ;
2008-12-08 10:26:21 +00:00
import java.util.Observable ;
import java.util.Observer ;
import java.util.Properties ;
import java.util.Vector ;
2008-03-19 09:40:38 +00:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2008-12-08 10:26:21 +00:00
import javax.swing.AbstractAction ;
2009-03-21 14:24:55 +00:00
import javax.swing.Action ;
2008-12-08 10:26:21 +00:00
import javax.swing.BorderFactory ;
import javax.swing.Box ;
import javax.swing.InputMap ;
import javax.swing.JApplet ;
import javax.swing.JButton ;
import javax.swing.JComponent ;
import javax.swing.JDesktopPane ;
import javax.swing.JDialog ;
import javax.swing.JFileChooser ;
import javax.swing.JFrame ;
import javax.swing.JInternalFrame ;
import javax.swing.JLabel ;
import javax.swing.JMenu ;
import javax.swing.JMenuBar ;
import javax.swing.JMenuItem ;
import javax.swing.JOptionPane ;
import javax.swing.JPanel ;
import javax.swing.JProgressBar ;
import javax.swing.JScrollPane ;
import javax.swing.JSeparator ;
2009-03-21 14:24:55 +00:00
import javax.swing.JTabbedPane ;
2008-12-08 10:26:21 +00:00
import javax.swing.KeyStroke ;
import javax.swing.SwingUtilities ;
2009-04-20 14:11:01 +00:00
import javax.swing.ToolTipManager ;
2008-12-08 10:26:21 +00:00
import javax.swing.UIManager ;
2006-08-21 12:11:16 +00:00
import javax.swing.event.MenuEvent ;
import javax.swing.event.MenuListener ;
import javax.swing.filechooser.FileFilter ;
2008-12-08 10:26:21 +00:00
2008-04-02 16:41:46 +00:00
import org.apache.log4j.BasicConfigurator ;
2006-08-21 12:11:16 +00:00
import org.apache.log4j.Logger ;
import org.apache.log4j.xml.DOMConfigurator ;
2007-01-09 10:27:53 +00:00
import org.jdom.Document ;
import org.jdom.Element ;
import org.jdom.JDOMException ;
import org.jdom.input.SAXBuilder ;
import org.jdom.output.Format ;
import org.jdom.output.XMLOutputter ;
2006-08-21 12:11:16 +00:00
2007-03-26 16:30:28 +00:00
import se.sics.cooja.MoteType.MoteTypeCreationException ;
2008-12-17 11:02:05 +00:00
import se.sics.cooja.VisPlugin.PluginRequiresVisualizationException ;
2008-12-08 10:26:21 +00:00
import se.sics.cooja.contikimote.ContikiMoteType ;
import se.sics.cooja.dialogs.AddMoteDialog ;
2009-02-20 16:50:16 +00:00
import se.sics.cooja.dialogs.ConfigurationWizard ;
2008-12-08 10:26:21 +00:00
import se.sics.cooja.dialogs.CreateSimDialog ;
import se.sics.cooja.dialogs.ExternalToolsDialog ;
import se.sics.cooja.dialogs.MessageList ;
import se.sics.cooja.dialogs.ProjectDirectoriesDialog ;
2009-06-10 15:57:08 +00:00
import se.sics.cooja.plugins.MoteInterfaceViewer ;
2008-12-08 10:26:21 +00:00
import se.sics.cooja.plugins.MoteTypeInformation ;
2008-12-17 13:12:07 +00:00
import se.sics.cooja.plugins.ScriptRunner ;
2008-12-08 10:26:21 +00:00
import se.sics.cooja.plugins.SimControl ;
import se.sics.cooja.plugins.SimInformation ;
2006-08-21 12:11:16 +00:00
/ * *
2007-01-10 14:57:42 +00:00
* Main file of COOJA Simulator . Typically contains a visualizer for the
* simulator , but can also be started without visualizer .
2007-08-22 11:23:50 +00:00
*
2007-03-23 23:33:54 +00:00
* This class loads external Java classes ( in project directories ) , and handles the
2007-01-10 14:57:42 +00:00
* COOJA plugins as well as the configuration system . If provides a number of
* help methods for the rest of the COOJA system , and is the starting point for
* loading and saving simulation configs .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @author Fredrik Osterlind
* /
2008-04-22 13:04:43 +00:00
public class GUI extends Observable {
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
/ * *
* External tools default Win32 settings filename .
* /
public static final String EXTERNAL_TOOLS_WIN32_SETTINGS_FILENAME = " /external_tools_win32.config " ;
2007-09-30 12:02:33 +00:00
/ * *
* External tools default Mac OS X settings filename .
* /
public static final String EXTERNAL_TOOLS_MACOSX_SETTINGS_FILENAME = " /external_tools_macosx.config " ;
2006-08-21 12:11:16 +00:00
/ * *
* External tools default Linux / Unix settings filename .
* /
public static final String EXTERNAL_TOOLS_LINUX_SETTINGS_FILENAME = " /external_tools_linux.config " ;
2008-12-16 16:15:36 +00:00
/ * *
* External tools default Linux / Unix settings filename for 64 bit architectures .
* EXPERIMENTAL . Tested on Intel 64 - bit Gentoo Linux .
* /
public static final String EXTERNAL_TOOLS_LINUX_64_SETTINGS_FILENAME = " /external_tools_linux_64.config " ;
2006-08-21 12:11:16 +00:00
/ * *
* External tools user settings filename .
* /
2006-12-01 14:12:50 +00:00
public static final String EXTERNAL_TOOLS_USER_SETTINGS_FILENAME = " .cooja.user.properties " ;
2008-02-18 08:18:01 +00:00
public static File externalToolsUserSettingsFile ;
2007-08-22 11:23:50 +00:00
private static boolean externalToolsUserSettingsFileReadOnly = false ;
2006-08-21 12:11:16 +00:00
2007-04-03 16:21:12 +00:00
private static String specifiedContikiPath = null ;
2007-08-22 11:23:50 +00:00
2006-08-21 12:11:16 +00:00
/ * *
* Logger settings filename .
* /
public static final String LOG_CONFIG_FILE = " log4j_config.xml " ;
/ * *
2007-03-23 23:33:54 +00:00
* Default project configuration filename .
2006-08-21 12:11:16 +00:00
* /
2008-02-18 08:18:01 +00:00
public static String PROJECT_DEFAULT_CONFIG_FILENAME = null ;
2006-08-21 12:11:16 +00:00
/ * *
2007-03-23 23:33:54 +00:00
* User project configuration filename .
2006-08-21 12:11:16 +00:00
* /
2007-03-23 23:33:54 +00:00
public static final String PROJECT_CONFIG_FILENAME = " cooja.config " ;
2006-08-21 12:11:16 +00:00
/ * *
* File filter only showing saved simulations files ( * . csc ) .
* /
public static final FileFilter SAVED_SIMULATIONS_FILES = new FileFilter ( ) {
public boolean accept ( File file ) {
2007-08-22 11:23:50 +00:00
if ( file . isDirectory ( ) ) {
2006-08-21 12:11:16 +00:00
return true ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2007-08-22 11:23:50 +00:00
if ( file . getName ( ) . endsWith ( " .csc " ) ) {
2006-08-21 12:11:16 +00:00
return true ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
return false ;
}
public String getDescription ( ) {
return " COOJA Configuration files " ;
}
public String toString ( ) {
return " .csc " ;
}
} ;
2008-02-12 15:20:56 +00:00
private static JFrame frame = null ;
private static JApplet applet = null ;
2006-08-21 12:11:16 +00:00
private static final long serialVersionUID = 1L ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private static Logger logger = Logger . getLogger ( GUI . class ) ;
// External tools setting names
2007-03-22 16:41:50 +00:00
private static Properties defaultExternalToolsSettings ;
2006-08-21 12:11:16 +00:00
private static Properties currentExternalToolsSettings ;
2007-01-10 14:57:42 +00:00
private static final String externalToolsSettingNames [ ] = new String [ ] {
2009-05-28 12:55:14 +00:00
" PATH_CONTIKI " , " PATH_COOJA_CORE_RELATIVE " ,
" PATH_MAKE " ,
" PATH_SHELL " ,
" PATH_C_COMPILER " , " COMPILER_ARGS " ,
" PATH_LINKER " , " LINK_COMMAND_1 " , " LINK_COMMAND_2 " ,
" PATH_AR " , " AR_COMMAND_1 " , " AR_COMMAND_2 " ,
" PATH_OBJDUMP " , " OBJDUMP_ARGS " ,
" PATH_JAVAC " ,
" CONTIKI_STANDARD_PROCESSES " ,
" CONTIKI_MAIN_TEMPLATE_FILENAME " ,
" CMD_GREP_PROCESSES " , " REGEXP_PARSE_PROCESSES " ,
" CMD_GREP_INTERFACES " , " REGEXP_PARSE_INTERFACES " ,
" CMD_GREP_SENSORS " , " REGEXP_PARSE_SENSORS " ,
" DEFAULT_PROJECTDIRS " ,
" CORECOMM_TEMPLATE_FILENAME " ,
" MAPFILE_DATA_START " , " MAPFILE_DATA_SIZE " ,
" MAPFILE_BSS_START " , " MAPFILE_BSS_SIZE " ,
" MAPFILE_VAR_NAME " ,
" MAPFILE_VAR_ADDRESS_1 " , " MAPFILE_VAR_ADDRESS_2 " ,
" MAPFILE_VAR_SIZE_1 " , " MAPFILE_VAR_SIZE_2 " ,
" PARSE_WITH_COMMAND " ,
" PARSE_COMMAND " ,
" COMMAND_VAR_NAME_ADDRESS " ,
" COMMAND_DATA_START " , " COMMAND_DATA_END " ,
" COMMAND_BSS_START " , " COMMAND_BSS_END " ,
2007-09-10 13:25:36 +00:00
} ;
2006-08-21 12:11:16 +00:00
private static final int FRAME_NEW_OFFSET = 30 ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private static final int FRAME_STANDARD_WIDTH = 150 ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private static final int FRAME_STANDARD_HEIGHT = 300 ;
private GUI myGUI ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
private Simulation mySimulation ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
protected GUIEventHandler guiEventHandler = new GUIEventHandler ( ) ;
2006-08-21 12:11:16 +00:00
private JMenu menuPlugins , menuMoteTypeClasses , menuMoteTypes ;
2007-01-10 14:57:42 +00:00
2007-03-22 16:17:01 +00:00
private JMenu menuOpenSimulation , menuConfOpenSimulation ;
2009-05-27 23:23:41 +00:00
private boolean hasFileHistoryChanged ;
2007-03-22 13:59:33 +00:00
2007-03-22 11:14:27 +00:00
private Vector < Class < ? extends Plugin > > menuMotePluginClasses ;
2007-08-22 11:23:50 +00:00
2007-01-09 10:27:53 +00:00
private JDesktopPane myDesktopPane ;
private Vector < Plugin > startedPlugins = new Vector < Plugin > ( ) ;
2006-08-21 12:11:16 +00:00
2009-05-28 14:53:26 +00:00
private ArrayList < GUIAction > guiActions = new ArrayList < GUIAction > ( ) ;
2009-05-28 12:55:14 +00:00
2006-08-21 12:11:16 +00:00
// Platform configuration variables
2007-03-23 23:33:54 +00:00
// Maintained via method reparseProjectConfig()
private ProjectConfig projectConfig ;
2007-01-10 14:57:42 +00:00
2007-03-23 23:33:54 +00:00
private Vector < File > currentProjectDirs = new Vector < File > ( ) ;
2007-01-10 14:57:42 +00:00
2007-03-23 23:33:54 +00:00
private ClassLoader projectDirClassLoader ;
2006-08-21 12:11:16 +00:00
private Vector < Class < ? extends MoteType > > moteTypeClasses = new Vector < Class < ? extends MoteType > > ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
private Vector < Class < ? extends Plugin > > pluginClasses = new Vector < Class < ? extends Plugin > > ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
private Vector < Class < ? extends Plugin > > pluginClassesTemporary = new Vector < Class < ? extends Plugin > > ( ) ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private Vector < Class < ? extends RadioMedium > > radioMediumClasses = new Vector < Class < ? extends RadioMedium > > ( ) ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private Vector < Class < ? extends IPDistributor > > ipDistributorClasses = new Vector < Class < ? extends IPDistributor > > ( ) ;
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
private Vector < Class < ? extends Positioner > > positionerClasses = new Vector < Class < ? extends Positioner > > ( ) ;
2007-05-30 10:51:14 +00:00
private class HighlightObservable extends Observable {
2009-02-26 13:35:45 +00:00
private void setChangedAndNotify ( Mote mote ) {
2007-05-30 10:51:14 +00:00
setChanged ( ) ;
notifyObservers ( mote ) ;
}
}
private HighlightObservable moteHighlightObservable = new HighlightObservable ( ) ;
2009-02-26 13:35:45 +00:00
private class MoteRelationsObservable extends Observable {
private void setChangedAndNotify ( ) {
setChanged ( ) ;
notifyObservers ( ) ;
}
}
private MoteRelationsObservable moteRelationObservable = new MoteRelationsObservable ( ) ;
/ * *
* Mote relation ( directed ) .
* /
public static class MoteRelation {
public Mote source ;
public Mote dest ;
public MoteRelation ( Mote source , Mote dest ) {
this . source = source ;
this . dest = dest ;
}
}
private ArrayList < MoteRelation > moteRelations = new ArrayList < MoteRelation > ( ) ;
2006-08-21 12:11:16 +00:00
/ * *
* Creates a new COOJA Simulator GUI .
2007-08-22 11:23:50 +00:00
*
2007-03-24 00:42:51 +00:00
* @param desktop Desktop pane
2006-08-21 12:11:16 +00:00
* /
2007-05-28 09:01:49 +00:00
public GUI ( JDesktopPane desktop ) {
2006-08-21 12:11:16 +00:00
myGUI = this ;
2007-01-09 10:27:53 +00:00
mySimulation = null ;
myDesktopPane = desktop ;
2007-08-22 11:23:50 +00:00
if ( menuPlugins = = null ) {
2007-05-28 09:01:49 +00:00
menuPlugins = new JMenu ( " Plugins " ) ;
2009-02-18 17:25:14 +00:00
menuPlugins . removeAll ( ) ;
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
menuPlugins . addSeparator ( ) ;
menuPlugins . addSeparator ( ) ;
2007-08-22 11:23:50 +00:00
}
if ( menuMotePluginClasses = = null ) {
2007-05-28 09:01:49 +00:00
menuMotePluginClasses = new Vector < Class < ? extends Plugin > > ( ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2007-03-22 13:59:33 +00:00
// Load default and overwrite with user settings (if any)
loadExternalToolsDefaultSettings ( ) ;
loadExternalToolsUserSettings ( ) ;
2007-04-03 16:21:12 +00:00
if ( specifiedContikiPath ! = null ) {
setExternalToolsSetting ( " PATH_CONTIKI " , specifiedContikiPath ) ;
}
2007-08-22 11:23:50 +00:00
2008-11-04 14:32:32 +00:00
/* Debugging - Break on repaints outside EDT */
/ * RepaintManager . setCurrentManager ( new RepaintManager ( ) {
public void addDirtyRegion ( JComponent comp , int a , int b , int c , int d ) {
if ( ! java . awt . EventQueue . isDispatchThread ( ) ) {
throw new RuntimeException ( " Repainting outside EDT " ) ;
}
super . addDirtyRegion ( comp , a , b , c , d ) ;
}
} ) ; * /
2007-03-23 23:33:54 +00:00
// Register default project directories
2009-06-10 15:57:08 +00:00
String defaultProjectDirs = getExternalToolsSetting ( " DEFAULT_PROJECTDIRS " , null ) ;
if ( defaultProjectDirs ! = null & & defaultProjectDirs . length ( ) > 0 ) {
String [ ] arr = defaultProjectDirs . split ( " ; " ) ;
for ( String p : arr ) {
File projectDir = new File ( p ) ;
currentProjectDirs . add ( projectDir ) ;
2006-12-01 14:12:50 +00:00
}
2007-01-10 14:57:42 +00:00
2008-02-18 08:18:01 +00:00
// Load extendable parts (using current project config)
try {
reparseProjectConfig ( ) ;
} catch ( ParseProjectsException e ) {
2008-12-19 12:48:09 +00:00
if ( isVisualized ( ) ) {
2008-02-18 08:18:01 +00:00
JOptionPane . showMessageDialog ( GUI . getTopParentContainer ( ) ,
2009-06-10 15:57:08 +00:00
" Default projects could not load, reconfigure project directories: " +
2009-01-08 15:43:49 +00:00
" \ n \ tMenu->Settings->Manage project directories " +
" \ n \ nSee console for stack trace with more information. " ,
" Project loading error " , JOptionPane . ERROR_MESSAGE ) ;
2008-02-18 08:18:01 +00:00
}
2009-06-10 15:57:08 +00:00
logger . fatal ( " Error when loading projects " , e ) ;
2007-09-21 16:14:19 +00:00
}
}
2006-12-13 11:57:04 +00:00
2007-01-10 14:57:42 +00:00
// Start all standard GUI plugins
2008-12-16 15:10:49 +00:00
for ( Class < ? extends Plugin > pluginClass : pluginClasses ) {
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
2007-01-09 10:27:53 +00:00
if ( pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
2009-06-10 15:57:08 +00:00
tryStartPlugin ( pluginClass , this , null , null ) ;
2006-12-13 11:57:04 +00:00
}
}
2006-08-21 12:11:16 +00:00
}
2007-05-30 10:51:14 +00:00
/ * *
* Add mote highlight observer .
2007-08-22 11:23:50 +00:00
*
2008-02-12 15:31:22 +00:00
* @see # deleteMoteHighlightObserver ( Observer )
2007-05-30 10:51:14 +00:00
* @param newObserver
* New observer
* /
2008-02-12 15:31:22 +00:00
public void addMoteHighlightObserver ( Observer newObserver ) {
2007-05-30 10:51:14 +00:00
moteHighlightObservable . addObserver ( newObserver ) ;
}
/ * *
* Delete an mote highlight observer .
2007-08-22 11:23:50 +00:00
*
2008-02-12 15:31:22 +00:00
* @see # addMoteHighlightObserver ( Observer )
2007-05-30 10:51:14 +00:00
* @param observer
* Observer to delete
* /
2008-02-12 15:31:22 +00:00
public void deleteMoteHighlightObserver ( Observer observer ) {
2007-05-30 10:51:14 +00:00
moteHighlightObservable . deleteObserver ( observer ) ;
}
2007-08-22 11:23:50 +00:00
2007-01-09 10:27:53 +00:00
/ * *
* @return True if simulator is visualized
* /
2008-02-12 15:20:56 +00:00
public static boolean isVisualized ( ) {
return isVisualizedInFrame ( ) | | isVisualizedInApplet ( ) ;
}
public static Container getTopParentContainer ( ) {
if ( isVisualizedInFrame ( ) ) {
return frame ;
}
if ( isVisualizedInApplet ( ) ) {
/* Find parent frame for applet */
Container container = applet ;
while ( ( container = container . getParent ( ) ) ! = null ) {
if ( container instanceof Frame ) {
return container ;
}
if ( container instanceof Dialog ) {
return container ;
}
if ( container instanceof Window ) {
return container ;
}
}
logger . fatal ( " Returning null top owner container " ) ;
}
return null ;
}
public static boolean isVisualizedInFrame ( ) {
2007-01-09 10:27:53 +00:00
return frame ! = null ;
}
2007-08-22 11:23:50 +00:00
2008-04-03 13:59:37 +00:00
public static URL getAppletCodeBase ( ) {
return applet . getCodeBase ( ) ;
}
2008-02-12 15:20:56 +00:00
public static boolean isVisualizedInApplet ( ) {
return applet ! = null ;
}
2007-05-28 09:01:49 +00:00
/ * *
* Tries to create / remove simulator visualizer .
2007-08-22 11:23:50 +00:00
*
2007-05-28 09:01:49 +00:00
* @param visualized Visualized
* /
2008-02-12 15:20:56 +00:00
public void setVisualizedInFrame ( boolean visualized ) {
if ( visualized ) {
if ( ! isVisualizedInFrame ( ) ) {
configureFrame ( myGUI , false ) ;
}
2007-05-28 09:01:49 +00:00
} else {
2008-02-12 15:20:56 +00:00
if ( frame ! = null ) {
frame . setVisible ( false ) ;
frame . dispose ( ) ;
frame = null ;
}
2007-05-28 09:01:49 +00:00
}
}
2007-01-10 14:57:42 +00:00
2009-05-27 23:23:41 +00:00
public File getLastOpenedFile ( ) {
2007-03-22 13:59:33 +00:00
// Fetch current history
String [ ] historyArray = getExternalToolsSetting ( " SIMCFG_HISTORY " , " " ) . split ( " ; " ) ;
2009-05-27 23:23:41 +00:00
return historyArray . length > 0 ? new File ( historyArray [ 0 ] ) : null ;
}
2007-03-22 13:59:33 +00:00
2009-05-27 23:23:41 +00:00
public File [ ] getFileHistory ( ) {
// Fetch current history
String [ ] historyArray = getExternalToolsSetting ( " SIMCFG_HISTORY " , " " ) . split ( " ; " ) ;
File [ ] history = new File [ historyArray . length ] ;
for ( int i = 0 ; i < historyArray . length ; i + + ) {
history [ i ] = new File ( historyArray [ i ] ) ;
2007-03-22 13:59:33 +00:00
}
return history ;
}
2008-09-29 13:02:15 +00:00
public void addToFileHistory ( File file ) {
2007-03-22 13:59:33 +00:00
// Fetch current history
String [ ] history = getExternalToolsSetting ( " SIMCFG_HISTORY " , " " ) . split ( " ; " ) ;
2008-11-10 14:59:03 +00:00
String newFile = file . getAbsolutePath ( ) ;
if ( history . length > 0 & & history [ 0 ] . equals ( newFile ) ) {
// File already added
2007-03-22 13:59:33 +00:00
return ;
}
2008-11-10 14:59:03 +00:00
// Create new history
StringBuilder newHistory = new StringBuilder ( ) ;
newHistory . append ( newFile ) ;
for ( int i = 0 , count = 1 ; i < history . length & & count < 10 ; i + + ) {
String historyFile = history [ i ] ;
if ( newFile . equals ( historyFile ) | | historyFile . length ( ) = = 0 ) {
// File already added or empty file name
2007-08-22 11:23:50 +00:00
} else {
2008-11-10 14:59:03 +00:00
newHistory . append ( ';' ) . append ( historyFile ) ;
count + + ;
2007-08-22 11:23:50 +00:00
}
2007-03-22 13:59:33 +00:00
}
2008-11-10 14:59:03 +00:00
setExternalToolsSetting ( " SIMCFG_HISTORY " , newHistory . toString ( ) ) ;
2007-03-22 13:59:33 +00:00
saveExternalToolsUserSettings ( ) ;
2009-05-27 23:23:41 +00:00
hasFileHistoryChanged = true ;
2007-03-22 13:59:33 +00:00
}
2007-08-22 11:23:50 +00:00
2007-03-22 13:59:33 +00:00
private void updateOpenHistoryMenuItems ( ) {
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
return ;
}
2009-05-27 23:23:41 +00:00
if ( ! hasFileHistoryChanged ) {
// No need to update menu because file history has not changed
return ;
2007-03-22 13:59:33 +00:00
}
2009-05-27 23:23:41 +00:00
hasFileHistoryChanged = false ;
2007-03-22 13:59:33 +00:00
2009-05-27 23:23:41 +00:00
File [ ] openFilesHistory = getFileHistory ( ) ;
updateOpenHistoryMenuItems ( " confopen " , menuConfOpenSimulation , openFilesHistory ) ;
updateOpenHistoryMenuItems ( " open " , menuOpenSimulation , openFilesHistory ) ;
}
2007-08-22 11:23:50 +00:00
2009-05-27 23:23:41 +00:00
private void updateOpenHistoryMenuItems ( String type , JMenu menu , File [ ] openFilesHistory ) {
menu . removeAll ( ) ;
JMenuItem browseItem = new JMenuItem ( " Browse... " ) ;
browseItem . setActionCommand ( type + " sim " ) ;
2007-03-22 13:59:33 +00:00
browseItem . addActionListener ( guiEventHandler ) ;
2009-05-27 23:23:41 +00:00
menu . add ( browseItem ) ;
menu . add ( new JSeparator ( ) ) ;
2007-08-22 11:23:50 +00:00
2009-05-27 23:23:41 +00:00
String command = type + " last sim " ;
int index = 0 ;
JMenuItem lastItem ;
2007-03-22 13:59:33 +00:00
for ( File file : openFilesHistory ) {
2009-05-27 23:23:41 +00:00
if ( index < 10 ) {
char mnemonic = ( char ) ( '0' + ( + + index % 10 ) ) ;
lastItem = new JMenuItem ( mnemonic + " " + file . getName ( ) ) ;
lastItem . setMnemonic ( mnemonic ) ;
} else {
lastItem = new JMenuItem ( file . getName ( ) ) ;
}
lastItem . setActionCommand ( command ) ;
2007-03-22 13:59:33 +00:00
lastItem . putClientProperty ( " file " , file ) ;
lastItem . setToolTipText ( file . getAbsolutePath ( ) ) ;
lastItem . addActionListener ( guiEventHandler ) ;
2009-05-27 23:23:41 +00:00
menu . add ( lastItem ) ;
2007-03-22 13:59:33 +00:00
}
}
2009-05-28 12:59:02 +00:00
/ * *
* Enables / disables menues and menu items depending on whether a simulation is loaded etc .
* /
2009-05-28 12:55:14 +00:00
private void updateGUIComponentState ( ) {
2009-05-28 12:59:02 +00:00
if ( ! isVisualized ( ) ) {
return ;
}
/* Update action state */
2009-05-28 14:53:26 +00:00
for ( GUIAction a : guiActions ) {
a . setEnabled ( a . shouldBeEnabled ( ) ) ;
2009-05-28 12:55:14 +00:00
}
2009-05-28 12:59:02 +00:00
/* Mote and mote type menues */
2009-06-02 15:04:49 +00:00
if ( menuMoteTypeClasses ! = null ) {
menuMoteTypeClasses . setEnabled ( getSimulation ( ) ! = null ) ;
}
if ( menuMoteTypes ! = null ) {
menuMoteTypes . setEnabled ( getSimulation ( ) ! = null ) ;
}
2009-05-28 12:55:14 +00:00
}
2006-08-21 12:11:16 +00:00
private JMenuBar createMenuBar ( ) {
JMenuBar menuBar = new JMenuBar ( ) ;
JMenu menu ;
JMenuItem menuItem ;
2009-05-28 12:55:14 +00:00
/* Prepare GUI actions */
guiActions . add ( newSimulationAction ) ;
guiActions . add ( closeSimulationAction ) ;
guiActions . add ( reloadSimulationAction ) ;
guiActions . add ( reloadRandomSimulationAction ) ;
guiActions . add ( saveSimulationAction ) ;
guiActions . add ( closePluginsAction ) ;
guiActions . add ( exitCoojaAction ) ;
guiActions . add ( startStopSimulationAction ) ;
guiActions . add ( removeAllMotesAction ) ;
/* File menu */
2006-08-21 12:11:16 +00:00
menu = new JMenu ( " File " ) ;
2007-03-22 13:59:33 +00:00
menu . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
2009-05-28 12:55:14 +00:00
updateGUIComponentState ( ) ;
2007-03-22 13:59:33 +00:00
updateOpenHistoryMenuItems ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
menu . setMnemonic ( KeyEvent . VK_F ) ;
menuBar . add ( menu ) ;
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( newSimulationAction ) ) ;
2006-08-21 12:11:16 +00:00
2008-12-08 09:38:42 +00:00
menuItem = new JMenu ( " Reload simulation " ) ;
2009-05-28 12:55:14 +00:00
menuItem . add ( new JMenuItem ( reloadSimulationAction ) ) ;
menuItem . add ( new JMenuItem ( reloadRandomSimulationAction ) ) ;
2007-03-23 11:25:19 +00:00
menu . add ( menuItem ) ;
2007-08-22 11:23:50 +00:00
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( closeSimulationAction ) ) ;
2007-08-22 11:23:50 +00:00
2007-03-22 13:59:33 +00:00
menuOpenSimulation = new JMenu ( " Open simulation " ) ;
2007-03-22 20:38:38 +00:00
menuOpenSimulation . setMnemonic ( KeyEvent . VK_O ) ;
2007-03-22 13:59:33 +00:00
menu . add ( menuOpenSimulation ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
menuOpenSimulation . setEnabled ( false ) ;
menuOpenSimulation . setToolTipText ( " Not available in applet version " ) ;
}
2007-03-22 16:17:01 +00:00
menuConfOpenSimulation = new JMenu ( " Open & Reconfigure simulation " ) ;
2007-03-22 20:38:38 +00:00
menuConfOpenSimulation . setMnemonic ( KeyEvent . VK_R ) ;
2007-03-22 16:17:01 +00:00
menu . add ( menuConfOpenSimulation ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
menuConfOpenSimulation . setEnabled ( false ) ;
menuConfOpenSimulation . setToolTipText ( " Not available in applet version " ) ;
}
2009-05-27 23:23:41 +00:00
hasFileHistoryChanged = true ;
2007-01-09 10:27:53 +00:00
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( saveSimulationAction ) ) ;
2006-08-21 12:11:16 +00:00
menu . addSeparator ( ) ;
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( closePluginsAction ) ) ;
2007-01-09 10:27:53 +00:00
menu . addSeparator ( ) ;
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( exitCoojaAction ) ) ;
2006-08-21 12:11:16 +00:00
2009-05-28 12:55:14 +00:00
/* Simulation menu */
2006-08-21 12:11:16 +00:00
menu = new JMenu ( " Simulation " ) ;
2009-05-28 12:55:14 +00:00
menu . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
2009-03-21 16:45:42 +00:00
}
} ) ;
2009-05-28 12:55:14 +00:00
menu . setMnemonic ( KeyEvent . VK_S ) ;
menuBar . add ( menu ) ;
menu . add ( new JMenuItem ( startStopSimulationAction ) ) ;
2009-03-21 16:45:42 +00:00
2009-05-28 14:53:26 +00:00
GUIAction guiAction = new StartPluginGUIAction ( " Control panel " ) ;
menuItem = new JMenuItem ( guiAction ) ;
guiActions . add ( guiAction ) ;
2006-08-21 12:11:16 +00:00
menuItem . setMnemonic ( KeyEvent . VK_C ) ;
menuItem . putClientProperty ( " class " , SimControl . class ) ;
menu . add ( menuItem ) ;
2009-05-28 14:53:26 +00:00
guiAction = new StartPluginGUIAction ( " Information " ) ;
menuItem = new JMenuItem ( guiAction ) ;
guiActions . add ( guiAction ) ;
2006-08-21 12:11:16 +00:00
menuItem . setMnemonic ( KeyEvent . VK_I ) ;
menuItem . putClientProperty ( " class " , SimInformation . class ) ;
menu . add ( menuItem ) ;
// Mote type menu
menu = new JMenu ( " Mote Types " ) ;
2009-05-28 12:55:14 +00:00
menu . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
menu . setMnemonic ( KeyEvent . VK_T ) ;
menuBar . add ( menu ) ;
// Mote type classes sub menu
menuMoteTypeClasses = new JMenu ( " Create mote type " ) ;
menuMoteTypeClasses . setMnemonic ( KeyEvent . VK_C ) ;
menuMoteTypeClasses . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
// Clear menu
menuMoteTypeClasses . removeAll ( ) ;
// Recreate menu items
JMenuItem menuItem ;
for ( Class < ? extends MoteType > moteTypeClass : moteTypeClasses ) {
2008-02-07 10:30:19 +00:00
/* Sort mote types according to abstraction level */
String abstractionLevelDescription = GUI . getAbstractionLevelDescriptionOf ( moteTypeClass ) ;
if ( abstractionLevelDescription = = null ) {
abstractionLevelDescription = " [unknown cross-level] " ;
}
/* Check if abstraction description already exists */
JSeparator abstractionLevelSeparator = null ;
for ( Component component : menuMoteTypeClasses . getMenuComponents ( ) ) {
if ( component = = null | | ! ( component instanceof JSeparator ) ) {
continue ;
}
JSeparator existing = ( JSeparator ) component ;
if ( abstractionLevelDescription . equals ( existing . getToolTipText ( ) ) ) {
abstractionLevelSeparator = existing ;
break ;
}
}
if ( abstractionLevelSeparator = = null ) {
abstractionLevelSeparator = new JSeparator ( ) ;
abstractionLevelSeparator . setToolTipText ( abstractionLevelDescription ) ;
menuMoteTypeClasses . add ( abstractionLevelSeparator ) ;
}
2006-08-21 12:11:16 +00:00
String description = GUI . getDescriptionOf ( moteTypeClass ) ;
menuItem = new JMenuItem ( description ) ;
menuItem . setActionCommand ( " create mote type " ) ;
menuItem . putClientProperty ( " class " , moteTypeClass ) ;
2008-02-07 10:30:19 +00:00
menuItem . setToolTipText ( abstractionLevelDescription ) ;
2006-08-21 12:11:16 +00:00
menuItem . addActionListener ( guiEventHandler ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) & & moteTypeClass . equals ( ContikiMoteType . class ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2008-02-07 10:30:19 +00:00
/* Add new item directly after cross level separator */
for ( int i = 0 ; i < menuMoteTypeClasses . getMenuComponentCount ( ) ; i + + ) {
if ( menuMoteTypeClasses . getMenuComponent ( i ) = = abstractionLevelSeparator ) {
menuMoteTypeClasses . add ( menuItem , i + 1 ) ;
break ;
}
}
2006-08-21 12:11:16 +00:00
}
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void menuDeselected ( MenuEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
menu . add ( menuMoteTypeClasses ) ;
2009-05-28 14:53:26 +00:00
guiAction = new StartPluginGUIAction ( " Information " ) ;
menuItem = new JMenuItem ( guiAction ) ;
guiActions . add ( guiAction ) ;
2006-08-21 12:11:16 +00:00
menuItem . putClientProperty ( " class " , MoteTypeInformation . class ) ;
menu . add ( menuItem ) ;
// Mote menu
menu = new JMenu ( " Motes " ) ;
2009-05-28 12:55:14 +00:00
menu . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
menu . setMnemonic ( KeyEvent . VK_M ) ;
menuBar . add ( menu ) ;
// Mote types sub menu
menuMoteTypes = new JMenu ( " Add motes of type " ) ;
menuMoteTypes . setMnemonic ( KeyEvent . VK_A ) ;
menuMoteTypes . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
// Clear menu
menuMoteTypes . removeAll ( ) ;
2007-01-09 10:27:53 +00:00
if ( mySimulation = = null ) {
2006-08-21 12:11:16 +00:00
return ;
}
// Recreate menu items
JMenuItem menuItem ;
2007-01-09 10:27:53 +00:00
for ( MoteType moteType : mySimulation . getMoteTypes ( ) ) {
2006-08-21 12:11:16 +00:00
menuItem = new JMenuItem ( moteType . getDescription ( ) ) ;
menuItem . setActionCommand ( " add motes " ) ;
menuItem . setToolTipText ( getDescriptionOf ( moteType . getClass ( ) ) ) ;
menuItem . putClientProperty ( " motetype " , moteType ) ;
menuItem . addActionListener ( guiEventHandler ) ;
menuMoteTypes . add ( menuItem ) ;
}
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void menuDeselected ( MenuEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
menu . add ( menuMoteTypes ) ;
2009-05-28 12:55:14 +00:00
menu . add ( new JMenuItem ( removeAllMotesAction ) ) ;
2007-04-02 16:50:07 +00:00
2006-08-21 12:11:16 +00:00
// Plugins menu
2007-08-22 11:23:50 +00:00
if ( menuPlugins = = null ) {
2007-05-28 09:01:49 +00:00
menuPlugins = new JMenu ( " Plugins " ) ;
2009-02-18 17:25:14 +00:00
menuPlugins . removeAll ( ) ;
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
menuPlugins . addSeparator ( ) ;
menuPlugins . addSeparator ( ) ;
2007-08-22 11:23:50 +00:00
} else {
2007-05-28 09:01:49 +00:00
menuPlugins . setText ( " Plugins " ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
menuPlugins . setMnemonic ( KeyEvent . VK_P ) ;
menuBar . add ( menuPlugins ) ;
// Settings menu
menu = new JMenu ( " Settings " ) ;
2009-05-28 12:55:14 +00:00
menu . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
menuBar . add ( menu ) ;
menuItem = new JMenuItem ( " External tools paths " ) ;
menuItem . setActionCommand ( " edit paths " ) ;
menuItem . addActionListener ( guiEventHandler ) ;
menu . add ( menuItem ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2006-08-21 12:11:16 +00:00
2007-03-23 23:33:54 +00:00
menuItem = new JMenuItem ( " Manage project directories " ) ;
menuItem . setActionCommand ( " manage projects " ) ;
2006-08-21 12:11:16 +00:00
menuItem . addActionListener ( guiEventHandler ) ;
menu . add ( menuItem ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2006-08-21 12:11:16 +00:00
2009-02-20 16:50:16 +00:00
menuItem = new JMenuItem ( " Compiler configuration wizard " ) ;
menuItem . setActionCommand ( " configuration wizard " ) ;
menuItem . addActionListener ( guiEventHandler ) ;
menu . add ( menuItem ) ;
if ( isVisualizedInApplet ( ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2007-05-18 14:08:19 +00:00
menu . addSeparator ( ) ;
menuItem = new JMenuItem ( " Java version: "
+ System . getProperty ( " java.version " ) + " ( "
+ System . getProperty ( " java.vendor " ) + " ) " ) ;
menuItem . setEnabled ( false ) ;
menu . add ( menuItem ) ;
2006-08-21 12:11:16 +00:00
// Mote plugins popup menu (not available via menu bar)
2007-08-22 11:23:50 +00:00
if ( menuMotePluginClasses = = null ) {
2007-05-28 09:01:49 +00:00
menuMotePluginClasses = new Vector < Class < ? extends Plugin > > ( ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
return menuBar ;
}
2007-08-22 11:23:50 +00:00
2007-05-28 09:01:49 +00:00
private static void configureFrame ( final GUI gui , boolean createSimDialog ) {
2006-08-21 12:11:16 +00:00
// Create and set up the window.
2009-01-08 15:43:49 +00:00
if ( frame = = null ) {
frame = new JFrame ( " COOJA Simulator " ) ;
}
2006-08-21 12:11:16 +00:00
frame . setDefaultCloseOperation ( JFrame . DO_NOTHING_ON_CLOSE ) ;
2007-05-28 09:01:49 +00:00
// Add menu bar
frame . setJMenuBar ( gui . createMenuBar ( ) ) ;
2007-01-09 10:27:53 +00:00
JComponent newContentPane = gui . getDesktopPane ( ) ;
2006-08-21 12:11:16 +00:00
newContentPane . setOpaque ( true ) ;
frame . setContentPane ( newContentPane ) ;
2007-08-22 11:23:50 +00:00
2007-01-09 10:27:53 +00:00
frame . setSize ( 700 , 700 ) ;
2007-02-01 16:00:40 +00:00
frame . setLocationRelativeTo ( null ) ;
2007-01-09 10:27:53 +00:00
frame . addWindowListener ( gui . guiEventHandler ) ;
2008-10-29 13:31:02 +00:00
/* Restore frame size and position */
int framePosX = Integer . parseInt ( getExternalToolsSetting ( " FRAME_POS_X " , " 0 " ) ) ;
int framePosY = Integer . parseInt ( getExternalToolsSetting ( " FRAME_POS_Y " , " 0 " ) ) ;
int frameWidth = Integer . parseInt ( getExternalToolsSetting ( " FRAME_WIDTH " , " 0 " ) ) ;
int frameHeight = Integer . parseInt ( getExternalToolsSetting ( " FRAME_HEIGHT " , " 0 " ) ) ;
String frameScreen = getExternalToolsSetting ( " FRAME_SCREEN " , " " ) ;
/* Restore position to the same graphics device */
GraphicsDevice device = null ;
GraphicsDevice all [ ] = GraphicsEnvironment . getLocalGraphicsEnvironment ( ) . getScreenDevices ( ) ;
for ( GraphicsDevice gd : all ) {
if ( gd . getIDstring ( ) . equals ( frameScreen ) ) {
device = gd ;
}
}
/* Check if frame should be maximized */
if ( device ! = null ) {
if ( frameWidth = = Integer . MAX_VALUE & & frameHeight = = Integer . MAX_VALUE ) {
frame . setLocation ( device . getDefaultConfiguration ( ) . getBounds ( ) . getLocation ( ) ) ;
2008-02-12 15:20:56 +00:00
frame . setExtendedState ( JFrame . MAXIMIZED_BOTH ) ;
2008-10-29 13:31:02 +00:00
} else if ( frameWidth > 0 & & frameHeight > 0 ) {
2008-12-16 15:10:49 +00:00
/* Sanity-check: will Cooja be visible on screen? */
boolean intersects =
device . getDefaultConfiguration ( ) . getBounds ( ) . intersects (
new Rectangle ( framePosX , framePosY , frameWidth , frameHeight ) ) ;
if ( intersects ) {
frame . setLocation ( framePosX , framePosY ) ;
frame . setSize ( frameWidth , frameHeight ) ;
}
2007-03-22 23:01:11 +00:00
}
}
2006-08-21 12:11:16 +00:00
frame . setVisible ( true ) ;
2007-05-28 09:01:49 +00:00
if ( createSimDialog ) {
SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
gui . doCreateSimulation ( true ) ;
}
} ) ;
}
2006-08-21 12:11:16 +00:00
}
2008-02-12 15:20:56 +00:00
private static void configureApplet ( final GUI gui , boolean createSimDialog ) {
applet = CoojaApplet . applet ;
// Add menu bar
JMenuBar menuBar = gui . createMenuBar ( ) ;
applet . setJMenuBar ( menuBar ) ;
JComponent newContentPane = gui . getDesktopPane ( ) ;
newContentPane . setOpaque ( true ) ;
applet . setContentPane ( newContentPane ) ;
applet . setSize ( 700 , 700 ) ;
if ( createSimDialog ) {
SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
gui . doCreateSimulation ( true ) ;
}
} ) ;
}
}
2007-01-09 10:27:53 +00:00
/ * *
* @return Current desktop pane ( simulator visualizer )
* /
public JDesktopPane getDesktopPane ( ) {
return myDesktopPane ;
}
2008-10-29 10:39:04 +00:00
private static void setLookAndFeel ( ) {
2008-11-21 13:09:53 +00:00
JFrame . setDefaultLookAndFeelDecorated ( true ) ;
JDialog . setDefaultLookAndFeelDecorated ( true ) ;
2009-04-20 14:11:01 +00:00
ToolTipManager . sharedInstance ( ) . setDismissDelay ( 60000 ) ;
2008-11-21 13:09:53 +00:00
/* Nimbus */
2008-10-29 10:39:04 +00:00
try {
2009-02-08 18:33:05 +00:00
String osName = System . getProperty ( " os.name " ) . toLowerCase ( ) ;
if ( osName . startsWith ( " linux " ) ) {
UIManager . setLookAndFeel ( UIManager . getCrossPlatformLookAndFeelClassName ( ) ) ;
} else {
UIManager . setLookAndFeel ( " com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel " ) ;
}
2008-11-21 13:09:53 +00:00
return ;
} catch ( Exception e ) {
2008-10-29 10:39:04 +00:00
}
2008-11-21 13:09:53 +00:00
/* System */
try {
UIManager . setLookAndFeel ( UIManager . getSystemLookAndFeelClassName ( ) ) ;
return ;
} catch ( Exception e ) {
}
2008-10-29 10:39:04 +00:00
}
2009-06-09 09:47:04 +00:00
private static Simulation quickStartSimulationConfig ( File config , boolean vis ) {
2009-03-12 15:10:00 +00:00
logger . info ( " > Starting COOJA " ) ;
JDesktopPane desktop = new JDesktopPane ( ) ;
desktop . setDragMode ( JDesktopPane . OUTLINE_DRAG_MODE ) ;
2009-06-09 09:47:04 +00:00
if ( vis ) {
frame = new JFrame ( " COOJA Simulator " ) ;
}
2009-03-12 15:10:00 +00:00
GUI gui = new GUI ( desktop ) ;
2009-06-09 09:47:04 +00:00
if ( vis ) {
configureFrame ( gui , false ) ;
}
2009-03-12 15:10:00 +00:00
2009-06-09 09:47:04 +00:00
if ( vis ) {
gui . doLoadConfig ( false , true , config ) ;
return gui . getSimulation ( ) ;
} else {
try {
Simulation newSim = gui . loadSimulationConfig ( config , true ) ;
if ( newSim = = null ) {
return null ;
}
gui . setSimulation ( newSim , false ) ;
return newSim ;
} catch ( Exception e ) {
logger . fatal ( " Exception when loading simulation: " , e ) ;
return null ;
}
}
2009-03-12 15:10:00 +00:00
}
2006-09-06 10:05:22 +00:00
/ * *
2009-03-11 07:45:54 +00:00
* Allows user to create a simulation with a single mote type .
2007-08-22 11:23:50 +00:00
*
2009-03-11 07:45:54 +00:00
* @param source Contiki application file name
* @return True if simulation was created
* /
private static boolean quickStartSimulation ( String source ) {
logger . info ( " > Starting COOJA " ) ;
2007-01-09 10:27:53 +00:00
JDesktopPane desktop = new JDesktopPane ( ) ;
desktop . setDragMode ( JDesktopPane . OUTLINE_DRAG_MODE ) ;
2009-03-11 07:45:54 +00:00
frame = new JFrame ( " COOJA Simulator " ) ;
GUI gui = new GUI ( desktop ) ;
configureFrame ( gui , false ) ;
2006-09-06 10:05:22 +00:00
2009-03-11 07:45:54 +00:00
logger . info ( " > Creating simulation " ) ;
Simulation simulation = new Simulation ( gui ) ;
simulation . setTitle ( " Quickstarted simulation: " + source ) ;
boolean simOK = CreateSimDialog . showDialog ( GUI . getTopParentContainer ( ) , simulation ) ;
if ( ! simOK ) {
logger . fatal ( " No simulation, aborting quickstart " ) ;
System . exit ( 1 ) ;
2006-09-06 10:05:22 +00:00
}
2009-06-09 09:47:04 +00:00
gui . setSimulation ( simulation , true ) ;
2006-09-06 10:05:22 +00:00
logger . info ( " > Creating mote type " ) ;
2009-03-11 07:45:54 +00:00
ContikiMoteType moteType = new ContikiMoteType ( ) ;
moteType . setContikiSourceFile ( new File ( source ) ) ;
moteType . setDescription ( " Contiki Mote Type ( " + source + " ) " ) ;
2006-09-06 10:05:22 +00:00
try {
2009-03-13 14:33:48 +00:00
boolean compileOK = moteType . configureAndInit ( GUI . getTopParentContainer ( ) , simulation , true ) ;
if ( ! compileOK ) {
logger . fatal ( " Mote type initialization failed, aborting quickstart " ) ;
return false ;
}
} catch ( MoteTypeCreationException e1 ) {
2009-03-11 07:45:54 +00:00
logger . fatal ( " Mote type initialization failed, aborting quickstart " ) ;
2006-09-06 10:05:22 +00:00
return false ;
}
simulation . addMoteType ( moteType ) ;
2009-03-11 07:45:54 +00:00
logger . info ( " > Adding motes " ) ;
gui . doAddMotes ( moteType ) ;
2006-09-06 10:05:22 +00:00
return true ;
}
2007-01-10 14:57:42 +00:00
2007-03-23 23:33:54 +00:00
//// PROJECT CONFIG AND EXTENDABLE PARTS METHODS ////
2006-08-21 12:11:16 +00:00
/ * *
* Register new mote type class .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param moteTypeClass
* Class to register
* /
public void registerMoteType ( Class < ? extends MoteType > moteTypeClass ) {
moteTypeClasses . add ( moteTypeClass ) ;
}
/ * *
* Unregister all mote type classes .
* /
public void unregisterMoteTypes ( ) {
moteTypeClasses . clear ( ) ;
}
/ * *
* @return All registered mote type classes
* /
public Vector < Class < ? extends MoteType > > getRegisteredMoteTypes ( ) {
return moteTypeClasses ;
}
/ * *
* Register new IP distributor class
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param ipDistributorClass
* Class to register
* @return True if class was registered
* /
public boolean registerIPDistributor (
Class < ? extends IPDistributor > ipDistributorClass ) {
// Check that vector constructor exists
try {
2007-01-10 14:57:42 +00:00
ipDistributorClass . getConstructor ( new Class [ ] { Vector . class } ) ;
2006-08-21 12:11:16 +00:00
} catch ( Exception e ) {
logger . fatal ( " No vector constructor found of IP distributor: "
+ ipDistributorClass ) ;
return false ;
}
ipDistributorClasses . add ( ipDistributorClass ) ;
return true ;
}
/ * *
* Unregister all IP distributors .
* /
public void unregisterIPDistributors ( ) {
ipDistributorClasses . clear ( ) ;
}
/ * *
* @return All registered IP distributors
* /
public Vector < Class < ? extends IPDistributor > > getRegisteredIPDistributors ( ) {
return ipDistributorClasses ;
}
/ * *
* Register new positioner class .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param positionerClass
* Class to register
* @return True if class was registered
* /
public boolean registerPositioner ( Class < ? extends Positioner > positionerClass ) {
// Check that interval constructor exists
try {
positionerClass
2009-05-28 12:55:14 +00:00
. getConstructor ( new Class [ ] { int . class , double . class , double . class ,
double . class , double . class , double . class , double . class } ) ;
2006-08-21 12:11:16 +00:00
} catch ( Exception e ) {
logger . fatal ( " No interval constructor found of positioner: "
+ positionerClass ) ;
return false ;
}
positionerClasses . add ( positionerClass ) ;
return true ;
}
/ * *
* Unregister all positioner classes .
* /
public void unregisterPositioners ( ) {
positionerClasses . clear ( ) ;
}
/ * *
* @return All registered positioner classes
* /
public Vector < Class < ? extends Positioner > > getRegisteredPositioners ( ) {
return positionerClasses ;
}
/ * *
* Register new radio medium class .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param radioMediumClass
* Class to register
* @return True if class was registered
* /
public boolean registerRadioMedium (
Class < ? extends RadioMedium > radioMediumClass ) {
2007-01-09 10:27:53 +00:00
// Check that simulation constructor exists
try {
2007-01-10 14:57:42 +00:00
radioMediumClass . getConstructor ( new Class [ ] { Simulation . class } ) ;
2007-01-09 10:27:53 +00:00
} catch ( Exception e ) {
logger . fatal ( " No simulation constructor found of radio medium: "
+ radioMediumClass ) ;
return false ;
}
2006-08-21 12:11:16 +00:00
radioMediumClasses . add ( radioMediumClass ) ;
return true ;
}
/ * *
* Unregister all radio medium classes .
* /
public void unregisterRadioMediums ( ) {
radioMediumClasses . clear ( ) ;
}
/ * *
* @return All registered radio medium classes
* /
public Vector < Class < ? extends RadioMedium > > getRegisteredRadioMediums ( ) {
return radioMediumClasses ;
}
/ * *
2007-03-23 23:33:54 +00:00
* Builds new project configuration using current project directories settings .
2006-08-21 12:11:16 +00:00
* Reregisters mote types , plugins , IP distributors , positioners and radio
* mediums . This method may still return true even if all classes could not be
2007-03-23 23:33:54 +00:00
* registered , but always returns false if all project directory configuration
2006-08-21 12:11:16 +00:00
* files were not parsed correctly .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* Any registered temporary plugins will be saved and reregistered .
* /
2008-02-12 15:31:22 +00:00
public void reparseProjectConfig ( ) throws ParseProjectsException {
2008-02-18 08:18:01 +00:00
if ( PROJECT_DEFAULT_CONFIG_FILENAME = = null ) {
if ( isVisualizedInApplet ( ) ) {
PROJECT_DEFAULT_CONFIG_FILENAME = " /cooja_applet.config " ;
} else {
PROJECT_DEFAULT_CONFIG_FILENAME = " /cooja_default.config " ;
}
}
2006-08-21 12:11:16 +00:00
// Backup temporary plugins
2009-06-10 15:57:08 +00:00
Vector < Class < ? extends Plugin > > oldTempPlugins =
( Vector < Class < ? extends Plugin > > ) pluginClassesTemporary . clone ( ) ;
2006-08-21 12:11:16 +00:00
// Reset current configuration
unregisterMoteTypes ( ) ;
unregisterPlugins ( ) ;
unregisterIPDistributors ( ) ;
unregisterPositioners ( ) ;
unregisterRadioMediums ( ) ;
try {
2006-08-22 15:28:17 +00:00
// Read default configuration
2007-03-23 23:33:54 +00:00
projectConfig = new ProjectConfig ( true ) ;
2006-08-22 15:28:17 +00:00
} catch ( FileNotFoundException e ) {
2007-03-23 23:33:54 +00:00
logger . fatal ( " Could not find default project config file: "
+ PROJECT_DEFAULT_CONFIG_FILENAME ) ;
2007-09-21 16:14:19 +00:00
throw ( ParseProjectsException ) new ParseProjectsException (
" Could not find default project config file: "
+ PROJECT_DEFAULT_CONFIG_FILENAME ) . initCause ( e ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException e ) {
2007-03-23 23:33:54 +00:00
logger . fatal ( " Error when reading default project config file: "
+ PROJECT_DEFAULT_CONFIG_FILENAME ) ;
2007-09-21 16:14:19 +00:00
throw ( ParseProjectsException ) new ParseProjectsException (
" Error when reading default project config file: "
+ PROJECT_DEFAULT_CONFIG_FILENAME ) . initCause ( e ) ;
2006-08-21 12:11:16 +00:00
}
2008-02-18 08:18:01 +00:00
if ( ! isVisualizedInApplet ( ) ) {
// Append project directory configurations
for ( File projectDir : currentProjectDirs ) {
try {
// Append config to general config
projectConfig . appendProjectDir ( projectDir ) ;
} catch ( FileNotFoundException e ) {
logger . fatal ( " Could not find project config file: " + projectDir ) ;
throw ( ParseProjectsException ) new ParseProjectsException (
" Could not find project config file: " + projectDir ) . initCause ( e ) ;
} catch ( IOException e ) {
logger . fatal ( " Error when reading project config file: " + projectDir ) ;
throw ( ParseProjectsException ) new ParseProjectsException (
" Error when reading project config file: " + projectDir ) . initCause ( e ) ;
}
}
2006-08-21 12:11:16 +00:00
2008-02-18 08:18:01 +00:00
// Create class loader
2006-08-21 12:11:16 +00:00
try {
2008-02-18 08:18:01 +00:00
projectDirClassLoader = createClassLoader ( currentProjectDirs ) ;
} catch ( ClassLoaderCreationException e ) {
2007-09-21 16:14:19 +00:00
throw ( ParseProjectsException ) new ParseProjectsException (
2008-02-18 08:18:01 +00:00
" Error when creating class loader " ) . initCause ( e ) ;
2006-08-21 12:11:16 +00:00
}
2008-02-18 08:18:01 +00:00
} else {
projectDirClassLoader = null ;
2006-08-21 12:11:16 +00:00
}
// Register mote types
2007-03-23 23:33:54 +00:00
String [ ] moteTypeClassNames = projectConfig . getStringArrayValue ( GUI . class ,
2009-05-28 12:55:14 +00:00
" MOTETYPES " ) ;
2006-08-21 12:11:16 +00:00
if ( moteTypeClassNames ! = null ) {
for ( String moteTypeClassName : moteTypeClassNames ) {
Class < ? extends MoteType > moteTypeClass = tryLoadClass ( this ,
MoteType . class , moteTypeClassName ) ;
if ( moteTypeClass ! = null ) {
registerMoteType ( moteTypeClass ) ;
// logger.info("Loaded mote type class: " + moteTypeClassName);
} else {
logger . warn ( " Could not load mote type class: " + moteTypeClassName ) ;
}
}
}
// Register plugins
registerPlugin ( SimControl . class , false ) ; // Not in menu
registerPlugin ( SimInformation . class , false ) ; // Not in menu
registerPlugin ( MoteTypeInformation . class , false ) ; // Not in menu
2007-03-23 23:33:54 +00:00
String [ ] pluginClassNames = projectConfig . getStringArrayValue ( GUI . class ,
2009-05-28 12:55:14 +00:00
" PLUGINS " ) ;
2006-08-21 12:11:16 +00:00
if ( pluginClassNames ! = null ) {
for ( String pluginClassName : pluginClassNames ) {
2007-01-10 14:57:42 +00:00
Class < ? extends Plugin > pluginClass = tryLoadClass ( this , Plugin . class ,
pluginClassName ) ;
2006-08-21 12:11:16 +00:00
if ( pluginClass ! = null ) {
registerPlugin ( pluginClass ) ;
// logger.info("Loaded plugin class: " + pluginClassName);
} else {
logger . warn ( " Could not load plugin class: " + pluginClassName ) ;
}
}
}
// Reregister temporary plugins again
if ( oldTempPlugins ! = null ) {
2007-01-09 10:27:53 +00:00
for ( Class < ? extends Plugin > pluginClass : oldTempPlugins ) {
2006-08-21 12:11:16 +00:00
if ( registerTemporaryPlugin ( pluginClass ) ) {
// logger.info("Reregistered temporary plugin class: " +
// getDescriptionOf(pluginClass));
2007-08-22 11:23:50 +00:00
} else {
2006-08-21 12:11:16 +00:00
logger . warn ( " Could not reregister temporary plugin class: "
+ getDescriptionOf ( pluginClass ) ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
}
// Register IP distributors
2007-03-23 23:33:54 +00:00
String [ ] ipDistClassNames = projectConfig . getStringArrayValue ( GUI . class ,
2009-05-28 12:55:14 +00:00
" IP_DISTRIBUTORS " ) ;
2006-08-21 12:11:16 +00:00
if ( ipDistClassNames ! = null ) {
for ( String ipDistClassName : ipDistClassNames ) {
Class < ? extends IPDistributor > ipDistClass = tryLoadClass ( this ,
IPDistributor . class , ipDistClassName ) ;
if ( ipDistClass ! = null ) {
registerIPDistributor ( ipDistClass ) ;
// logger.info("Loaded IP distributor class: " + ipDistClassName);
} else {
logger
2009-05-28 12:55:14 +00:00
. warn ( " Could not load IP distributor class: " + ipDistClassName ) ;
2006-08-21 12:11:16 +00:00
}
}
}
// Register positioners
2007-03-23 23:33:54 +00:00
String [ ] positionerClassNames = projectConfig . getStringArrayValue (
2006-08-21 12:11:16 +00:00
GUI . class , " POSITIONERS " ) ;
if ( positionerClassNames ! = null ) {
for ( String positionerClassName : positionerClassNames ) {
Class < ? extends Positioner > positionerClass = tryLoadClass ( this ,
Positioner . class , positionerClassName ) ;
if ( positionerClass ! = null ) {
registerPositioner ( positionerClass ) ;
// logger.info("Loaded positioner class: " + positionerClassName);
} else {
logger
2009-05-28 12:55:14 +00:00
. warn ( " Could not load positioner class: " + positionerClassName ) ;
2006-08-21 12:11:16 +00:00
}
}
}
// Register radio mediums
2007-03-23 23:33:54 +00:00
String [ ] radioMediumsClassNames = projectConfig . getStringArrayValue (
2006-08-21 12:11:16 +00:00
GUI . class , " RADIOMEDIUMS " ) ;
if ( radioMediumsClassNames ! = null ) {
for ( String radioMediumClassName : radioMediumsClassNames ) {
Class < ? extends RadioMedium > radioMediumClass = tryLoadClass ( this ,
RadioMedium . class , radioMediumClassName ) ;
if ( radioMediumClass ! = null ) {
registerRadioMedium ( radioMediumClass ) ;
// logger.info("Loaded radio medium class: " + radioMediumClassName);
} else {
logger . warn ( " Could not load radio medium class: "
+ radioMediumClassName ) ;
}
}
}
}
/ * *
2007-03-23 23:33:54 +00:00
* Returns the current project configuration common to the entire simulator .
2007-08-22 11:23:50 +00:00
*
2007-03-23 23:33:54 +00:00
* @return Current project configuration
2006-08-21 12:11:16 +00:00
* /
2007-03-23 23:33:54 +00:00
public ProjectConfig getProjectConfig ( ) {
return projectConfig ;
2006-08-21 12:11:16 +00:00
}
/ * *
2007-03-23 23:33:54 +00:00
* Returns the current project directories common to the entire simulator .
2007-08-22 11:23:50 +00:00
*
2007-03-23 23:33:54 +00:00
* @return Current project directories .
2006-08-21 12:11:16 +00:00
* /
2007-03-23 23:33:54 +00:00
public Vector < File > getProjectDirs ( ) {
return currentProjectDirs ;
2006-08-21 12:11:16 +00:00
}
// // PLUGIN METHODS ////
/ * *
* Show a started plugin in working area .
2007-08-22 11:23:50 +00:00
*
2008-12-16 15:10:49 +00:00
* @param plugin Plugin
2006-08-21 12:11:16 +00:00
* /
2008-12-16 15:10:49 +00:00
public void showPlugin ( final Plugin plugin ) {
2008-11-04 14:32:32 +00:00
new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
2008-12-16 15:10:49 +00:00
JInternalFrame pluginFrame = plugin . getGUI ( ) ;
if ( pluginFrame = = null ) {
logger . fatal ( " Failed trying to show plugin without visualizer! " ) ;
return false ;
}
2008-11-04 14:32:32 +00:00
int nrFrames = myDesktopPane . getAllFrames ( ) . length ;
2008-12-16 15:10:49 +00:00
myDesktopPane . add ( pluginFrame ) ;
2006-08-21 12:11:16 +00:00
2008-12-16 15:10:49 +00:00
/* Set size if not already specified by plugin */
if ( pluginFrame . getWidth ( ) < = 0 | | pluginFrame . getHeight ( ) < = 0 ) {
pluginFrame . setSize ( FRAME_STANDARD_WIDTH , FRAME_STANDARD_HEIGHT ) ;
2008-11-04 14:32:32 +00:00
}
2006-08-21 12:11:16 +00:00
2008-12-16 15:10:49 +00:00
/* Set location if not already visible */
if ( pluginFrame . getLocation ( ) . x < = 0 & & pluginFrame . getLocation ( ) . y < = 0 ) {
pluginFrame . setLocation (
2008-11-04 14:32:32 +00:00
nrFrames * FRAME_NEW_OFFSET ,
nrFrames * FRAME_NEW_OFFSET ) ;
}
2007-01-10 14:57:42 +00:00
2008-12-16 15:10:49 +00:00
pluginFrame . setVisible ( true ) ;
2008-10-03 14:31:32 +00:00
2008-12-16 15:10:49 +00:00
/* Select plugin */
2008-11-04 14:32:32 +00:00
try {
for ( JInternalFrame existingPlugin : myDesktopPane . getAllFrames ( ) ) {
existingPlugin . setSelected ( false ) ;
}
2008-12-16 15:10:49 +00:00
pluginFrame . setSelected ( true ) ;
} catch ( Exception e ) { }
myDesktopPane . moveToFront ( pluginFrame ) ;
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
return true ;
}
} . invokeAndWait ( ) ;
2006-08-21 12:11:16 +00:00
}
2008-03-17 08:35:10 +00:00
/ * *
* Close all mote plugins for given mote .
*
* @param mote Mote
* /
public void closeMotePlugins ( Mote mote ) {
Vector < Plugin > pluginsToRemove = new Vector < Plugin > ( ) ;
for ( Plugin startedPlugin : startedPlugins ) {
int pluginType = startedPlugin . getClass ( ) . getAnnotation ( PluginType . class ) . value ( ) ;
if ( pluginType ! = PluginType . MOTE_PLUGIN ) {
continue ;
}
Mote pluginMote = ( Mote ) startedPlugin . getTag ( ) ;
if ( pluginMote = = mote ) {
pluginsToRemove . add ( startedPlugin ) ;
}
}
for ( Plugin pluginToRemove : pluginsToRemove ) {
removePlugin ( pluginToRemove , false ) ;
}
}
2006-08-21 12:11:16 +00:00
/ * *
* Remove a plugin from working area .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param plugin
* Plugin to remove
* @param askUser
* If plugin is the last one , ask user if we should remove current
* simulation also ?
* /
2008-11-04 14:32:32 +00:00
public void removePlugin ( final Plugin plugin , final boolean askUser ) {
new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
/* Free resources */
plugin . closePlugin ( ) ;
startedPlugins . remove ( plugin ) ;
2009-05-28 12:55:14 +00:00
updateGUIComponentState ( ) ;
2007-01-10 14:57:42 +00:00
2008-11-04 14:32:32 +00:00
/* Dispose visualized components */
2008-12-16 15:10:49 +00:00
if ( plugin . getGUI ( ) ! = null ) {
plugin . getGUI ( ) . dispose ( ) ;
2008-11-04 14:32:32 +00:00
}
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
/* (OPTIONAL) Remove simulation if all plugins are closed */
if ( getSimulation ( ) ! = null & & askUser & & startedPlugins . isEmpty ( ) ) {
doRemoveSimulation ( true ) ;
}
return true ;
2006-08-21 12:11:16 +00:00
}
2008-11-04 14:32:32 +00:00
} . invokeAndWait ( ) ;
2006-08-21 12:11:16 +00:00
}
/ * *
2009-06-10 15:57:08 +00:00
* Same as the { @link # startPlugin ( Class , GUI , Simulation , Mote ) } method ,
* but does not throw exceptions . If COOJA is visualised , an error dialog
* is shown if plugin could not be started .
*
* @see # startPlugin ( Class , GUI , Simulation , Mote )
* @param pluginClass Plugin class
* @param argGUI Plugin GUI argument
* @param argSimulation Plugin simulation argument
* @param argMote Plugin mote argument
* @return Started plugin
* /
public Plugin tryStartPlugin ( final Class < ? extends Plugin > pluginClass ,
final GUI argGUI , final Simulation argSimulation , final Mote argMote ) {
try {
return startPlugin ( pluginClass , argGUI , argSimulation , argMote ) ;
} catch ( PluginConstructionException ex ) {
if ( GUI . isVisualized ( ) ) {
GUI . showErrorDialog ( GUI . getTopParentContainer ( ) , " Error when starting plugin " , ex , false ) ;
} else {
2009-06-11 10:23:29 +00:00
/* If the plugin requires visualization, inform user */
Throwable cause = ex . getCause ( ) ;
do {
if ( cause instanceof PluginRequiresVisualizationException ) {
logger . info ( " Visualized plugin was not started: " + pluginClass ) ;
return null ;
}
} while ( ( cause = cause . getCause ( ) ) ! = null ) ;
2009-06-10 15:57:08 +00:00
logger . fatal ( " Error when starting plugin " , ex ) ;
}
}
return null ;
}
/ * *
* Starts given plugin . If visualized , the plugin is also shown .
*
* @see PluginType
* @param pluginClass Plugin class
* @param argGUI Plugin GUI argument
* @param argSimulation Plugin simulation argument
* @param argMote Plugin mote argument
* @return Started plugin
* @throws PluginConstructionException At errors
2006-08-21 12:11:16 +00:00
* /
2008-11-04 14:32:32 +00:00
public Plugin startPlugin ( final Class < ? extends Plugin > pluginClass ,
2009-06-10 15:57:08 +00:00
final GUI argGUI , final Simulation argSimulation , final Mote argMote )
throws PluginConstructionException
{
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
// Check that plugin class is registered
if ( ! pluginClasses . contains ( pluginClass ) ) {
2009-06-10 15:57:08 +00:00
throw new PluginConstructionException ( " Plugin class not registered: " + pluginClass ) ;
2006-08-21 12:11:16 +00:00
}
2007-01-09 10:27:53 +00:00
// Construct plugin depending on plugin type
2008-12-16 15:10:49 +00:00
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
2009-06-10 15:57:08 +00:00
Plugin plugin ;
2006-08-21 12:11:16 +00:00
2008-12-16 15:10:49 +00:00
try {
if ( pluginType = = PluginType . MOTE_PLUGIN ) {
2009-06-10 15:57:08 +00:00
if ( argGUI = = null ) {
throw new PluginConstructionException ( " No GUI argument for mote plugin " ) ;
}
if ( argSimulation = = null ) {
throw new PluginConstructionException ( " No simulation argument for mote plugin " ) ;
}
if ( argMote = = null ) {
throw new PluginConstructionException ( " No mote argument for mote plugin " ) ;
2008-12-16 15:10:49 +00:00
}
2006-08-21 12:11:16 +00:00
2009-06-10 15:57:08 +00:00
plugin =
pluginClass . getConstructor ( new Class [ ] { Mote . class , Simulation . class , GUI . class } )
. newInstance ( argMote , argSimulation , argGUI ) ;
/* Tag plugin with mote */
plugin . tagWithObject ( argMote ) ;
2007-01-10 14:57:42 +00:00
2008-12-16 15:10:49 +00:00
} else if ( pluginType = = PluginType . SIM_PLUGIN
| | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
2009-06-10 15:57:08 +00:00
if ( argGUI = = null ) {
throw new PluginConstructionException ( " No GUI argument for simulation plugin " ) ;
}
if ( argSimulation = = null ) {
throw new PluginConstructionException ( " No simulation argument for simulation plugin " ) ;
2008-12-16 15:10:49 +00:00
}
2006-08-21 12:11:16 +00:00
2009-06-10 15:57:08 +00:00
plugin =
pluginClass . getConstructor ( new Class [ ] { Simulation . class , GUI . class } )
. newInstance ( argSimulation , argGUI ) ;
2008-12-16 15:10:49 +00:00
} else if ( pluginType = = PluginType . COOJA_PLUGIN
| | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
2009-06-10 15:57:08 +00:00
if ( argGUI = = null ) {
throw new PluginConstructionException ( " No GUI argument for GUI plugin " ) ;
2006-12-13 11:57:04 +00:00
}
2009-06-10 15:57:08 +00:00
plugin =
pluginClass . getConstructor ( new Class [ ] { GUI . class } )
. newInstance ( argGUI ) ;
2008-12-17 11:02:05 +00:00
} else {
2009-06-10 15:57:08 +00:00
throw new PluginConstructionException ( " Bad plugin type: " + pluginType ) ;
2008-12-17 11:02:05 +00:00
}
2009-06-10 15:57:08 +00:00
} catch ( PluginRequiresVisualizationException e ) {
PluginConstructionException ex = new PluginConstructionException ( " Plugin class requires visualization: " + pluginClass . getName ( ) ) ;
ex . initCause ( e ) ;
throw ex ;
2008-12-16 15:10:49 +00:00
} catch ( Exception e ) {
2009-06-10 15:57:08 +00:00
PluginConstructionException ex = new PluginConstructionException ( " Construction error for plugin of class: " + pluginClass . getName ( ) ) ;
ex . initCause ( e ) ;
throw ex ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2007-01-09 10:27:53 +00:00
// Add to active plugins list
2008-12-16 15:10:49 +00:00
startedPlugins . add ( plugin ) ;
2009-05-28 12:55:14 +00:00
updateGUIComponentState ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Show plugin if visualizer type
2008-12-16 15:10:49 +00:00
if ( plugin . getGUI ( ) ! = null ) {
myGUI . showPlugin ( plugin ) ;
2007-01-09 10:27:53 +00:00
}
2008-12-16 15:10:49 +00:00
return plugin ;
2006-08-21 12:11:16 +00:00
}
/ * *
* Register a plugin to be included in the GUI . The plugin will be visible in
* the menubar .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param newPluginClass
* New plugin to register
* @return True if this plugin was registered ok , false otherwise
* /
2007-01-09 10:27:53 +00:00
public boolean registerPlugin ( Class < ? extends Plugin > newPluginClass ) {
2006-08-21 12:11:16 +00:00
return registerPlugin ( newPluginClass , true ) ;
}
/ * *
* Register a temporary plugin to be included in the GUI . The plugin will be
* visible in the menubar . This plugin will automatically be unregistered if
* the current simulation is removed .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param newPluginClass
* New plugin to register
* @return True if this plugin was registered ok , false otherwise
* /
2007-01-10 14:57:42 +00:00
public boolean registerTemporaryPlugin ( Class < ? extends Plugin > newPluginClass ) {
2007-08-22 11:23:50 +00:00
if ( pluginClasses . contains ( newPluginClass ) ) {
2006-08-21 12:11:16 +00:00
return false ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
boolean returnVal = registerPlugin ( newPluginClass , true ) ;
2007-08-22 11:23:50 +00:00
if ( ! returnVal ) {
2006-08-21 12:11:16 +00:00
return false ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
pluginClassesTemporary . add ( newPluginClass ) ;
return true ;
}
/ * *
* Unregister a plugin class . Removes any plugin menu items links as well .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param pluginClass
* Plugin class to unregister
* /
2007-01-09 10:27:53 +00:00
public void unregisterPlugin ( Class < ? extends Plugin > pluginClass ) {
2006-08-21 12:11:16 +00:00
// Remove (if existing) plugin class menu items
for ( Component menuComponent : menuPlugins . getMenuComponents ( ) ) {
if ( menuComponent . getClass ( ) . isAssignableFrom ( JMenuItem . class ) ) {
JMenuItem menuItem = ( JMenuItem ) menuComponent ;
2007-08-22 11:23:50 +00:00
if ( menuItem . getClientProperty ( " class " ) . equals ( pluginClass ) ) {
2006-08-21 12:11:16 +00:00
menuPlugins . remove ( menuItem ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
}
2007-08-22 11:23:50 +00:00
if ( menuMotePluginClasses . contains ( pluginClass ) ) {
2007-03-22 11:14:27 +00:00
menuMotePluginClasses . remove ( pluginClass ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
// Remove from plugin vectors (including temporary)
2007-08-22 11:23:50 +00:00
if ( pluginClasses . contains ( pluginClass ) ) {
2006-08-21 12:11:16 +00:00
pluginClasses . remove ( pluginClass ) ;
2007-08-22 11:23:50 +00:00
}
if ( pluginClassesTemporary . contains ( pluginClass ) ) {
2006-08-21 12:11:16 +00:00
pluginClassesTemporary . remove ( pluginClass ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
/ * *
* Register a plugin to be included in the GUI .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param newPluginClass
* 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
* /
2008-11-04 14:32:32 +00:00
private boolean registerPlugin ( final Class < ? extends Plugin > newPluginClass ,
2006-08-21 12:11:16 +00:00
boolean addToMenu ) {
// Get description annotation (if any)
2008-11-04 14:32:32 +00:00
final String description = getDescriptionOf ( newPluginClass ) ;
2006-08-21 12:11:16 +00:00
// Get plugin type annotation (required)
2008-11-04 14:32:32 +00:00
final int pluginType ;
2007-01-09 10:27:53 +00:00
if ( newPluginClass . isAnnotationPresent ( PluginType . class ) ) {
pluginType = newPluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
2006-08-21 12:11:16 +00:00
} else {
2007-01-09 10:27:53 +00:00
pluginType = PluginType . UNDEFINED_PLUGIN ;
2006-08-21 12:11:16 +00:00
}
// Check that plugin type is valid and constructor exists
try {
2007-01-09 10:27:53 +00:00
if ( pluginType = = PluginType . MOTE_PLUGIN ) {
2007-01-10 14:57:42 +00:00
newPluginClass . getConstructor ( new Class [ ] { Mote . class ,
Simulation . class , GUI . class } ) ;
} else if ( pluginType = = PluginType . SIM_PLUGIN
| | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
2008-11-04 14:32:32 +00:00
newPluginClass . getConstructor ( new Class [ ] { Simulation . class , GUI . class } ) ;
2007-01-10 14:57:42 +00:00
} else if ( pluginType = = PluginType . COOJA_PLUGIN
| | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
newPluginClass . getConstructor ( new Class [ ] { GUI . class } ) ;
2006-08-21 12:11:16 +00:00
} else {
2008-11-04 14:32:32 +00:00
logger . fatal ( " Could not find valid plugin type annotation in class " + newPluginClass ) ;
2006-08-21 12:11:16 +00:00
return false ;
}
} catch ( NoSuchMethodException e ) {
2008-11-04 14:32:32 +00:00
logger . fatal ( " Could not find valid constructor in class " + newPluginClass + " : " + e ) ;
2006-08-21 12:11:16 +00:00
return false ;
}
2007-01-09 10:27:53 +00:00
if ( addToMenu & & menuPlugins ! = null ) {
2008-11-04 14:32:32 +00:00
new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
// Create 'start plugin'-menu item
2009-05-28 14:53:26 +00:00
JMenuItem menuItem ;
2009-05-28 12:55:14 +00:00
String tooltip = " <html> " ;
2009-02-18 17:25:14 +00:00
/* Sort menu according to plugin type */
int itemIndex = 0 ;
if ( pluginType = = PluginType . COOJA_PLUGIN | | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
for ( ; itemIndex < menuPlugins . getItemCount ( ) ; itemIndex + + ) {
if ( menuPlugins . getItem ( itemIndex ) = = null /* separator */ ) {
break ;
}
}
2009-05-28 12:55:14 +00:00
tooltip + = " COOJA plugin: " + newPluginClass . getName ( ) ;
2009-05-28 14:53:26 +00:00
menuItem = new JMenuItem ( description ) ;
2009-05-28 13:45:18 +00:00
menuItem . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
2009-06-10 15:57:08 +00:00
tryStartPlugin ( newPluginClass , myGUI , null , null ) ;
2009-05-28 13:45:18 +00:00
}
} ) ;
2009-02-18 17:25:14 +00:00
} else if ( pluginType = = PluginType . SIM_PLUGIN | | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
for ( ; itemIndex < menuPlugins . getItemCount ( ) ; itemIndex + + ) {
if ( menuPlugins . getItem ( itemIndex ) = = null /* separator */ ) {
break ;
}
}
itemIndex + + ;
for ( ; itemIndex < menuPlugins . getItemCount ( ) ; itemIndex + + ) {
if ( menuPlugins . getItem ( itemIndex ) = = null /* separator */ ) {
break ;
}
}
2009-05-28 12:55:14 +00:00
tooltip + = " Simulation plugin: " + newPluginClass . getName ( ) ;
2009-05-28 14:53:26 +00:00
GUIAction guiAction = new StartPluginGUIAction ( description ) ;
menuItem = new JMenuItem ( guiAction ) ;
guiActions . add ( guiAction ) ;
2009-02-18 17:25:14 +00:00
} else if ( pluginType = = PluginType . MOTE_PLUGIN ) {
2008-11-04 14:32:32 +00:00
// Disable previous menu item and add new item to mote plugins menu
2009-05-28 14:53:26 +00:00
menuItem = new JMenuItem ( description ) ;
2008-11-04 14:32:32 +00:00
menuItem . setEnabled ( false ) ;
2009-05-28 12:55:14 +00:00
tooltip + = " Mote plugin: " + newPluginClass . getName ( ) ;
tooltip + = " <br>Start mote plugins by right-clicking a mote in the simulation visualizer " ;
2008-11-04 14:32:32 +00:00
menuMotePluginClasses . add ( newPluginClass ) ;
2009-02-18 17:25:14 +00:00
itemIndex = menuPlugins . getItemCount ( ) ;
2009-05-28 14:53:26 +00:00
} else {
logger . warn ( " Unknown plugin type: " + pluginType ) ;
return false ;
2008-11-04 14:32:32 +00:00
}
2009-02-18 17:25:14 +00:00
2009-05-28 12:55:14 +00:00
/* Check if plugin was imported by a project directory */
File project =
getProjectConfig ( ) . getUserProjectDefining ( GUI . class , " PLUGINS " , newPluginClass . getName ( ) ) ;
if ( project ! = null ) {
tooltip + = " <br>Loaded by project: " + project . getPath ( ) ;
}
tooltip + = " </html> " ;
menuItem . setToolTipText ( tooltip ) ;
2009-05-28 14:53:26 +00:00
menuItem . putClientProperty ( " class " , newPluginClass ) ;
2009-05-28 12:55:14 +00:00
2009-02-18 17:25:14 +00:00
menuPlugins . add ( menuItem , itemIndex ) ;
2008-11-04 14:32:32 +00:00
return true ;
}
} . invokeAndWait ( ) ;
2006-08-21 12:11:16 +00:00
}
pluginClasses . add ( newPluginClass ) ;
return true ;
}
/ * *
* Unregister all plugin classes , including temporary plugins .
* /
public void unregisterPlugins ( ) {
2007-01-09 10:27:53 +00:00
if ( menuPlugins ! = null ) {
menuPlugins . removeAll ( ) ;
2009-02-18 17:25:14 +00:00
/* COOJA/GUI plugins at top, simulation plugins in middle, mote plugins at bottom */
menuPlugins . addSeparator ( ) ;
menuPlugins . addSeparator ( ) ;
2007-05-28 09:01:49 +00:00
}
if ( menuMotePluginClasses ! = null ) {
2007-03-22 11:14:27 +00:00
menuMotePluginClasses . clear ( ) ;
2007-01-09 10:27:53 +00:00
}
2006-08-21 12:11:16 +00:00
pluginClasses . clear ( ) ;
pluginClassesTemporary . clear ( ) ;
}
/ * *
2007-03-22 11:14:27 +00:00
* Return a mote plugins submenu for given mote .
2007-08-22 11:23:50 +00:00
*
2007-03-22 11:14:27 +00:00
* @param mote Mote
* @return Mote plugins menu
2006-08-21 12:11:16 +00:00
* /
2007-03-22 11:14:27 +00:00
public JMenu createMotePluginsSubmenu ( Mote mote ) {
JMenu menuMotePlugins = new JMenu ( " Open mote plugin for " + mote ) ;
for ( Class < ? extends Plugin > motePluginClass : menuMotePluginClasses ) {
2009-06-02 15:04:49 +00:00
GUIAction guiAction = new StartPluginGUIAction ( getDescriptionOf ( motePluginClass ) ) ;
JMenuItem menuItem = new JMenuItem ( guiAction ) ;
2007-03-22 11:14:27 +00:00
menuItem . putClientProperty ( " class " , motePluginClass ) ;
menuItem . putClientProperty ( " mote " , mote ) ;
menuMotePlugins . add ( menuItem ) ;
}
return menuMotePlugins ;
2006-08-21 12:11:16 +00:00
}
// // GUI CONTROL METHODS ////
2007-01-09 10:27:53 +00:00
/ * *
* @return Current simulation
* /
public Simulation getSimulation ( ) {
return mySimulation ;
}
2007-01-10 14:57:42 +00:00
2009-06-09 09:47:04 +00:00
public void setSimulation ( Simulation sim , boolean startPlugins ) {
2006-08-21 12:11:16 +00:00
if ( sim ! = null ) {
doRemoveSimulation ( false ) ;
}
2007-01-09 10:27:53 +00:00
mySimulation = sim ;
2009-05-28 12:55:14 +00:00
updateGUIComponentState ( ) ;
2006-08-21 12:11:16 +00:00
// Set frame title
2007-08-22 11:23:50 +00:00
if ( frame ! = null ) {
2007-01-09 10:27:53 +00:00
frame . setTitle ( " COOJA Simulator " + " - " + sim . getTitle ( ) ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2006-11-06 17:55:59 +00:00
// Open standard plugins (if none opened already)
2009-06-09 09:47:04 +00:00
if ( startPlugins ) {
2007-01-09 10:27:53 +00:00
for ( Class < ? extends Plugin > pluginClass : pluginClasses ) {
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
if ( pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
2009-06-10 15:57:08 +00:00
tryStartPlugin ( pluginClass , this , sim , null ) ;
2006-11-06 17:55:59 +00:00
}
2006-08-21 12:11:16 +00:00
}
2007-08-22 11:23:50 +00:00
}
2008-04-22 13:04:43 +00:00
setChanged ( ) ;
notifyObservers ( ) ;
2006-08-21 12:11:16 +00:00
}
/ * *
* Creates a new mote type of the given mote type class .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param moteTypeClass
* Mote type class
* /
public void doCreateMoteType ( Class < ? extends MoteType > moteTypeClass ) {
2007-01-09 10:27:53 +00:00
if ( mySimulation = = null ) {
2006-08-21 12:11:16 +00:00
logger . fatal ( " Can't create mote type (no simulation) " ) ;
return ;
}
// Stop simulation (if running)
2007-01-09 10:27:53 +00:00
mySimulation . stopSimulation ( ) ;
2006-08-21 12:11:16 +00:00
// Create mote type
MoteType newMoteType = null ;
boolean moteTypeOK = false ;
try {
newMoteType = moteTypeClass . newInstance ( ) ;
2008-02-12 15:20:56 +00:00
moteTypeOK = newMoteType . configureAndInit ( GUI . getTopParentContainer ( ) , mySimulation , isVisualized ( ) ) ;
2009-04-20 16:07:32 +00:00
} catch ( Exception e ) {
logger . fatal ( " Exception when creating mote type " , e ) ;
if ( isVisualized ( ) ) {
showErrorDialog ( getTopParentContainer ( ) , " Mote type creation error " , e , false ) ;
}
2006-08-21 12:11:16 +00:00
return ;
}
// Add mote type to simulation
2008-10-03 13:17:28 +00:00
if ( moteTypeOK ) {
2007-01-09 10:27:53 +00:00
mySimulation . addMoteType ( newMoteType ) ;
2008-10-03 13:17:28 +00:00
/* Allow user to immediately add motes */
doAddMotes ( newMoteType ) ;
2006-08-21 12:11:16 +00:00
}
}
/ * *
* Remove current simulation
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param askForConfirmation
* Should we ask for confirmation if a simulation is already active ?
2008-11-04 14:32:32 +00:00
* @return True if no simulation exists when method returns
2006-08-21 12:11:16 +00:00
* /
2008-11-04 14:32:32 +00:00
public boolean doRemoveSimulation ( boolean askForConfirmation ) {
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( mySimulation = = null ) {
return true ;
}
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( askForConfirmation ) {
boolean ok = new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
String s1 = " Remove " ;
String s2 = " Cancel " ;
Object [ ] options = { s1 , s2 } ;
int n = JOptionPane . showOptionDialog ( GUI . getTopParentContainer ( ) ,
" You have an active simulation. \ nDo you want to remove it? " ,
" Remove current simulation? " , JOptionPane . YES_NO_OPTION ,
JOptionPane . QUESTION_MESSAGE , null , options , s1 ) ;
if ( n ! = JOptionPane . YES_OPTION ) {
return false ;
}
return true ;
2007-08-22 11:23:50 +00:00
}
2008-11-04 14:32:32 +00:00
} . invokeAndWait ( ) ;
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( ! ok ) {
return false ;
2006-08-21 12:11:16 +00:00
}
2008-11-04 14:32:32 +00:00
}
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
// Close all started non-GUI plugins
for ( Object startedPlugin : startedPlugins . toArray ( ) ) {
int pluginType = startedPlugin . getClass ( ) . getAnnotation ( PluginType . class ) . value ( ) ;
if ( pluginType ! = PluginType . COOJA_PLUGIN
& & pluginType ! = PluginType . COOJA_STANDARD_PLUGIN ) {
removePlugin ( ( Plugin ) startedPlugin , false ) ;
2008-02-12 15:20:56 +00:00
}
2008-11-04 14:32:32 +00:00
}
2008-04-22 13:04:43 +00:00
2008-11-04 14:32:32 +00:00
// Delete simulation
mySimulation . deleteObservers ( ) ;
mySimulation . stopSimulation ( ) ;
2009-02-27 14:48:15 +00:00
/* Clear current mote relations */
MoteRelation relations [ ] = getMoteRelations ( ) ;
for ( MoteRelation r : relations ) {
removeMoteRelation ( r . source , r . dest ) ;
}
2008-11-04 14:32:32 +00:00
mySimulation = null ;
2009-05-28 12:55:14 +00:00
updateGUIComponentState ( ) ;
2008-11-04 14:32:32 +00:00
// Unregister temporary plugin classes
2009-03-11 07:45:54 +00:00
Class < ? extends Plugin > [ ] pluginClasses =
new Class [ pluginClassesTemporary . size ( ) ] ;
pluginClassesTemporary . toArray ( pluginClasses ) ;
for ( Class < ? extends Plugin > pClass : pluginClasses ) {
unregisterPlugin ( pClass ) ;
2006-08-21 12:11:16 +00:00
}
2008-11-04 14:32:32 +00:00
// Reset frame title
if ( isVisualizedInFrame ( ) ) {
frame . setTitle ( " COOJA Simulator " ) ;
}
setChanged ( ) ;
notifyObservers ( ) ;
return true ;
2006-08-21 12:11:16 +00:00
}
/ * *
* Load a simulation configuration file from disk
2007-08-22 11:23:50 +00:00
*
2007-03-22 13:59:33 +00:00
* @param askForConfirmation Ask for confirmation before removing any current simulation
* @param quick Quick - load simulation
* @param configFile Configuration file to load , if null a dialog will appear
2006-08-21 12:11:16 +00:00
* /
2007-03-22 15:02:55 +00:00
public void doLoadConfig ( boolean askForConfirmation , final boolean quick , File configFile ) {
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
return ;
}
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
/* Remove current simulation */
if ( ! doRemoveSimulation ( true ) ) {
2006-08-21 12:11:16 +00:00
return ;
}
2008-11-04 14:32:32 +00:00
/* Use provided configuration, or open File Chooser */
2008-09-29 13:02:15 +00:00
if ( configFile ! = null & & ! configFile . isDirectory ( ) ) {
2007-03-22 15:02:55 +00:00
if ( ! configFile . exists ( ) | | ! configFile . canRead ( ) ) {
2009-03-11 20:14:52 +00:00
logger . fatal ( " No read access to file: " + configFile . getAbsolutePath ( ) ) ;
/* File does not exist, open dialog */
doLoadConfig ( askForConfirmation , quick , null ) ;
2007-03-22 15:02:55 +00:00
return ;
}
} else {
2008-11-04 14:32:32 +00:00
final File suggestedFile = configFile ;
configFile = new RunnableInEDT < File > ( ) {
public File work ( ) {
JFileChooser fc = new JFileChooser ( ) ;
fc . setFileFilter ( GUI . SAVED_SIMULATIONS_FILES ) ;
if ( suggestedFile ! = null & & suggestedFile . isDirectory ( ) ) {
fc . setCurrentDirectory ( suggestedFile ) ;
} else {
/* Suggest file using file history */
2009-05-27 23:23:41 +00:00
File suggestedFile = getLastOpenedFile ( ) ;
if ( suggestedFile ! = null ) {
2008-11-04 14:32:32 +00:00
fc . setSelectedFile ( suggestedFile ) ;
}
}
2007-03-22 13:59:33 +00:00
2008-11-04 14:32:32 +00:00
int returnVal = fc . showOpenDialog ( GUI . getTopParentContainer ( ) ) ;
if ( returnVal ! = JFileChooser . APPROVE_OPTION ) {
logger . info ( " Load command cancelled by user... " ) ;
return null ;
}
2007-03-22 13:59:33 +00:00
2008-11-04 14:32:32 +00:00
File file = fc . getSelectedFile ( ) ;
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( ! file . exists ( ) ) {
/* Try default file extension */
file = new File ( file . getParent ( ) , file . getName ( ) + SAVED_SIMULATIONS_FILES ) ;
}
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( ! file . exists ( ) | | ! file . canRead ( ) ) {
logger . fatal ( " No read access to file " ) ;
return null ;
}
2007-03-22 13:59:33 +00:00
2008-11-04 14:32:32 +00:00
return file ;
2007-03-22 15:02:55 +00:00
}
2008-11-04 14:32:32 +00:00
} . invokeAndWait ( ) ;
2006-08-21 12:11:16 +00:00
2008-11-04 14:32:32 +00:00
if ( configFile = = null ) {
2007-03-22 15:02:55 +00:00
return ;
2006-08-21 12:11:16 +00:00
}
2007-03-22 15:02:55 +00:00
}
2006-08-21 12:11:16 +00:00
2008-02-12 15:20:56 +00:00
final JDialog progressDialog ;
2009-06-12 13:00:57 +00:00
final String progressTitle = configFile = = null
? " Loading " : ( " Loading " + configFile . getAbsolutePath ( ) ) ;
2008-02-12 15:20:56 +00:00
2008-09-29 13:02:15 +00:00
if ( quick ) {
final Thread loadThread = Thread . currentThread ( ) ;
2008-11-04 14:32:32 +00:00
progressDialog = new RunnableInEDT < JDialog > ( ) {
public JDialog work ( ) {
final JDialog progressDialog ;
if ( GUI . getTopParentContainer ( ) instanceof Window ) {
2009-06-12 13:00:57 +00:00
progressDialog = new JDialog ( ( Window ) GUI . getTopParentContainer ( ) , progressTitle , ModalityType . APPLICATION_MODAL ) ;
2008-11-04 14:32:32 +00:00
} else if ( GUI . getTopParentContainer ( ) instanceof Frame ) {
2009-06-12 13:00:57 +00:00
progressDialog = new JDialog ( ( Frame ) GUI . getTopParentContainer ( ) , progressTitle , ModalityType . APPLICATION_MODAL ) ;
2008-11-04 14:32:32 +00:00
} else if ( GUI . getTopParentContainer ( ) instanceof Dialog ) {
2009-06-12 13:00:57 +00:00
progressDialog = new JDialog ( ( Dialog ) GUI . getTopParentContainer ( ) , progressTitle , ModalityType . APPLICATION_MODAL ) ;
2008-11-04 14:32:32 +00:00
} else {
logger . warn ( " No parent container " ) ;
2009-06-12 13:00:57 +00:00
progressDialog = new JDialog ( ( Frame ) null , progressTitle , ModalityType . APPLICATION_MODAL ) ;
2008-11-04 14:32:32 +00:00
}
2008-09-29 13:02:15 +00:00
JPanel progressPanel = new JPanel ( new BorderLayout ( ) ) ;
JProgressBar progressBar ;
JButton button ;
progressBar = new JProgressBar ( 0 , 100 ) ;
progressBar . setValue ( 0 ) ;
progressBar . setIndeterminate ( true ) ;
2009-03-11 20:14:52 +00:00
PROGRESS_BAR = progressBar ; /* Allow various parts of COOJA to show messages */
button = new JButton ( " Cancel " ) ;
2008-09-29 13:02:15 +00:00
button . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
2008-11-04 14:32:32 +00:00
if ( loadThread . isAlive ( ) ) {
2008-09-29 13:02:15 +00:00
loadThread . interrupt ( ) ;
doRemoveSimulation ( false ) ;
}
2008-11-04 14:32:32 +00:00
if ( progressDialog . isDisplayable ( ) ) {
2008-09-29 13:02:15 +00:00
progressDialog . dispose ( ) ;
}
}
} ) ;
2006-08-21 12:11:16 +00:00
2008-09-29 13:02:15 +00:00
progressPanel . add ( BorderLayout . CENTER , progressBar ) ;
progressPanel . add ( BorderLayout . SOUTH , button ) ;
progressPanel . setBorder ( BorderFactory . createEmptyBorder ( 20 , 20 , 20 , 20 ) ) ;
2007-03-22 15:02:55 +00:00
2008-09-29 13:02:15 +00:00
progressPanel . setVisible ( true ) ;
2007-03-22 15:02:55 +00:00
2008-09-29 13:02:15 +00:00
progressDialog . getContentPane ( ) . add ( progressPanel ) ;
2009-03-11 20:14:52 +00:00
progressDialog . setSize ( 400 , 200 ) ;
2006-08-21 12:11:16 +00:00
2008-09-29 13:02:15 +00:00
progressDialog . getRootPane ( ) . setDefaultButton ( button ) ;
progressDialog . setLocationRelativeTo ( GUI . getTopParentContainer ( ) ) ;
progressDialog . setDefaultCloseOperation ( JDialog . DO_NOTHING_ON_CLOSE ) ;
2008-11-04 14:32:32 +00:00
java . awt . EventQueue . invokeLater ( new Runnable ( ) {
public void run ( ) {
progressDialog . setVisible ( true ) ;
}
} ) ;
return progressDialog ;
2007-05-19 17:05:54 +00:00
}
2008-11-04 14:32:32 +00:00
} . invokeAndWait ( ) ;
2008-09-29 13:02:15 +00:00
} else {
progressDialog = null ;
2007-08-22 11:23:50 +00:00
}
2008-09-29 13:02:15 +00:00
// Load simulation in this thread, while showing progress monitor
final File fileToLoad = configFile ;
Simulation newSim = null ;
2009-03-21 14:24:55 +00:00
boolean shouldRetry = false ;
do {
try {
shouldRetry = false ;
myGUI . doRemoveSimulation ( false ) ;
newSim = loadSimulationConfig ( fileToLoad , quick ) ;
2009-06-09 09:47:04 +00:00
myGUI . setSimulation ( newSim , false ) ;
2009-03-21 14:24:55 +00:00
addToFileHistory ( fileToLoad ) ;
} catch ( UnsatisfiedLinkError e ) {
shouldRetry = showErrorDialog ( GUI . getTopParentContainer ( ) , " Simulation load error " , e , true ) ;
} catch ( SimulationCreationException e ) {
shouldRetry = showErrorDialog ( GUI . getTopParentContainer ( ) , " Simulation load error " , e , true ) ;
}
} while ( shouldRetry ) ;
2008-09-29 13:02:15 +00:00
if ( progressDialog ! = null & & progressDialog . isDisplayable ( ) ) {
progressDialog . dispose ( ) ;
}
return ;
2006-08-21 12:11:16 +00:00
}
2007-08-22 11:23:50 +00:00
2007-03-23 11:25:19 +00:00
/ * *
2008-12-08 09:38:42 +00:00
* Reload currently configured simulation .
* Reloading a simulation may include recompiling Contiki .
*
* @param autoStart Start executing simulation when loaded
* @param newSeed Change simulation seed
2007-03-23 11:25:19 +00:00
* /
2009-02-18 10:09:32 +00:00
public void reloadCurrentSimulation ( final boolean autoStart , final long randomSeed ) {
2007-04-02 12:45:19 +00:00
if ( getSimulation ( ) = = null ) {
logger . fatal ( " No simulation to reload " ) ;
return ;
}
2007-08-22 11:23:50 +00:00
2007-03-23 11:25:19 +00:00
final JDialog progressDialog = new JDialog ( frame , " Reloading " , true ) ;
final Thread loadThread = new Thread ( new Runnable ( ) {
public void run ( ) {
2008-03-19 09:40:38 +00:00
/* Get current simulation configuration */
Element root = new Element ( " simconf " ) ;
2007-03-23 11:25:19 +00:00
Element simulationElement = new Element ( " simulation " ) ;
2008-12-08 09:38:42 +00:00
2007-03-23 11:25:19 +00:00
simulationElement . addContent ( getSimulation ( ) . getConfigXML ( ) ) ;
root . addContent ( simulationElement ) ;
2008-03-19 09:40:38 +00:00
Collection < Element > pluginsConfig = getPluginsConfigXML ( ) ;
2007-08-22 11:23:50 +00:00
if ( pluginsConfig ! = null ) {
2007-03-23 11:25:19 +00:00
root . addContent ( pluginsConfig ) ;
2007-08-22 11:23:50 +00:00
}
2007-03-23 11:25:19 +00:00
2008-03-19 09:40:38 +00:00
/* Remove current simulation, and load config */
2007-05-11 10:55:07 +00:00
boolean shouldRetry = false ;
do {
try {
shouldRetry = false ;
myGUI . doRemoveSimulation ( false ) ;
2008-03-19 09:40:38 +00:00
Simulation newSim = loadSimulationConfig ( root , true ) ;
2009-06-09 09:47:04 +00:00
myGUI . setSimulation ( newSim , false ) ;
2009-02-18 10:09:32 +00:00
myGUI . getSimulation ( ) . setRandomSeed ( randomSeed ) ;
2008-04-22 13:04:43 +00:00
if ( autoStart ) {
newSim . startSimulation ( ) ;
}
2007-05-11 10:55:07 +00:00
} catch ( UnsatisfiedLinkError e ) {
shouldRetry = showErrorDialog ( frame , " Simulation reload error " , e , true ) ;
myGUI . doRemoveSimulation ( false ) ;
} catch ( SimulationCreationException e ) {
shouldRetry = showErrorDialog ( frame , " Simulation reload error " , e , true ) ;
myGUI . doRemoveSimulation ( false ) ;
2007-03-23 11:25:19 +00:00
}
2007-05-11 10:55:07 +00:00
} while ( shouldRetry ) ;
2007-03-23 11:25:19 +00:00
2008-12-08 09:38:42 +00:00
if ( progressDialog . isDisplayable ( ) ) {
2007-05-11 10:55:07 +00:00
progressDialog . dispose ( ) ;
}
2007-03-23 11:25:19 +00:00
}
} ) ;
// Display progress dialog while reloading
JProgressBar progressBar = new JProgressBar ( 0 , 100 ) ;
progressBar . setValue ( 0 ) ;
progressBar . setIndeterminate ( true ) ;
2009-03-11 20:14:52 +00:00
PROGRESS_BAR = progressBar ; /* Allow various parts of COOJA to show messages */
2007-03-23 11:25:19 +00:00
JButton button = new JButton ( " Cancel " ) ;
button . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
2008-12-08 09:38:42 +00:00
if ( loadThread . isAlive ( ) ) {
2007-03-23 11:25:19 +00:00
loadThread . interrupt ( ) ;
doRemoveSimulation ( false ) ;
}
2008-12-08 09:38:42 +00:00
if ( progressDialog . isDisplayable ( ) ) {
2007-03-23 11:25:19 +00:00
progressDialog . dispose ( ) ;
}
}
} ) ;
JPanel progressPanel = new JPanel ( new BorderLayout ( ) ) ;
progressPanel . add ( BorderLayout . CENTER , progressBar ) ;
progressPanel . add ( BorderLayout . SOUTH , button ) ;
progressPanel . setBorder ( BorderFactory . createEmptyBorder ( 20 , 20 , 20 , 20 ) ) ;
progressPanel . setVisible ( true ) ;
progressDialog . getContentPane ( ) . add ( progressPanel ) ;
2009-03-11 20:14:52 +00:00
progressDialog . setSize ( 400 , 200 ) ;
2007-03-23 11:25:19 +00:00
progressDialog . getRootPane ( ) . setDefaultButton ( button ) ;
progressDialog . setLocationRelativeTo ( frame ) ;
progressDialog . setDefaultCloseOperation ( JDialog . DO_NOTHING_ON_CLOSE ) ;
loadThread . start ( ) ;
progressDialog . setVisible ( true ) ;
}
2006-08-21 12:11:16 +00:00
2008-12-08 09:38:42 +00:00
/ * *
* Reload currently configured simulation .
* Reloading a simulation may include recompiling Contiki .
* The same random seed is used .
*
* @see # reloadCurrentSimulation ( boolean , boolean )
* @param autoStart Start executing simulation when loaded
* /
public void reloadCurrentSimulation ( boolean autoStart ) {
2009-02-18 10:09:32 +00:00
reloadCurrentSimulation ( autoStart , getSimulation ( ) . getRandomSeed ( ) ) ;
2008-12-08 09:38:42 +00:00
}
2006-08-21 12:11:16 +00:00
/ * *
* Save current simulation configuration to disk
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param askForConfirmation
* Ask for confirmation before overwriting file
* /
2009-06-09 09:47:04 +00:00
public File doSaveConfig ( boolean askForConfirmation ) {
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
2009-06-09 09:47:04 +00:00
return null ;
2008-02-18 08:18:01 +00:00
}
2009-06-09 09:47:04 +00:00
if ( mySimulation = = null ) {
return null ;
}
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
mySimulation . stopSimulation ( ) ;
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
JFileChooser fc = new JFileChooser ( ) ;
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
fc . setFileFilter ( GUI . SAVED_SIMULATIONS_FILES ) ;
2007-03-22 13:59:33 +00:00
2009-06-09 09:47:04 +00:00
// Suggest file using history
File suggestedFile = getLastOpenedFile ( ) ;
if ( suggestedFile ! = null ) {
fc . setSelectedFile ( suggestedFile ) ;
}
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
int returnVal = fc . showSaveDialog ( myDesktopPane ) ;
if ( returnVal = = JFileChooser . APPROVE_OPTION ) {
File saveFile = fc . getSelectedFile ( ) ;
if ( ! fc . accept ( saveFile ) ) {
saveFile = new File ( saveFile . getParent ( ) , saveFile . getName ( )
+ SAVED_SIMULATIONS_FILES ) ;
}
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
if ( saveFile . exists ( ) ) {
if ( askForConfirmation ) {
String s1 = " Overwrite " ;
String s2 = " Cancel " ;
Object [ ] options = { s1 , s2 } ;
int n = JOptionPane . showOptionDialog (
GUI . getTopParentContainer ( ) ,
" A file with the same name already exists. \ nDo you want to remove it? " ,
" Overwrite existing file? " , JOptionPane . YES_NO_OPTION ,
JOptionPane . QUESTION_MESSAGE , null , options , s1 ) ;
if ( n ! = JOptionPane . YES_OPTION ) {
return null ;
}
2007-08-22 11:23:50 +00:00
}
2009-06-09 09:47:04 +00:00
}
2006-08-21 12:11:16 +00:00
2009-06-09 09:47:04 +00:00
if ( ! saveFile . exists ( ) | | saveFile . canWrite ( ) ) {
saveSimulationConfig ( saveFile ) ;
addToFileHistory ( saveFile ) ;
return saveFile ;
2006-08-21 12:11:16 +00:00
} else {
2009-06-09 09:47:04 +00:00
logger . fatal ( " No write access to file " ) ;
2006-08-21 12:11:16 +00:00
}
2009-06-09 09:47:04 +00:00
} else {
logger . info ( " Save command cancelled by user... " ) ;
2006-08-21 12:11:16 +00:00
}
2009-06-09 09:47:04 +00:00
return null ;
2006-08-21 12:11:16 +00:00
}
/ * *
* Add new mote to current simulation
* /
public void doAddMotes ( MoteType moteType ) {
2007-01-09 10:27:53 +00:00
if ( mySimulation ! = null ) {
mySimulation . stopSimulation ( ) ;
2006-08-21 12:11:16 +00:00
2008-02-12 15:20:56 +00:00
Vector < Mote > newMotes = AddMoteDialog . showDialog ( getTopParentContainer ( ) , mySimulation ,
2007-01-10 14:57:42 +00:00
moteType ) ;
2006-08-21 12:11:16 +00:00
if ( newMotes ! = null ) {
2007-08-22 11:23:50 +00:00
for ( Mote newMote : newMotes ) {
2007-01-09 10:27:53 +00:00
mySimulation . addMote ( newMote ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
2007-08-22 11:23:50 +00:00
} else {
2006-08-21 12:11:16 +00:00
logger . warn ( " No simulation active " ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
/ * *
* Create a new simulation
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param askForConfirmation
* Should we ask for confirmation if a simulation is already active ?
* /
public void doCreateSimulation ( boolean askForConfirmation ) {
2008-11-04 14:32:32 +00:00
/* Remove current simulation */
if ( ! doRemoveSimulation ( askForConfirmation ) ) {
return ;
2006-08-21 12:11:16 +00:00
}
// Create new simulation
2007-01-09 10:27:53 +00:00
Simulation newSim = new Simulation ( this ) ;
2008-02-12 15:20:56 +00:00
boolean createdOK = CreateSimDialog . showDialog ( GUI . getTopParentContainer ( ) , newSim ) ;
2006-08-21 12:11:16 +00:00
if ( createdOK ) {
2009-06-09 09:47:04 +00:00
myGUI . setSimulation ( newSim , true ) ;
2006-08-21 12:11:16 +00:00
}
}
/ * *
* Quit program
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param askForConfirmation
* Should we ask for confirmation before quitting ?
* /
public void doQuit ( boolean askForConfirmation ) {
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
return ;
}
2007-01-09 10:27:53 +00:00
if ( askForConfirmation ) {
String s1 = " Quit " ;
String s2 = " Cancel " ;
2007-01-10 14:57:42 +00:00
Object [ ] options = { s1 , s2 } ;
2008-02-12 15:20:56 +00:00
int n = JOptionPane . showOptionDialog ( GUI . getTopParentContainer ( ) ,
" Sure you want to quit? " ,
2007-01-09 10:27:53 +00:00
" Close COOJA Simulator " , JOptionPane . YES_NO_OPTION ,
JOptionPane . QUESTION_MESSAGE , null , options , s1 ) ;
2007-08-22 11:23:50 +00:00
if ( n ! = JOptionPane . YES_OPTION ) {
2007-01-09 10:27:53 +00:00
return ;
2007-08-22 11:23:50 +00:00
}
2007-01-09 10:27:53 +00:00
}
// Clean up resources
Object [ ] plugins = startedPlugins . toArray ( ) ;
2007-08-22 11:23:50 +00:00
for ( Object plugin : plugins ) {
2007-01-09 10:27:53 +00:00
removePlugin ( ( Plugin ) plugin , false ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2008-10-29 13:31:02 +00:00
/* Store frame size and position */
2008-02-12 15:20:56 +00:00
if ( isVisualizedInFrame ( ) ) {
2008-10-29 13:31:02 +00:00
setExternalToolsSetting ( " FRAME_SCREEN " , frame . getGraphicsConfiguration ( ) . getDevice ( ) . getIDstring ( ) ) ;
2007-03-22 23:01:11 +00:00
setExternalToolsSetting ( " FRAME_POS_X " , " " + frame . getLocationOnScreen ( ) . x ) ;
setExternalToolsSetting ( " FRAME_POS_Y " , " " + frame . getLocationOnScreen ( ) . y ) ;
2008-10-29 13:31:02 +00:00
if ( frame . getExtendedState ( ) = = JFrame . MAXIMIZED_BOTH ) {
setExternalToolsSetting ( " FRAME_WIDTH " , " " + Integer . MAX_VALUE ) ;
setExternalToolsSetting ( " FRAME_HEIGHT " , " " + Integer . MAX_VALUE ) ;
} else {
setExternalToolsSetting ( " FRAME_WIDTH " , " " + frame . getWidth ( ) ) ;
setExternalToolsSetting ( " FRAME_HEIGHT " , " " + frame . getHeight ( ) ) ;
}
2007-03-22 23:01:11 +00:00
}
2008-02-12 15:20:56 +00:00
saveExternalToolsUserSettings ( ) ;
2007-08-22 11:23:50 +00:00
2006-08-21 12:11:16 +00:00
System . exit ( 0 ) ;
}
// // EXTERNAL TOOLS SETTINGS METHODS ////
/ * *
* @return Number of external tools settings
* /
public static int getExternalToolsSettingsCount ( ) {
return externalToolsSettingNames . length ;
}
/ * *
* Get name of external tools setting at given index .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param index
* Setting index
* @return Name
* /
public static String getExternalToolsSettingName ( int index ) {
return externalToolsSettingNames [ index ] ;
}
/ * *
* @param name
* Name of setting
* @return Value
* /
public static String getExternalToolsSetting ( String name ) {
return currentExternalToolsSettings . getProperty ( name ) ;
}
/ * *
* @param name
* Name of setting
* @param defaultValue
* Default value
* @return Value
* /
public static String getExternalToolsSetting ( String name , String defaultValue ) {
return currentExternalToolsSettings . getProperty ( name , defaultValue ) ;
}
2007-03-22 16:41:50 +00:00
/ * *
* @param name
* Name of setting
* @param defaultValue
* Default value
* @return Value
* /
public static String getExternalToolsDefaultSetting ( String name , String defaultValue ) {
return defaultExternalToolsSettings . getProperty ( name , defaultValue ) ;
}
2006-08-21 12:11:16 +00:00
/ * *
* @param name
* Name of setting
* @param newVal
* New value
* /
public static void setExternalToolsSetting ( String name , String newVal ) {
currentExternalToolsSettings . setProperty ( name , newVal ) ;
}
/ * *
* Load external tools settings from default file .
* /
public static void loadExternalToolsDefaultSettings ( ) {
2007-09-30 12:02:33 +00:00
String osName = System . getProperty ( " os.name " ) . toLowerCase ( ) ;
2008-12-16 16:15:36 +00:00
String osArch = System . getProperty ( " os.arch " ) . toLowerCase ( ) ;
2007-09-30 12:02:33 +00:00
2008-12-16 16:15:36 +00:00
String filename = null ;
2007-09-30 12:02:33 +00:00
if ( osName . startsWith ( " win " ) ) {
2006-08-21 12:11:16 +00:00
filename = GUI . EXTERNAL_TOOLS_WIN32_SETTINGS_FILENAME ;
2007-09-30 12:02:33 +00:00
} else if ( osName . startsWith ( " mac os x " ) ) {
filename = GUI . EXTERNAL_TOOLS_MACOSX_SETTINGS_FILENAME ;
2008-12-16 16:15:36 +00:00
} else if ( osName . startsWith ( " linux " ) ) {
filename = GUI . EXTERNAL_TOOLS_LINUX_SETTINGS_FILENAME ;
if ( osArch . startsWith ( " amd64 " ) ) {
filename = GUI . EXTERNAL_TOOLS_LINUX_64_SETTINGS_FILENAME ;
}
} else {
logger . warn ( " Unknown system: " + osName ) ;
logger . warn ( " Using default linux external tools configuration " ) ;
filename = GUI . EXTERNAL_TOOLS_LINUX_SETTINGS_FILENAME ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2007-09-30 12:02:33 +00:00
logger . info ( " Loading external tools user settings from: " + filename ) ;
2006-08-21 12:11:16 +00:00
try {
InputStream in = GUI . class . getResourceAsStream ( filename ) ;
if ( in = = null ) {
throw new FileNotFoundException ( filename + " not found " ) ;
}
Properties settings = new Properties ( ) ;
settings . load ( in ) ;
in . close ( ) ;
currentExternalToolsSettings = settings ;
2007-03-22 16:41:50 +00:00
defaultExternalToolsSettings = ( Properties ) currentExternalToolsSettings . clone ( ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException e ) {
// Error while importing default properties
logger . warn (
" Error when reading external tools settings from " + filename , e ) ;
} finally {
if ( currentExternalToolsSettings = = null ) {
2007-03-22 16:41:50 +00:00
defaultExternalToolsSettings = new Properties ( ) ;
2006-08-21 12:11:16 +00:00
currentExternalToolsSettings = new Properties ( ) ;
}
}
}
/ * *
* Load user values from external properties file
* /
2007-09-10 13:25:36 +00:00
public static void loadExternalToolsUserSettings ( ) {
2008-02-18 08:18:01 +00:00
if ( externalToolsUserSettingsFile = = null ) {
return ;
}
2006-08-21 12:11:16 +00:00
try {
2007-04-03 16:21:12 +00:00
FileInputStream in = new FileInputStream ( externalToolsUserSettingsFile ) ;
2006-08-21 12:11:16 +00:00
Properties settings = new Properties ( ) ;
settings . load ( in ) ;
in . close ( ) ;
Enumeration en = settings . keys ( ) ;
while ( en . hasMoreElements ( ) ) {
String key = ( String ) en . nextElement ( ) ;
setExternalToolsSetting ( key , settings . getProperty ( key ) ) ;
}
} catch ( FileNotFoundException e ) {
// No default configuration file found, using default
} catch ( IOException e ) {
// Error while importing saved properties, using default
2007-04-03 16:21:12 +00:00
logger . warn ( " Error when reading default settings from " + externalToolsUserSettingsFile ) ;
2006-08-21 12:11:16 +00:00
}
}
/ * *
* Save external tools user settings to file .
* /
public static void saveExternalToolsUserSettings ( ) {
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
return ;
}
2007-08-22 11:23:50 +00:00
if ( externalToolsUserSettingsFileReadOnly ) {
return ;
}
2006-08-21 12:11:16 +00:00
try {
2007-04-03 16:21:12 +00:00
FileOutputStream out = new FileOutputStream ( externalToolsUserSettingsFile ) ;
2007-08-22 11:23:50 +00:00
2007-04-04 08:04:48 +00:00
Properties differingSettings = new Properties ( ) ;
Enumeration keyEnum = currentExternalToolsSettings . keys ( ) ;
while ( keyEnum . hasMoreElements ( ) ) {
String key = ( String ) keyEnum . nextElement ( ) ;
String defaultSetting = getExternalToolsDefaultSetting ( key , " " ) ;
String currentSetting = getExternalToolsSetting ( key , " " ) ;
if ( ! defaultSetting . equals ( currentSetting ) ) {
differingSettings . setProperty ( key , currentSetting ) ;
}
}
2007-08-22 11:23:50 +00:00
2007-04-04 08:04:48 +00:00
differingSettings . store ( out , " COOJA External Tools (User specific) " ) ;
2006-08-21 12:11:16 +00:00
out . close ( ) ;
} catch ( FileNotFoundException ex ) {
// Could not open settings file for writing, aborting
2007-01-10 14:57:42 +00:00
logger . warn ( " Could not save external tools user settings to "
2007-04-03 16:21:12 +00:00
+ externalToolsUserSettingsFile + " , aborting " ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException ex ) {
// Could not open settings file for writing, aborting
logger . warn ( " Error while saving external tools user settings to "
2007-04-03 16:21:12 +00:00
+ externalToolsUserSettingsFile + " , aborting " ) ;
2006-08-21 12:11:16 +00:00
}
}
// // GUI EVENT HANDLER ////
private class GUIEventHandler implements ActionListener , WindowListener {
public void windowDeactivated ( WindowEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void windowIconified ( WindowEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void windowDeiconified ( WindowEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void windowOpened ( WindowEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void windowClosed ( WindowEvent e ) {
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
public void windowActivated ( WindowEvent e ) {
}
public void windowClosing ( WindowEvent e ) {
myGUI . doQuit ( true ) ;
}
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
if ( e . getActionCommand ( ) . equals ( " confopen sim " ) ) {
2008-09-29 13:02:15 +00:00
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( true , false , null ) ;
}
} ) . start ( ) ;
2007-03-22 16:17:01 +00:00
} else if ( e . getActionCommand ( ) . equals ( " confopen last sim " ) ) {
2008-09-29 13:02:15 +00:00
final File file = ( File ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " file " ) ;
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( true , false , file ) ;
}
} ) . start ( ) ;
2007-03-22 16:17:01 +00:00
} else if ( e . getActionCommand ( ) . equals ( " open sim " ) ) {
2008-09-29 13:02:15 +00:00
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( true , true , null ) ;
}
} ) . start ( ) ;
2007-03-22 16:17:01 +00:00
} else if ( e . getActionCommand ( ) . equals ( " open last sim " ) ) {
2008-09-29 13:02:15 +00:00
final File file = ( File ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " file " ) ;
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( true , true , file ) ;
}
} ) . start ( ) ;
2006-08-21 12:11:16 +00:00
} else if ( e . getActionCommand ( ) . equals ( " create mote type " ) ) {
myGUI . doCreateMoteType ( ( Class < ? extends MoteType > ) ( ( JMenuItem ) e
. getSource ( ) ) . getClientProperty ( " class " ) ) ;
} else if ( e . getActionCommand ( ) . equals ( " add motes " ) ) {
myGUI . doAddMotes ( ( MoteType ) ( ( JMenuItem ) e . getSource ( ) )
. getClientProperty ( " motetype " ) ) ;
} else if ( e . getActionCommand ( ) . equals ( " edit paths " ) ) {
2008-02-12 15:20:56 +00:00
ExternalToolsDialog . showDialog ( GUI . getTopParentContainer ( ) ) ;
2007-03-23 23:33:54 +00:00
} else if ( e . getActionCommand ( ) . equals ( " manage projects " ) ) {
2008-02-12 15:20:56 +00:00
Vector < File > newProjects = ProjectDirectoriesDialog . showDialog (
GUI . getTopParentContainer ( ) , currentProjectDirs , null ) ;
2007-03-23 23:33:54 +00:00
if ( newProjects ! = null ) {
currentProjectDirs = newProjects ;
2007-09-21 16:14:19 +00:00
try {
reparseProjectConfig ( ) ;
} catch ( ParseProjectsException e2 ) {
logger . fatal ( " Error when loading projects: " + e2 . getMessage ( ) ) ;
e2 . printStackTrace ( ) ;
if ( myGUI . isVisualized ( ) ) {
2008-02-12 15:20:56 +00:00
JOptionPane . showMessageDialog ( GUI . getTopParentContainer ( ) ,
2007-09-21 16:14:19 +00:00
" Error when loading projects. \ nStack trace printed to console. " ,
" Error " , JOptionPane . ERROR_MESSAGE ) ;
}
return ;
}
2006-08-21 12:11:16 +00:00
}
2009-02-20 16:50:16 +00:00
} else if ( e . getActionCommand ( ) . equals ( " configuration wizard " ) ) {
ConfigurationWizard . startWizard ( GUI . getTopParentContainer ( ) , GUI . this ) ;
2007-08-22 11:23:50 +00:00
} else {
2006-08-21 12:11:16 +00:00
logger . warn ( " Unhandled action: " + e . getActionCommand ( ) ) ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
}
}
// // VARIOUS HELP METHODS ////
/ * *
* Help method that tries to load and initialize a class with given name .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param < N >
* Class extending given class type
* @param classType
* Class type
* @param className
* Class name
* @return Class extending given class type or null if not found
* /
public < N extends Object > Class < ? extends N > tryLoadClass (
Object callingObject , Class < N > classType , String className ) {
if ( callingObject ! = null ) {
try {
2009-05-28 12:55:14 +00:00
return callingObject . getClass ( ) . getClassLoader ( ) . loadClass ( className ) . asSubclass ( classType ) ;
2006-08-21 12:11:16 +00:00
} catch ( ClassNotFoundException e ) {
2007-09-18 15:57:14 +00:00
} catch ( UnsupportedClassVersionError e ) {
2006-08-21 12:11:16 +00:00
}
}
try {
return Class . forName ( className ) . asSubclass ( classType ) ;
} catch ( ClassNotFoundException e ) {
2007-09-18 15:57:14 +00:00
} catch ( UnsupportedClassVersionError e ) {
2006-08-21 12:11:16 +00:00
}
2008-02-18 08:18:01 +00:00
if ( ! isVisualizedInApplet ( ) ) {
try {
if ( projectDirClassLoader ! = null ) {
return projectDirClassLoader . loadClass ( className ) . asSubclass (
classType ) ;
}
} catch ( NoClassDefFoundError e ) {
} catch ( ClassNotFoundException e ) {
} catch ( UnsupportedClassVersionError e ) {
2006-08-22 12:25:24 +00:00
}
2006-08-21 12:11:16 +00:00
}
return null ;
}
2007-09-21 16:14:19 +00:00
public ClassLoader createProjectDirClassLoader ( Vector < File > projectsDirs )
throws ParseProjectsException , ClassLoaderCreationException {
2007-03-23 23:33:54 +00:00
if ( projectDirClassLoader = = null ) {
reparseProjectConfig ( ) ;
2006-08-22 12:25:24 +00:00
}
2007-03-23 23:33:54 +00:00
return createClassLoader ( projectDirClassLoader , projectsDirs ) ;
2006-08-22 12:25:24 +00:00
}
2007-09-21 16:14:19 +00:00
private ClassLoader createClassLoader ( Vector < File > currentProjectDirs )
throws ClassLoaderCreationException
{
2007-01-10 14:57:42 +00:00
return createClassLoader ( ClassLoader . getSystemClassLoader ( ) ,
2007-03-23 23:33:54 +00:00
currentProjectDirs ) ;
2006-08-22 12:25:24 +00:00
}
2006-08-21 12:11:16 +00:00
2007-03-23 23:33:54 +00:00
private File findJarFile ( File projectDir , String jarfile ) {
2006-08-22 12:25:24 +00:00
File fp = new File ( jarfile ) ;
if ( ! fp . exists ( ) ) {
2007-03-23 23:33:54 +00:00
fp = new File ( projectDir , jarfile ) ;
2006-08-22 12:25:24 +00:00
}
if ( ! fp . exists ( ) ) {
2007-03-23 23:33:54 +00:00
fp = new File ( projectDir , " java/ " + jarfile ) ;
2006-08-22 12:25:24 +00:00
}
if ( ! fp . exists ( ) ) {
2007-03-23 23:33:54 +00:00
fp = new File ( projectDir , " java/lib/ " + jarfile ) ;
2006-08-22 12:25:24 +00:00
}
if ( ! fp . exists ( ) ) {
2007-03-23 23:33:54 +00:00
fp = new File ( projectDir , " lib/ " + jarfile ) ;
2006-08-22 12:25:24 +00:00
}
return fp . exists ( ) ? fp : null ;
}
private ClassLoader createClassLoader ( ClassLoader parent ,
2007-09-21 16:14:19 +00:00
Vector < File > projectDirs ) throws ClassLoaderCreationException {
2007-03-23 23:33:54 +00:00
if ( projectDirs = = null | | projectDirs . isEmpty ( ) ) {
2006-08-22 12:25:24 +00:00
return parent ;
}
2007-01-10 14:57:42 +00:00
2007-03-23 23:33:54 +00:00
// Combine class loader from all project directories (including any
2006-08-22 12:25:24 +00:00
// specified JAR files)
ArrayList < URL > urls = new ArrayList < URL > ( ) ;
2007-03-23 23:33:54 +00:00
for ( int j = projectDirs . size ( ) - 1 ; j > = 0 ; j - - ) {
File projectDir = projectDirs . get ( j ) ;
2006-08-21 12:11:16 +00:00
try {
2008-02-07 22:25:26 +00:00
urls . add ( ( new File ( projectDir , " java " ) ) . toURI ( ) . toURL ( ) ) ;
2007-01-10 14:57:42 +00:00
2006-08-22 15:28:17 +00:00
// Read configuration to check if any JAR files should be loaded
2007-03-23 23:33:54 +00:00
ProjectConfig projectConfig = new ProjectConfig ( false ) ;
projectConfig . appendProjectDir ( projectDir ) ;
String [ ] projectJarFiles = projectConfig . getStringArrayValue (
2006-08-21 12:11:16 +00:00
GUI . class , " JARFILES " ) ;
2007-03-23 23:33:54 +00:00
if ( projectJarFiles ! = null & & projectJarFiles . length > 0 ) {
for ( String jarfile : projectJarFiles ) {
File jarpath = findJarFile ( projectDir , jarfile ) ;
2006-08-22 15:28:17 +00:00
if ( jarpath = = null ) {
throw new FileNotFoundException ( jarfile ) ;
}
2008-02-07 22:25:26 +00:00
urls . add ( jarpath . toURI ( ) . toURL ( ) ) ;
2006-08-21 12:11:16 +00:00
}
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
} catch ( Exception e ) {
2007-03-23 23:33:54 +00:00
logger . fatal ( " Error when trying to read JAR-file in " + projectDir
2006-08-21 12:11:16 +00:00
+ " : " + e ) ;
2007-09-21 16:14:19 +00:00
throw ( ClassLoaderCreationException ) new ClassLoaderCreationException (
" Error when trying to read JAR-file in " + projectDir ) . initCause ( e ) ;
2006-08-21 12:11:16 +00:00
}
}
2007-01-10 14:57:42 +00:00
2008-02-07 22:25:26 +00:00
URL [ ] urlsArray = urls . toArray ( new URL [ urls . size ( ) ] ) ;
2008-02-12 15:20:56 +00:00
/* TODO Load from webserver if applet */
2008-02-07 22:25:26 +00:00
return new URLClassLoader ( urlsArray , parent ) ;
2006-08-21 12:11:16 +00:00
}
2007-01-10 14:57:42 +00:00
2006-08-21 12:11:16 +00:00
/ * *
* Help method that returns the description for given object . This method
* reads from the object ' s class annotations if existing . Otherwise it returns
* the simple class name of object ' s class .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param object
* Object
* @return Description
* /
public static String getDescriptionOf ( Object object ) {
return getDescriptionOf ( object . getClass ( ) ) ;
}
/ * *
* Help method that returns the description for given class . This method reads
* from class annotations if existing . Otherwise it returns the simple class
* name .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param clazz
* Class
* @return Description
* /
public static String getDescriptionOf ( Class < ? extends Object > clazz ) {
if ( clazz . isAnnotationPresent ( ClassDescription . class ) ) {
return clazz . getAnnotation ( ClassDescription . class ) . value ( ) ;
}
return clazz . getSimpleName ( ) ;
}
2008-02-07 10:30:19 +00:00
/ * *
* Help method that returns the abstraction level description for given mote type class .
*
* @param clazz
* Class
* @return Description
* /
public static String getAbstractionLevelDescriptionOf ( Class < ? extends MoteType > clazz ) {
if ( clazz . isAnnotationPresent ( AbstractionLevelDescription . class ) ) {
return clazz . getAnnotation ( AbstractionLevelDescription . class ) . value ( ) ;
}
return null ;
}
2006-08-21 12:11:16 +00:00
/ * *
* Load configurations and create a GUI .
2007-08-22 11:23:50 +00:00
*
2006-08-21 12:11:16 +00:00
* @param args
* null
* /
public static void main ( String [ ] args ) {
2008-02-18 08:18:01 +00:00
try {
2008-04-02 16:41:46 +00:00
// Configure logger
if ( ( new File ( LOG_CONFIG_FILE ) ) . exists ( ) ) {
DOMConfigurator . configure ( LOG_CONFIG_FILE ) ;
} else {
// Used when starting from jar
DOMConfigurator . configure ( GUI . class . getResource ( " / " + LOG_CONFIG_FILE ) ) ;
}
2006-08-21 12:11:16 +00:00
2008-04-02 16:41:46 +00:00
externalToolsUserSettingsFile = new File ( System . getProperty ( " user.home " ) , EXTERNAL_TOOLS_USER_SETTINGS_FILENAME ) ;
2008-02-18 08:18:01 +00:00
} catch ( AccessControlException e ) {
2008-04-02 16:41:46 +00:00
BasicConfigurator . configure ( ) ;
2008-02-18 08:18:01 +00:00
externalToolsUserSettingsFile = null ;
}
2008-10-29 10:39:04 +00:00
/* Look and Feel: Nimbus */
setLookAndFeel ( ) ;
2007-05-28 08:06:41 +00:00
// Parse general command arguments
2007-08-22 11:23:50 +00:00
for ( String element : args ) {
if ( element . startsWith ( " -contiki= " ) ) {
String arg = element . substring ( " -contiki= " . length ( ) ) ;
2007-04-03 16:21:12 +00:00
GUI . specifiedContikiPath = arg ;
}
2007-05-28 08:06:41 +00:00
2007-08-22 11:23:50 +00:00
if ( element . startsWith ( " -external_tools_config= " ) ) {
String arg = element . substring ( " -external_tools_config= " . length ( ) ) ;
2007-05-28 08:06:41 +00:00
File specifiedExternalToolsConfigFile = new File ( arg ) ;
if ( ! specifiedExternalToolsConfigFile . exists ( ) ) {
logger . fatal ( " Specified external tools configuration not found: " + specifiedExternalToolsConfigFile ) ;
specifiedExternalToolsConfigFile = null ;
System . exit ( 1 ) ;
} else {
GUI . externalToolsUserSettingsFile = specifiedExternalToolsConfigFile ;
2007-08-22 11:23:50 +00:00
GUI . externalToolsUserSettingsFileReadOnly = true ;
2007-05-28 08:06:41 +00:00
}
}
2007-04-03 16:21:12 +00:00
}
2007-08-22 11:23:50 +00:00
2006-09-06 10:05:22 +00:00
// Check if simulator should be quick-started
if ( args . length > 0 & & args [ 0 ] . startsWith ( " -quickstart= " ) ) {
2009-03-11 07:45:54 +00:00
String contikiApp = args [ 0 ] . substring ( " -quickstart= " . length ( ) ) ;
2006-09-06 10:05:22 +00:00
2009-03-12 13:04:10 +00:00
/* Cygwin fix */
if ( contikiApp . startsWith ( " /cygdrive/ " ) ) {
char driveCharacter = contikiApp . charAt ( " /cygdrive/ " . length ( ) ) ;
contikiApp = contikiApp . replace ( " /cygdrive/ " + driveCharacter + " / " , driveCharacter + " :/ " ) ;
}
2009-03-12 15:10:00 +00:00
boolean ok = false ;
if ( contikiApp . endsWith ( " .csc " ) ) {
2009-06-09 09:47:04 +00:00
ok = quickStartSimulationConfig ( new File ( contikiApp ) , true ) ! = null ;
2009-03-12 15:10:00 +00:00
} else {
if ( contikiApp . endsWith ( " .cooja " ) ) {
contikiApp = contikiApp . substring ( 0 , contikiApp . length ( ) - " .cooja " . length ( ) ) ;
}
if ( ! contikiApp . endsWith ( " .c " ) ) {
contikiApp + = " .c " ;
}
ok = quickStartSimulation ( contikiApp ) ;
}
2007-08-22 11:23:50 +00:00
if ( ! ok ) {
2006-09-06 10:05:22 +00:00
System . exit ( 1 ) ;
2007-08-22 11:23:50 +00:00
}
2006-09-06 10:05:22 +00:00
2009-06-09 09:47:04 +00:00
} else if ( args . length > 0 & & args [ 0 ] . startsWith ( " -nogui= " ) ) {
2007-08-22 11:23:50 +00:00
2009-06-09 09:47:04 +00:00
/* Load simulation */
String config = args [ 0 ] . substring ( " -nogui= " . length ( ) ) ;
final File configFile = new File ( config ) ;
Simulation sim = quickStartSimulationConfig ( configFile , false ) ;
if ( sim = = null ) {
System . exit ( 1 ) ;
}
GUI gui = sim . getGUI ( ) ;
/* Make sure at least one test editor is controlling the simulation */
boolean hasEditor = false ;
for ( Plugin startedPlugin : gui . startedPlugins ) {
if ( startedPlugin instanceof ScriptRunner ) {
hasEditor = true ;
break ;
2008-04-22 13:04:43 +00:00
}
}
2009-06-09 09:47:04 +00:00
/ * Backwards compatibility :
* simulation has no test editor , but has external ( old style ) test script .
* We will manually start a test editor from here . * /
if ( ! hasEditor ) {
File scriptFile = new File ( config . substring ( 0 , config . length ( ) - 4 ) + " .js " ) ;
if ( scriptFile . exists ( ) ) {
logger . info ( " Detected old simulation test, starting test editor manually from: " + scriptFile ) ;
2009-06-10 15:57:08 +00:00
ScriptRunner plugin = ( ScriptRunner ) gui . tryStartPlugin ( ScriptRunner . class , gui , sim , null ) ;
if ( plugin = = null ) {
System . exit ( 1 ) ;
}
2009-06-09 09:47:04 +00:00
plugin . updateScript ( scriptFile ) ;
plugin . setScriptActive ( true ) ;
sim . setDelayTime ( 0 ) ;
sim . startSimulation ( ) ;
} else {
logger . fatal ( " No test editor controlling simulation, aborting " ) ;
2008-04-22 13:04:43 +00:00
System . exit ( 1 ) ;
}
}
2009-06-09 09:47:04 +00:00
2008-02-12 15:20:56 +00:00
} else if ( args . length > 0 & & args [ 0 ] . startsWith ( " -applet " ) ) {
2008-04-03 13:59:37 +00:00
String tmpWebPath = null , tmpBuildPath = null , tmpEsbFirmware = null , tmpSkyFirmware = null ;
for ( int i = 1 ; i < args . length ; i + + ) {
if ( args [ i ] . startsWith ( " -web= " ) ) {
tmpWebPath = args [ i ] . substring ( " -web= " . length ( ) ) ;
} else if ( args [ i ] . startsWith ( " -sky_firmware= " ) ) {
tmpSkyFirmware = args [ i ] . substring ( " -sky_firmware= " . length ( ) ) ;
} else if ( args [ i ] . startsWith ( " -esb_firmware= " ) ) {
tmpEsbFirmware = args [ i ] . substring ( " -esb_firmware= " . length ( ) ) ;
} else if ( args [ i ] . startsWith ( " -build= " ) ) {
tmpBuildPath = args [ i ] . substring ( " -build= " . length ( ) ) ;
}
}
2008-02-12 15:20:56 +00:00
// Applet start-up
2008-04-03 13:59:37 +00:00
final String webPath = tmpWebPath , buildPath = tmpBuildPath ;
final String skyFirmware = tmpSkyFirmware , esbFirmware = tmpEsbFirmware ;
2008-02-12 15:20:56 +00:00
javax . swing . SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
JDesktopPane desktop = new JDesktopPane ( ) ;
desktop . setDragMode ( JDesktopPane . OUTLINE_DRAG_MODE ) ;
2008-02-18 08:18:01 +00:00
applet = CoojaApplet . applet ;
2008-02-12 15:20:56 +00:00
GUI gui = new GUI ( desktop ) ;
2008-04-03 13:59:37 +00:00
GUI . setExternalToolsSetting ( " PATH_CONTIKI_BUILD " , buildPath ) ;
GUI . setExternalToolsSetting ( " PATH_CONTIKI_WEB " , webPath ) ;
GUI . setExternalToolsSetting ( " SKY_FIRMWARE " , skyFirmware ) ;
GUI . setExternalToolsSetting ( " ESB_FIRMWARE " , esbFirmware ) ;
2008-02-12 15:20:56 +00:00
configureApplet ( gui , false ) ;
}
} ) ;
2006-09-06 10:05:22 +00:00
} else {
2008-02-12 15:20:56 +00:00
// Frame start-up
2006-09-06 10:05:22 +00:00
javax . swing . SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
2007-05-28 09:01:49 +00:00
JDesktopPane desktop = new JDesktopPane ( ) ;
desktop . setDragMode ( JDesktopPane . OUTLINE_DRAG_MODE ) ;
2009-01-08 15:43:49 +00:00
frame = new JFrame ( " COOJA Simulator " ) ;
2007-05-28 09:01:49 +00:00
GUI gui = new GUI ( desktop ) ;
configureFrame ( gui , false ) ;
2006-09-06 10:05:22 +00:00
}
} ) ;
}
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
/ * *
* Loads a simulation configuration from given file .
2007-08-22 11:23:50 +00:00
*
2007-01-09 10:27:53 +00:00
* When loading Contiki mote types , the libraries must be recompiled . User may
* change mote type settings at this point .
2007-08-22 11:23:50 +00:00
*
2007-01-09 10:27:53 +00:00
* @see # saveSimulationConfig ( File )
* @param file
* File to read
* @return New simulation or null if recompiling failed or aborted
* @throws UnsatisfiedLinkError
* If associated libraries could not be loaded
* /
2007-01-10 14:57:42 +00:00
public Simulation loadSimulationConfig ( File file , boolean quick )
2007-04-02 12:45:19 +00:00
throws UnsatisfiedLinkError , SimulationCreationException {
2009-03-12 15:10:00 +00:00
this . currentConfigFile = file ; /* Used to generate config relative paths */
2007-03-23 11:25:19 +00:00
try {
SAXBuilder builder = new SAXBuilder ( ) ;
Document doc = builder . build ( file ) ;
Element root = doc . getRootElement ( ) ;
2007-01-09 10:27:53 +00:00
2007-03-23 11:25:19 +00:00
return loadSimulationConfig ( root , quick ) ;
} catch ( JDOMException e ) {
logger . fatal ( " Config not wellformed: " + e . getMessage ( ) ) ;
return null ;
} catch ( IOException e ) {
2009-06-09 09:47:04 +00:00
logger . fatal ( " Load simulation error: " + e . getMessage ( ) ) ;
2007-03-23 11:25:19 +00:00
return null ;
}
}
2007-01-09 10:27:53 +00:00
2007-08-22 11:23:50 +00:00
private Simulation loadSimulationConfig ( StringReader stringReader , boolean quick )
2007-04-02 12:45:19 +00:00
throws SimulationCreationException {
2007-01-09 10:27:53 +00:00
try {
SAXBuilder builder = new SAXBuilder ( ) ;
2007-03-23 11:25:19 +00:00
Document doc = builder . build ( stringReader ) ;
2007-01-09 10:27:53 +00:00
Element root = doc . getRootElement ( ) ;
2007-03-23 11:25:19 +00:00
return loadSimulationConfig ( root , quick ) ;
} catch ( JDOMException e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" Configuration file not wellformed: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-03-23 11:25:19 +00:00
} catch ( IOException e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" IO Exception: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-03-23 11:25:19 +00:00
}
}
2007-04-02 12:45:19 +00:00
private Simulation loadSimulationConfig ( Element root , boolean quick )
throws SimulationCreationException {
2007-03-23 11:25:19 +00:00
Simulation newSim = null ;
try {
2007-01-09 10:27:53 +00:00
// Check that config file version is correct
if ( ! root . getName ( ) . equals ( " simconf " ) ) {
logger . fatal ( " Not a valid COOJA simulation config! " ) ;
return null ;
}
2008-12-08 10:26:21 +00:00
/* Verify project directories */
boolean projectsOk = verifyProjects ( root . getChildren ( ) , ! quick ) ;
2008-03-19 09:40:38 +00:00
/* GENERATE UNIQUE MOTE TYPE IDENTIFIERS */
root . detach ( ) ;
String configString = new XMLOutputter ( ) . outputString ( new Document ( root ) ) ;
/* Locate Contiki mote types in config */
Properties moteTypeIDMappings = new Properties ( ) ;
String identifierExtraction = ContikiMoteType . class . getName ( ) + " [ \\ s \\ n]*<identifier>([^<]*)</identifier> " ;
Matcher matcher = Pattern . compile ( identifierExtraction ) . matcher ( configString ) ;
while ( matcher . find ( ) ) {
moteTypeIDMappings . setProperty ( matcher . group ( 1 ) , " " ) ;
}
/* Create old to new identifier mappings */
2008-11-04 14:32:32 +00:00
Enumeration < Object > existingIdentifiers = moteTypeIDMappings . keys ( ) ;
2008-03-19 09:40:38 +00:00
while ( existingIdentifiers . hasMoreElements ( ) ) {
String existingIdentifier = ( String ) existingIdentifiers . nextElement ( ) ;
2009-03-11 07:45:54 +00:00
MoteType [ ] existingMoteTypes = null ;
2008-03-19 09:40:38 +00:00
if ( mySimulation ! = null ) {
existingMoteTypes = mySimulation . getMoteTypes ( ) ;
}
2009-02-25 16:11:59 +00:00
ArrayList < Object > reserved = new ArrayList < Object > ( ) ;
reserved . addAll ( moteTypeIDMappings . keySet ( ) ) ;
reserved . addAll ( moteTypeIDMappings . values ( ) ) ;
String newID = ContikiMoteType . generateUniqueMoteTypeID ( existingMoteTypes , reserved ) ;
2008-03-19 09:40:38 +00:00
moteTypeIDMappings . setProperty ( existingIdentifier , newID ) ;
}
/* Create new config */
existingIdentifiers = moteTypeIDMappings . keys ( ) ;
while ( existingIdentifiers . hasMoreElements ( ) ) {
String existingIdentifier = ( String ) existingIdentifiers . nextElement ( ) ;
configString = configString . replaceAll (
" <identifier> " + existingIdentifier + " </identifier> " ,
" <identifier> " + moteTypeIDMappings . get ( existingIdentifier ) + " </identifier> " ) ;
configString = configString . replaceAll (
" <motetype_identifier> " + existingIdentifier + " </motetype_identifier> " ,
" <motetype_identifier> " + moteTypeIDMappings . get ( existingIdentifier ) + " </motetype_identifier> " ) ;
}
/* Replace existing config */
root = new SAXBuilder ( ) . build ( new StringReader ( configString ) ) . getRootElement ( ) ;
2007-01-09 10:27:53 +00:00
// Create new simulation from config
for ( Object element : root . getChildren ( ) ) {
if ( ( ( Element ) element ) . getName ( ) . equals ( " simulation " ) ) {
Collection < Element > config = ( ( Element ) element ) . getChildren ( ) ;
newSim = new Simulation ( this ) ;
2008-04-22 13:04:43 +00:00
System . gc ( ) ;
2007-01-09 10:27:53 +00:00
boolean createdOK = newSim . setConfigXML ( config , ! quick ) ;
if ( ! createdOK ) {
logger . info ( " Simulation not loaded " ) ;
return null ;
}
}
}
// Restart plugins from config
setPluginsConfigXML ( root . getChildren ( ) , newSim , ! quick ) ;
} catch ( JDOMException e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" Configuration file not wellformed: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-01-09 10:27:53 +00:00
} catch ( IOException e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" No access to configuration file: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-04-02 13:42:05 +00:00
} catch ( MoteTypeCreationException e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" Mote type creation error: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-01-09 10:27:53 +00:00
} catch ( Exception e ) {
2007-05-10 17:05:01 +00:00
throw ( SimulationCreationException ) new SimulationCreationException (
" Unknown error: " + e . getMessage ( ) ) . initCause ( e ) ;
2007-01-09 10:27:53 +00:00
}
return newSim ;
}
/ * *
* Saves current simulation configuration to given file and notifies
* observers .
2007-08-22 11:23:50 +00:00
*
2007-01-10 14:57:42 +00:00
* @see # loadSimulationConfig ( File , boolean )
2007-01-09 10:27:53 +00:00
* @param file
* File to write
* /
public void saveSimulationConfig ( File file ) {
2009-03-12 15:10:00 +00:00
this . currentConfigFile = file ; /* Used to generate config relative paths */
2007-01-09 10:27:53 +00:00
try {
2008-12-08 10:26:21 +00:00
// Create simulation config
2007-01-09 10:27:53 +00:00
Element root = new Element ( " simconf " ) ;
2008-12-08 10:26:21 +00:00
/* Store project directories meta data */
for ( File project : currentProjectDirs ) {
Element projectElement = new Element ( " project " ) ;
projectElement . addContent ( project . getPath ( ) . replaceAll ( " \\ \\ " , " / " ) ) ;
root . addContent ( projectElement ) ;
}
2007-01-09 10:27:53 +00:00
Element simulationElement = new Element ( " simulation " ) ;
simulationElement . addContent ( mySimulation . getConfigXML ( ) ) ;
root . addContent ( simulationElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Create started plugins config
Collection < Element > pluginsConfig = getPluginsConfigXML ( ) ;
2007-08-22 11:23:50 +00:00
if ( pluginsConfig ! = null ) {
2007-01-09 10:27:53 +00:00
root . addContent ( pluginsConfig ) ;
2007-08-22 11:23:50 +00:00
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Create and write to document
Document doc = new Document ( root ) ;
FileOutputStream out = new FileOutputStream ( file ) ;
XMLOutputter outputter = new XMLOutputter ( ) ;
outputter . setFormat ( Format . getPrettyFormat ( ) ) ;
outputter . output ( doc , out ) ;
out . close ( ) ;
logger . info ( " Saved to file: " + file . getAbsolutePath ( ) ) ;
} catch ( Exception e ) {
logger . warn ( " Exception while saving simulation config: " + e ) ;
e . printStackTrace ( ) ;
}
}
/ * *
* Returns started plugins config .
2007-08-22 11:23:50 +00:00
*
2007-01-09 10:27:53 +00:00
* @return Config or null
* /
public Collection < Element > getPluginsConfigXML ( ) {
Vector < Element > config = new Vector < Element > ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Loop through all started plugins
// (Only return config of non-GUI plugins)
Element pluginElement , pluginSubElement ;
2007-01-10 14:57:42 +00:00
for ( Plugin startedPlugin : startedPlugins ) {
2009-05-28 12:55:14 +00:00
int pluginType = startedPlugin . getClass ( ) . getAnnotation ( PluginType . class ) . value ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Ignore GUI plugins
2007-01-10 14:57:42 +00:00
if ( pluginType = = PluginType . COOJA_PLUGIN
2007-08-22 11:23:50 +00:00
| | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
2007-01-09 10:27:53 +00:00
continue ;
2007-08-22 11:23:50 +00:00
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginElement = new Element ( " plugin " ) ;
pluginElement . setText ( startedPlugin . getClass ( ) . getName ( ) ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// Create mote argument config (if mote plugin)
2007-01-10 14:57:42 +00:00
if ( pluginType = = PluginType . MOTE_PLUGIN
& & startedPlugin . getTag ( ) ! = null ) {
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " mote_arg " ) ;
Mote taggedMote = ( Mote ) startedPlugin . getTag ( ) ;
for ( int moteNr = 0 ; moteNr < mySimulation . getMotesCount ( ) ; moteNr + + ) {
if ( mySimulation . getMote ( moteNr ) = = taggedMote ) {
pluginSubElement . setText ( Integer . toString ( moteNr ) ) ;
pluginElement . addContent ( pluginSubElement ) ;
break ;
}
}
}
// Create plugin specific configuration
2008-12-16 15:10:49 +00:00
Collection < Element > pluginXML = startedPlugin . getConfigXML ( ) ;
2007-01-09 10:27:53 +00:00
if ( pluginXML ! = null ) {
pluginSubElement = new Element ( " plugin_config " ) ;
pluginSubElement . addContent ( pluginXML ) ;
pluginElement . addContent ( pluginSubElement ) ;
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
// If plugin is visualizer plugin, create visualization arguments
2008-12-16 15:10:49 +00:00
if ( startedPlugin . getGUI ( ) ! = null ) {
JInternalFrame pluginFrame = startedPlugin . getGUI ( ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " width " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( " " + pluginFrame . getSize ( ) . width ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " z " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( " " + getDesktopPane ( ) . getComponentZOrder ( pluginFrame ) ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " height " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( " " + pluginFrame . getSize ( ) . height ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " location_x " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( " " + pluginFrame . getLocation ( ) . x ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " location_y " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( " " + pluginFrame . getLocation ( ) . y ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " minimized " ) ;
2008-12-16 15:10:49 +00:00
pluginSubElement . setText ( new Boolean ( pluginFrame . isIcon ( ) ) . toString ( ) ) ;
2007-01-09 10:27:53 +00:00
pluginElement . addContent ( pluginSubElement ) ;
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
config . add ( pluginElement ) ;
}
2007-01-10 14:57:42 +00:00
2007-01-09 10:27:53 +00:00
return config ;
}
2008-12-08 10:26:21 +00:00
public boolean verifyProjects ( Collection < Element > configXML , boolean visAvailable ) {
boolean allOk = true ;
/* Match current projects against projects in simulation config */
for ( final Element pluginElement : configXML . toArray ( new Element [ 0 ] ) ) {
if ( pluginElement . getName ( ) . equals ( " project " ) ) {
String project = pluginElement . getText ( ) ;
boolean found = false ;
for ( File currentProject : currentProjectDirs ) {
if ( project . equals ( currentProject . getPath ( ) . replaceAll ( " \\ \\ " , " / " ) ) ) {
found = true ;
break ;
}
}
if ( ! found ) {
logger . warn ( " Loaded simulation may depend on external project: ' " + project + " ' " ) ;
allOk = false ;
}
}
}
return allOk ;
}
2007-01-09 10:27:53 +00:00
/ * *
* Starts plugins with arguments in given config .
2007-08-22 11:23:50 +00:00
*
2007-01-09 10:27:53 +00:00
* @param configXML
* Config XML elements
* @param simulation
* Simulation on which to start plugins
* @return True if all plugins started , false otherwise
* /
public boolean setPluginsConfigXML ( Collection < Element > configXML ,
Simulation simulation , boolean visAvailable ) {
2008-11-04 14:32:32 +00:00
for ( final Element pluginElement : configXML . toArray ( new Element [ 0 ] ) ) {
2007-01-09 10:27:53 +00:00
if ( pluginElement . getName ( ) . equals ( " plugin " ) ) {
// Read plugin class
String pluginClassName = pluginElement . getText ( ) . trim ( ) ;
2009-03-24 15:47:10 +00:00
/* Backwards compatibility: old visualizers were replaced */
if ( pluginClassName . equals ( " se.sics.cooja.plugins.VisUDGM " ) | |
pluginClassName . equals ( " se.sics.cooja.plugins.VisBattery " ) | |
pluginClassName . equals ( " se.sics.cooja.plugins.VisTraffic " ) | |
2009-06-09 09:47:04 +00:00
pluginClassName . equals ( " se.sics.cooja.plugins.VisState " ) | |
2009-03-24 15:47:10 +00:00
pluginClassName . equals ( " se.sics.cooja.plugins.VisUDGM " ) ) {
logger . warn ( " Old simulation config detected: visualizers have been remade " ) ;
pluginClassName = " se.sics.cooja.plugins.Visualizer " ;
}
2008-12-16 15:10:49 +00:00
Class < ? extends Plugin > pluginClass =
tryLoadClass ( this , Plugin . class , pluginClassName ) ;
2008-09-29 13:02:15 +00:00
if ( pluginClass = = null ) {
2007-01-09 10:27:53 +00:00
logger . fatal ( " Could not load plugin class: " + pluginClassName ) ;
return false ;
}
// Parse plugin mote argument (if any)
Mote mote = null ;
2008-11-04 14:32:32 +00:00
for ( Element pluginSubElement : ( List < Element > ) pluginElement . getChildren ( ) ) {
2007-01-09 10:27:53 +00:00
if ( pluginSubElement . getName ( ) . equals ( " mote_arg " ) ) {
int moteNr = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
2007-01-24 18:12:59 +00:00
if ( moteNr > = 0 & & moteNr < simulation . getMotesCount ( ) ) {
2007-01-09 10:27:53 +00:00
mote = simulation . getMote ( moteNr ) ;
2007-01-24 18:12:59 +00:00
}
2007-01-09 10:27:53 +00:00
}
}
2008-12-16 15:10:49 +00:00
/* Start plugin */
2009-06-10 15:57:08 +00:00
final Plugin startedPlugin = tryStartPlugin ( pluginClass , this , simulation , mote ) ;
2008-12-16 15:10:49 +00:00
if ( startedPlugin = = null ) {
continue ;
}
2007-01-09 10:27:53 +00:00
2008-12-16 15:10:49 +00:00
/* Apply plugin specific configuration */
2008-11-04 14:32:32 +00:00
for ( Element pluginSubElement : ( List < Element > ) pluginElement . getChildren ( ) ) {
2007-01-09 10:27:53 +00:00
if ( pluginSubElement . getName ( ) . equals ( " plugin_config " ) ) {
2008-09-29 13:02:15 +00:00
startedPlugin . setConfigXML ( pluginSubElement . getChildren ( ) , visAvailable ) ;
2007-01-09 10:27:53 +00:00
}
}
2008-12-16 15:10:49 +00:00
/* If Cooja not visualized, ignore window configuration */
if ( startedPlugin . getGUI ( ) = = null ) {
continue ;
}
2007-01-09 10:27:53 +00:00
// If plugin is visualizer plugin, parse visualization arguments
2008-12-16 15:10:49 +00:00
new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
Dimension size = new Dimension ( 100 , 100 ) ;
Point location = new Point ( 100 , 100 ) ;
for ( Element pluginSubElement : ( List < Element > ) pluginElement . getChildren ( ) ) {
if ( pluginSubElement . getName ( ) . equals ( " width " ) ) {
size . width = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
startedPlugin . getGUI ( ) . setSize ( size ) ;
} else if ( pluginSubElement . getName ( ) . equals ( " height " ) ) {
size . height = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
startedPlugin . getGUI ( ) . setSize ( size ) ;
} else if ( pluginSubElement . getName ( ) . equals ( " z " ) ) {
int zOrder = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
// Save z order as temporary client property
startedPlugin . getGUI ( ) . putClientProperty ( " zorder " , zOrder ) ;
} else if ( pluginSubElement . getName ( ) . equals ( " location_x " ) ) {
location . x = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
startedPlugin . getGUI ( ) . setLocation ( location ) ;
} else if ( pluginSubElement . getName ( ) . equals ( " location_y " ) ) {
location . y = Integer . parseInt ( pluginSubElement . getText ( ) ) ;
startedPlugin . getGUI ( ) . setLocation ( location ) ;
} else if ( pluginSubElement . getName ( ) . equals ( " minimized " ) ) {
try {
startedPlugin . getGUI ( ) . setIcon ( Boolean . parseBoolean ( pluginSubElement . getText ( ) ) ) ;
} catch ( PropertyVetoException e ) { }
2008-11-04 14:32:32 +00:00
}
2008-12-16 15:10:49 +00:00
}
2008-11-04 14:32:32 +00:00
2008-12-16 15:10:49 +00:00
// For all visualized plugins, check if they have a zorder property
try {
for ( JInternalFrame plugin : getDesktopPane ( ) . getAllFrames ( ) ) {
if ( plugin . getClientProperty ( " zorder " ) ! = null ) {
getDesktopPane ( ) . setComponentZOrder ( plugin ,
( ( Integer ) plugin . getClientProperty ( " zorder " ) ) . intValue ( ) ) ;
plugin . putClientProperty ( " zorder " , null ) ;
2008-11-04 14:32:32 +00:00
}
2007-01-09 10:27:53 +00:00
}
2008-12-16 15:10:49 +00:00
} catch ( Exception e ) { }
2007-01-09 10:27:53 +00:00
2008-12-16 15:10:49 +00:00
return true ;
}
} . invokeAndWait ( ) ;
2008-11-04 14:32:32 +00:00
2007-01-09 10:27:53 +00:00
}
}
return true ;
}
2007-08-22 11:23:50 +00:00
2007-09-21 16:14:19 +00:00
public class ParseProjectsException extends Exception {
public ParseProjectsException ( String message ) {
super ( message ) ;
}
}
public class ClassLoaderCreationException extends Exception {
public ClassLoaderCreationException ( String message ) {
super ( message ) ;
}
}
public class SimulationCreationException extends Exception {
2007-04-02 12:45:19 +00:00
public SimulationCreationException ( String message ) {
super ( message ) ;
}
}
2007-05-10 17:05:01 +00:00
2009-06-10 15:57:08 +00:00
public class PluginConstructionException extends Exception {
public PluginConstructionException ( String message ) {
super ( message ) ;
}
}
2007-05-11 10:55:07 +00:00
/ * *
2009-03-21 14:24:55 +00:00
* A simple error dialog with compilation output and stack trace .
2007-08-22 11:23:50 +00:00
*
2007-05-11 10:55:07 +00:00
* @param parentComponent
* Parent component
* @param title
* Title of error window
* @param exception
* Exception causing window to be shown
* @param retryAvailable
2008-11-04 14:32:32 +00:00
* If true , a retry option is presented
* @return Retry failed operation
2007-05-11 10:55:07 +00:00
* /
2008-11-04 14:32:32 +00:00
public static boolean showErrorDialog ( final Component parentComponent ,
final String title , final Throwable exception , final boolean retryAvailable ) {
return new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
2009-03-21 14:24:55 +00:00
JTabbedPane tabbedPane = new JTabbedPane ( ) ;
final JDialog errorDialog ;
if ( parentComponent instanceof Dialog ) {
errorDialog = new JDialog ( ( Dialog ) parentComponent , title , true ) ;
} else if ( parentComponent instanceof Frame ) {
errorDialog = new JDialog ( ( Frame ) parentComponent , title , true ) ;
} else {
errorDialog = new JDialog ( ( Frame ) null , title ) ;
}
Box buttonBox = Box . createHorizontalBox ( ) ;
if ( exception ! = null ) {
/* Compilation output */
MessageList compilationOutput = null ;
if ( exception instanceof MoteTypeCreationException
& & ( ( MoteTypeCreationException ) exception ) . hasCompilationOutput ( ) ) {
compilationOutput = ( ( MoteTypeCreationException ) exception ) . getCompilationOutput ( ) ;
} else if ( exception . getCause ( ) ! = null
& & exception . getCause ( ) instanceof MoteTypeCreationException
& & ( ( MoteTypeCreationException ) exception . getCause ( ) ) . hasCompilationOutput ( ) ) {
compilationOutput = ( ( MoteTypeCreationException ) exception . getCause ( ) ) . getCompilationOutput ( ) ;
2007-05-10 17:05:01 +00:00
}
2009-03-21 14:24:55 +00:00
if ( compilationOutput ! = null ) {
compilationOutput . addPopupMenuItem ( null , true ) ;
tabbedPane . addTab ( " Compilation output " , null , new JScrollPane ( compilationOutput ) , null ) ;
2007-05-10 17:05:01 +00:00
}
2007-05-11 10:55:07 +00:00
2009-03-21 14:24:55 +00:00
/* Stack trace */
MessageList stackTrace = new MessageList ( ) ;
PrintStream printStream = stackTrace . getInputStream ( MessageList . NORMAL ) ;
exception . printStackTrace ( printStream ) ;
stackTrace . addPopupMenuItem ( null , true ) ;
tabbedPane . addTab ( " Java stack trace " , null , new JScrollPane ( stackTrace ) , null ) ;
/* Exception message */
buttonBox . add ( Box . createHorizontalStrut ( 10 ) ) ;
buttonBox . add ( new JLabel ( exception . getMessage ( ) ) ) ;
buttonBox . add ( Box . createHorizontalStrut ( 10 ) ) ;
2007-05-10 17:05:01 +00:00
}
2009-03-21 14:24:55 +00:00
buttonBox . add ( Box . createHorizontalGlue ( ) ) ;
if ( retryAvailable ) {
Action retryAction = new AbstractAction ( ) {
public void actionPerformed ( ActionEvent e ) {
errorDialog . setTitle ( " -RETRY- " ) ;
errorDialog . dispose ( ) ;
}
} ;
JButton retryButton = new JButton ( retryAction ) ;
retryButton . setText ( " Retry Ctrl+R " ) ;
buttonBox . add ( retryButton ) ;
InputMap inputMap = errorDialog . getRootPane ( ) . getInputMap (
JComponent . WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ) ;
inputMap . put ( KeyStroke . getKeyStroke ( KeyEvent . VK_R , KeyEvent . CTRL_DOWN_MASK , false ) , " retry " ) ;
errorDialog . getRootPane ( ) . getActionMap ( ) . put ( " retry " , retryAction ) ;
2007-05-11 10:55:07 +00:00
}
2009-03-21 14:24:55 +00:00
AbstractAction closeAction = new AbstractAction ( ) {
public void actionPerformed ( ActionEvent e ) {
errorDialog . dispose ( ) ;
}
} ;
2007-05-10 17:05:01 +00:00
2009-03-21 14:24:55 +00:00
JButton closeButton = new JButton ( closeAction ) ;
closeButton . setText ( " Close " ) ;
buttonBox . add ( closeButton ) ;
2007-08-22 11:23:50 +00:00
2009-03-21 14:24:55 +00:00
InputMap inputMap = errorDialog . getRootPane ( ) . getInputMap (
JComponent . WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ) ;
inputMap . put ( KeyStroke . getKeyStroke ( KeyEvent . VK_ESCAPE , 0 , false ) , " close " ) ;
errorDialog . getRootPane ( ) . getActionMap ( ) . put ( " close " , closeAction ) ;
2007-05-11 10:55:07 +00:00
2009-03-21 14:24:55 +00:00
errorDialog . getRootPane ( ) . setDefaultButton ( closeButton ) ;
errorDialog . getContentPane ( ) . add ( BorderLayout . CENTER , tabbedPane ) ;
errorDialog . getContentPane ( ) . add ( BorderLayout . SOUTH , buttonBox ) ;
errorDialog . setSize ( 700 , 500 ) ;
errorDialog . setLocationRelativeTo ( parentComponent ) ;
errorDialog . setVisible ( true ) ; /* BLOCKS */
if ( errorDialog . getTitle ( ) . equals ( " -RETRY- " ) ) {
return true ;
}
return false ;
2008-11-04 14:32:32 +00:00
}
} . invokeAndWait ( ) ;
}
/ * *
* Runs work method in event dispatcher thread .
* Worker method returns a value .
*
2009-02-25 16:11:59 +00:00
* @author Fredrik Osterlind
2008-11-04 14:32:32 +00:00
* /
public static abstract class RunnableInEDT < T > {
private T val ;
/ * *
* Work method to be implemented .
*
* @return Return value
* /
public abstract T work ( ) ;
/ * *
* Runs worker method in event dispatcher thread .
*
* @see # work ( )
* @return Worker method return value
* /
public T invokeAndWait ( ) {
if ( java . awt . EventQueue . isDispatchThread ( ) ) {
return RunnableInEDT . this . work ( ) ;
}
try {
java . awt . EventQueue . invokeAndWait ( new Runnable ( ) {
public void run ( ) {
val = RunnableInEDT . this . work ( ) ;
}
} ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
} catch ( InvocationTargetException e ) {
e . printStackTrace ( ) ;
}
return val ;
}
2007-05-10 17:05:01 +00:00
}
2007-01-09 10:27:53 +00:00
2007-05-30 10:51:14 +00:00
/ * *
* This method can be used by various different modules in the simulator to
* indicate for example that a mote has been selected . All mote highlight
* listeners will be notified . An example application of mote highlightinh is
* a simulator visualizer that highlights the mote .
2007-08-22 11:23:50 +00:00
*
2008-02-12 15:31:22 +00:00
* @see # addMoteHighlightObserver ( Observer )
2007-05-30 10:51:14 +00:00
* @param m
* Mote to highlight
* /
public void signalMoteHighlight ( Mote m ) {
2009-02-26 13:35:45 +00:00
moteHighlightObservable . setChangedAndNotify ( m ) ;
}
/ * *
* Adds directed relation between given motes .
*
* @param source Source mote
* @param dest Destination mote
* /
public void addMoteRelation ( Mote source , Mote dest ) {
if ( source = = null | | dest = = null ) {
return ;
}
removeMoteRelation ( source , dest ) ; /* Unique relations */
moteRelations . add ( new MoteRelation ( source , dest ) ) ;
moteRelationObservable . setChangedAndNotify ( ) ;
}
/ * *
* Removes the relations between given motes .
*
* @param source Source mote
* @param dest Destination mote
* /
public void removeMoteRelation ( Mote source , Mote dest ) {
if ( source = = null | | dest = = null ) {
return ;
}
MoteRelation [ ] arr = getMoteRelations ( ) ;
for ( MoteRelation r : arr ) {
if ( r . source = = source & & r . dest = = dest ) {
moteRelations . remove ( r ) ;
}
}
moteRelationObservable . setChangedAndNotify ( ) ;
}
/ * *
* @return All current mote relations .
*
* @see # addMoteRelationsObserver ( Observer )
* /
public MoteRelation [ ] getMoteRelations ( ) {
MoteRelation [ ] arr = new MoteRelation [ moteRelations . size ( ) ] ;
moteRelations . toArray ( arr ) ;
return arr ;
}
/ * *
* Adds mote relation observer .
* Typically used by visualizer plugins .
*
* @param newObserver Observer
* /
public void addMoteRelationsObserver ( Observer newObserver ) {
moteRelationObservable . addObserver ( newObserver ) ;
}
/ * *
* Removes mote relation observer .
* Typically used by visualizer plugins .
*
* @param observer Observer
* /
public void deleteMoteRelationsObserver ( Observer observer ) {
moteRelationObservable . deleteObserver ( observer ) ;
2007-05-30 10:51:14 +00:00
}
2008-09-18 14:04:13 +00:00
2009-03-12 15:10:00 +00:00
public File createPortablePath ( File file ) {
2008-09-18 14:04:13 +00:00
try {
2009-03-11 19:19:39 +00:00
File contikiPath = new File ( GUI . getExternalToolsSetting ( " PATH_CONTIKI " , null ) ) ;
String contikiRelative = contikiPath . getPath ( ) ;
String contikiCanonical = contikiPath . getCanonicalPath ( ) ;
String fileCanonical = file . getCanonicalPath ( ) ;
if ( ! fileCanonical . startsWith ( contikiCanonical ) ) {
2009-03-12 15:10:00 +00:00
/*logger.warn("Error when converting to Contiki relative path: file is not in Contiki: " + file.getAbsolutePath());*/
return createConfigPath ( file ) ;
2008-09-18 14:04:13 +00:00
}
2009-03-11 19:19:39 +00:00
/* Replace Contiki's canonical path with Contiki's relative path */
2009-06-15 18:13:45 +00:00
String newFilePath = fileCanonical . replaceFirst (
java . util . regex . Matcher . quoteReplacement ( contikiCanonical ) ,
java . util . regex . Matcher . quoteReplacement ( contikiRelative ) ) ;
2009-03-11 19:19:39 +00:00
File newFile = new File ( newFilePath ) ;
if ( ! newFile . exists ( ) ) {
2009-03-12 15:10:00 +00:00
/*logger.warn("Error when converting to Contiki relative path: new file does not exist: " + newFile.getAbsolutePath());*/
return createConfigPath ( file ) ;
}
logger . info ( " Generated Contiki relative path ' " + file . getPath ( ) + " ' to ' " + newFile . getPath ( ) + " ' " ) ;
return newFile ;
} catch ( IOException e1 ) {
/*logger.warn("Error when converting to Contiki relative path: " + e1.getMessage());*/
}
return createConfigPath ( file ) ;
}
public File restorePortablePath ( File file ) {
return restoreConfigPath ( file ) ;
}
2009-03-22 13:47:38 +00:00
public File currentConfigFile = null ; /* Used to generate config relative paths */
2009-03-12 15:10:00 +00:00
public File createConfigPath ( File file ) {
if ( currentConfigFile = = null ) {
return file ;
}
try {
File configPath = currentConfigFile . getParentFile ( ) ;
String configIdentifier = " [CONFIG_DIR] " ;
2009-03-22 13:47:38 +00:00
if ( configPath = = null ) {
return file ;
}
2009-03-12 15:10:00 +00:00
String configCanonical = configPath . getCanonicalPath ( ) ;
String fileCanonical = file . getCanonicalPath ( ) ;
if ( ! fileCanonical . startsWith ( configCanonical ) ) {
2009-03-17 09:16:36 +00:00
/* SPECIAL CASE: Allow one parent directory */
configCanonical = configPath . getParentFile ( ) . getCanonicalPath ( ) ;
configIdentifier + = " /.. " ;
if ( ! fileCanonical . startsWith ( configCanonical ) ) {
/*logger.warn("Error when converting to config relative path: file not in config directory: " + file.getAbsolutePath());*/
return file ;
}
2008-09-18 14:04:13 +00:00
}
2009-03-12 15:10:00 +00:00
/* Replace config's canonical path with config identifier */
2009-06-15 18:13:45 +00:00
String newFilePath = fileCanonical . replaceFirst (
java . util . regex . Matcher . quoteReplacement ( configCanonical ) ,
java . util . regex . Matcher . quoteReplacement ( configIdentifier ) ) ;
2009-03-12 15:10:00 +00:00
File newFile = new File ( newFilePath ) ;
2009-06-15 18:13:45 +00:00
/*logger.info("Generated config relative path: '" + file.getPath() + "' to '" + newFile.getPath() + "'");*/
/* Verify that new file exists */
File tmpFile = restorePortablePath ( newFile ) ;
if ( ! tmpFile . exists ( ) ) {
/*logger.warn("Failed generating config relative path, using absolute path: " + file);*/
return file ;
}
2009-03-11 19:19:39 +00:00
return newFile ;
2008-09-18 14:04:13 +00:00
2009-03-11 19:19:39 +00:00
} catch ( IOException e1 ) {
2009-03-12 15:10:00 +00:00
/*logger.warn("Error when converting to config relative path: " + e1.getMessage());*/
2008-09-18 14:04:13 +00:00
}
2009-03-11 19:19:39 +00:00
return file ;
2008-09-18 14:04:13 +00:00
}
2009-03-11 20:14:52 +00:00
2009-03-12 15:10:00 +00:00
public File restoreConfigPath ( File file ) {
if ( currentConfigFile = = null ) {
return file ;
}
File configPath = currentConfigFile . getParentFile ( ) ;
2009-03-22 13:47:38 +00:00
if ( configPath = = null ) {
return file ;
}
2009-03-12 15:10:00 +00:00
String path = file . getPath ( ) ;
if ( ! path . startsWith ( " [CONFIG_DIR] " ) ) {
/*logger.info("Not config relative path: " + file.getAbsolutePath());*/
return file ;
}
File newFile = new File ( path . replace ( " [CONFIG_DIR] " , configPath . getAbsolutePath ( ) ) ) ;
2009-06-15 18:13:45 +00:00
/*logger.info("Reverted config relative path: '" + path + "' to '" + newFile.getPath() + "'");*/
2009-03-12 15:10:00 +00:00
return newFile ;
}
2009-03-11 20:14:52 +00:00
private static JProgressBar PROGRESS_BAR = null ;
public static void setProgressMessage ( String msg ) {
if ( PROGRESS_BAR ! = null & & PROGRESS_BAR . isShowing ( ) ) {
PROGRESS_BAR . setString ( msg ) ;
PROGRESS_BAR . setStringPainted ( true ) ;
}
}
2009-05-28 12:55:14 +00:00
/* GUI actions */
2009-05-28 14:53:26 +00:00
abstract class GUIAction extends AbstractAction {
public GUIAction ( String name ) {
super ( name ) ;
}
public GUIAction ( String name , int nmenomic ) {
this ( name ) ;
putValue ( Action . MNEMONIC_KEY , nmenomic ) ;
}
public GUIAction ( String name , KeyStroke accelerator ) {
this ( name ) ;
putValue ( Action . ACCELERATOR_KEY , accelerator ) ;
}
public GUIAction ( String name , int nmenomic , KeyStroke accelerator ) {
this ( name , nmenomic ) ;
putValue ( Action . ACCELERATOR_KEY , accelerator ) ;
}
public abstract boolean shouldBeEnabled ( ) ;
}
GUIAction newSimulationAction = new GUIAction ( " New simulation " , KeyEvent . VK_N , KeyStroke . getKeyStroke ( KeyEvent . VK_N , ActionEvent . CTRL_MASK ) ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
myGUI . doCreateSimulation ( true ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
return true ;
}
2009-05-28 12:55:14 +00:00
} ;
2009-05-28 14:53:26 +00:00
GUIAction closeSimulationAction = new GUIAction ( " Close simulation " , KeyEvent . VK_C ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
myGUI . doRemoveSimulation ( true ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
return getSimulation ( ) ! = null ;
}
} ;
2009-05-28 14:53:26 +00:00
GUIAction reloadSimulationAction = new GUIAction ( " keep random seed " , KeyEvent . VK_K , KeyStroke . getKeyStroke ( KeyEvent . VK_R , ActionEvent . CTRL_MASK ) ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
if ( getSimulation ( ) = = null ) {
/* Reload last opened simulation */
final File file = getLastOpenedFile ( ) ;
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( true , true , file ) ;
}
} ) . start ( ) ;
return ;
}
/* Reload current simulation */
long seed = getSimulation ( ) . getRandomSeed ( ) ;
reloadCurrentSimulation ( getSimulation ( ) . isRunning ( ) , seed ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
return true ;
}
2009-05-28 12:55:14 +00:00
} ;
2009-05-28 14:53:26 +00:00
GUIAction reloadRandomSimulationAction = new GUIAction ( " new random seed " , KeyEvent . VK_N , KeyStroke . getKeyStroke ( KeyEvent . VK_R , ActionEvent . CTRL_MASK | ActionEvent . SHIFT_MASK ) ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
/* Replace seed before reloading */
getSimulation ( ) . setRandomSeed ( getSimulation ( ) . getRandomSeed ( ) + 1 ) ;
reloadSimulationAction . actionPerformed ( null ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
return getSimulation ( ) ! = null ;
2009-05-28 12:55:14 +00:00
}
} ;
2009-05-28 14:53:26 +00:00
GUIAction saveSimulationAction = new GUIAction ( " Save simulation " , KeyEvent . VK_S ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
myGUI . doSaveConfig ( true ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
if ( isVisualizedInApplet ( ) ) {
return false ;
}
return getSimulation ( ) ! = null ;
}
} ;
2009-05-28 14:53:26 +00:00
GUIAction closePluginsAction = new GUIAction ( " Close all plugins " ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
Object [ ] plugins = startedPlugins . toArray ( ) ;
for ( Object plugin : plugins ) {
removePlugin ( ( Plugin ) plugin , false ) ;
}
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
return ! startedPlugins . isEmpty ( ) ;
}
} ;
2009-05-28 14:53:26 +00:00
GUIAction exitCoojaAction = new GUIAction ( " Exit " , KeyEvent . VK_X , KeyStroke . getKeyStroke ( KeyEvent . VK_X , ActionEvent . CTRL_MASK ) ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
myGUI . doQuit ( true ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
if ( isVisualizedInApplet ( ) ) {
return false ;
}
return true ;
}
} ;
2009-05-28 14:53:26 +00:00
GUIAction startStopSimulationAction = new GUIAction ( " Start/Stop simulation " , KeyStroke . getKeyStroke ( KeyEvent . VK_S , ActionEvent . CTRL_MASK ) ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
/* Start/Stop current simulation */
2009-05-28 14:53:26 +00:00
Simulation s = getSimulation ( ) ;
if ( s = = null ) {
2009-05-28 12:55:14 +00:00
return ;
}
2009-05-28 14:53:26 +00:00
if ( s . isRunning ( ) ) {
s . stopSimulation ( ) ;
2009-05-28 12:55:14 +00:00
} else {
2009-05-28 14:53:26 +00:00
s . startSimulation ( ) ;
2009-05-28 12:55:14 +00:00
}
}
public void setEnabled ( boolean newValue ) {
if ( getSimulation ( ) = = null ) {
putValue ( NAME , " Start/Stop simulation " ) ;
} else if ( getSimulation ( ) . isRunning ( ) ) {
putValue ( NAME , " Stop simulation " ) ;
} else {
putValue ( NAME , " Start simulation " ) ;
}
super . setEnabled ( newValue ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
return getSimulation ( ) ! = null ;
}
} ;
2009-05-28 14:53:26 +00:00
class StartPluginGUIAction extends GUIAction {
public StartPluginGUIAction ( String name ) {
super ( name ) ;
}
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
Class < Plugin > pluginClass =
( Class < Plugin > ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " class " ) ;
Mote mote = ( Mote ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " mote " ) ;
2009-06-10 15:57:08 +00:00
tryStartPlugin ( pluginClass , myGUI , mySimulation , mote ) ;
2009-05-28 12:55:14 +00:00
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2009-05-28 12:55:14 +00:00
return getSimulation ( ) ! = null ;
}
2009-05-28 14:53:26 +00:00
}
GUIAction removeAllMotesAction = new GUIAction ( " Remove all motes " ) {
2009-05-28 12:55:14 +00:00
public void actionPerformed ( ActionEvent e ) {
2009-05-28 14:53:26 +00:00
Simulation s = getSimulation ( ) ;
if ( s . isRunning ( ) ) {
s . stopSimulation ( ) ;
2009-05-28 12:55:14 +00:00
}
2009-05-28 14:53:26 +00:00
while ( s . getMotesCount ( ) > 0 ) {
s . removeMote ( getSimulation ( ) . getMote ( 0 ) ) ;
2009-05-28 12:55:14 +00:00
}
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
Simulation s = getSimulation ( ) ;
return s ! = null & & s . getMotesCount ( ) > 0 ;
2009-05-28 12:55:14 +00:00
}
} ;
2006-08-21 12:11:16 +00:00
}