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
*
2006-08-21 12:11:16 +00:00
* /
package se.sics.cooja ;
2008-12-08 10:26:21 +00:00
import java.awt.BorderLayout ;
2009-06-30 12:45:51 +00:00
import java.awt.Color ;
2008-12-08 10:26:21 +00:00
import java.awt.Component ;
import java.awt.Container ;
import java.awt.Dialog ;
2012-06-04 16:14:05 +02:00
import java.awt.Dialog.ModalityType ;
2008-12-08 10:26:21 +00:00
import java.awt.Dimension ;
import java.awt.Frame ;
import java.awt.GraphicsDevice ;
import java.awt.GraphicsEnvironment ;
2012-06-05 17:03:07 +02:00
import java.awt.GridLayout ;
2008-12-08 10:26:21 +00:00
import java.awt.Point ;
import java.awt.Rectangle ;
import java.awt.Window ;
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListener ;
2009-06-30 12:45:51 +00:00
import java.awt.event.ComponentAdapter ;
import java.awt.event.ComponentEvent ;
2008-12-08 10:26:21 +00:00
import java.awt.event.KeyEvent ;
2009-06-30 12:45:51 +00:00
import java.awt.event.WindowAdapter ;
2008-12-08 10:26:21 +00:00
import java.awt.event.WindowEvent ;
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 ;
2009-06-30 12:45:51 +00:00
import java.io.FileReader ;
2008-12-08 10:26:21 +00:00
import java.io.IOException ;
import java.io.InputStream ;
2010-12-10 15:54:52 +00:00
import java.io.OutputStream ;
2008-12-08 10:26:21 +00:00
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 ;
2010-02-23 22:53:34 +00:00
import java.text.DecimalFormat ;
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 ;
2010-12-10 15:54:52 +00:00
import java.util.zip.GZIPInputStream ;
import java.util.zip.GZIPOutputStream ;
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 ;
2009-06-30 12:45:51 +00:00
import javax.swing.DefaultDesktopManager ;
2008-12-08 10:26:21 +00:00
import javax.swing.InputMap ;
import javax.swing.JApplet ;
import javax.swing.JButton ;
2009-11-13 14:25:43 +00:00
import javax.swing.JCheckBox ;
2009-06-30 12:45:51 +00:00
import javax.swing.JCheckBoxMenuItem ;
2008-12-08 10:26:21 +00:00
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 ;
2009-06-30 12:45:51 +00:00
import javax.swing.JTextPane ;
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 ;
2012-06-04 13:30:33 +02:00
import javax.swing.UIManager.LookAndFeelInfo ;
2012-06-04 16:14:05 +02:00
import javax.swing.UnsupportedLookAndFeelException ;
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-07-03 13:37:40 +00:00
import se.sics.cooja.dialogs.BufferSettings ;
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 ;
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 ;
2009-10-29 10:16:05 +00:00
import se.sics.cooja.util.ExecuteJAR ;
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
*
2012-05-31 18:01:53 +02:00
* This class loads external Java classes ( in extension 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 {
2010-12-02 15:29:07 +00:00
private static JFrame frame = null ;
private static JApplet applet = null ;
private static final long serialVersionUID = 1L ;
private static Logger logger = Logger . getLogger ( GUI . class ) ;
2007-01-10 14:57:42 +00:00
2012-06-01 11:17:54 +02:00
/ * *
* External tools configuration .
* /
public static final String EXTERNAL_TOOLS_SETTINGS_FILENAME = " /external_tools.config " ;
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 " ;
2009-08-27 12:25:11 +00:00
/ * *
* External tools default FreeBSD settings filename .
* /
public static final String EXTERNAL_TOOLS_FREEBSD_SETTINGS_FILENAME = " /external_tools_freebsd.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 .
2009-06-30 12:45:51 +00:00
* Tested on Intel 64 - bit Gentoo Linux .
2008-12-16 16:15:36 +00:00
* /
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 " ;
/ * *
2012-05-31 18:01:53 +02:00
* Default extension 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
/ * *
2012-05-31 18:01:53 +02:00
* User extension 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
}
2010-12-10 15:54:52 +00:00
if ( file . getName ( ) . endsWith ( " .csc.gz " ) ) {
return true ;
}
2006-08-21 12:11:16 +00:00
return false ;
}
public String getDescription ( ) {
2012-05-31 18:01:53 +02:00
return " Cooja simulation (.csc, .csc.gz) " ;
2006-08-21 12:11:16 +00:00
}
public String toString ( ) {
return " .csc " ;
}
} ;
// External tools setting names
2009-10-29 10:16:05 +00:00
public static Properties defaultExternalToolsSettings ;
public 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 " ,
2012-03-09 14:57:21 +01:00
" PATH_OBJCOPY " ,
2009-05-28 12:55:14 +00:00
" PATH_JAVAC " ,
" CONTIKI_STANDARD_PROCESSES " ,
" CMD_GREP_PROCESSES " , " REGEXP_PARSE_PROCESSES " ,
" CMD_GREP_INTERFACES " , " REGEXP_PARSE_INTERFACES " ,
" CMD_GREP_SENSORS " , " REGEXP_PARSE_SENSORS " ,
" DEFAULT_PROJECTDIRS " ,
" CORECOMM_TEMPLATE_FILENAME " ,
2010-01-20 13:27:02 +00:00
" PARSE_WITH_COMMAND " ,
2009-05-28 12:55:14 +00:00
" MAPFILE_DATA_START " , " MAPFILE_DATA_SIZE " ,
" MAPFILE_BSS_START " , " MAPFILE_BSS_SIZE " ,
2010-01-20 13:27:02 +00:00
" MAPFILE_COMMON_START " , " MAPFILE_COMMON_SIZE " ,
2009-05-28 12:55:14 +00:00
" MAPFILE_VAR_NAME " ,
" MAPFILE_VAR_ADDRESS_1 " , " MAPFILE_VAR_ADDRESS_2 " ,
" MAPFILE_VAR_SIZE_1 " , " MAPFILE_VAR_SIZE_2 " ,
" PARSE_COMMAND " ,
" COMMAND_VAR_NAME_ADDRESS " ,
" COMMAND_DATA_START " , " COMMAND_DATA_END " ,
" COMMAND_BSS_START " , " COMMAND_BSS_END " ,
2010-01-20 13:27:02 +00:00
" COMMAND_COMMON_START " , " COMMAND_COMMON_END " ,
2012-03-23 15:14:24 +01:00
2009-11-13 14:25:43 +00:00
" HIDE_WARNINGS "
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 ;
2012-06-04 13:30:33 +02:00
private static final String WINDOW_TITLE = " Cooja: The Contiki Network Simulator " ;
2012-05-31 18:01:53 +02:00
2006-08-21 12:11:16 +00:00
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
2012-06-05 17:03:07 +02:00
private JMenu menuMoteTypeClasses , menuMoteTypes ;
2007-01-10 14:57:42 +00:00
2010-12-10 15:54:52 +00:00
private JMenu menuOpenSimulation ;
2009-05-27 23:23:41 +00:00
private boolean hasFileHistoryChanged ;
2007-03-22 13:59:33 +00:00
2012-06-05 17:03:07 +02:00
private Vector < Class < ? extends Plugin > > menuMotePluginClasses = new Vector < Class < ? extends Plugin > > ( ) ;
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 > ( ) ;
2012-03-23 15:14:24 +01: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
2010-12-02 15:29:07 +00:00
private ArrayList < COOJAProject > currentProjects = new ArrayList < COOJAProject > ( ) ;
2007-01-10 14:57:42 +00:00
2009-11-25 20:47:18 +00:00
public 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
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 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 ( ) ;
2009-06-30 12:45:51 +00:00
private JTextPane quickHelpTextPane ;
private JScrollPane quickHelpScroll ;
private Properties quickHelpProperties = null ; /* quickhelp.txt */
2009-02-26 13:35:45 +00:00
/ * *
* Mote relation ( directed ) .
* /
public static class MoteRelation {
public Mote source ;
public Mote dest ;
2010-12-10 17:50:48 +00:00
public Color color ;
public MoteRelation ( Mote source , Mote dest , Color color ) {
2009-02-26 13:35:45 +00:00
this . source = source ;
this . dest = dest ;
2010-12-10 17:50:48 +00:00
this . color = color ;
2009-02-26 13:35:45 +00:00
}
}
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 ;
2006-08-21 12:11:16 +00:00
2009-06-30 12:45:51 +00:00
/* Help panel */
quickHelpTextPane = new JTextPane ( ) ;
quickHelpTextPane . setContentType ( " text/html " ) ;
quickHelpTextPane . setEditable ( false ) ;
quickHelpTextPane . setVisible ( false ) ;
quickHelpScroll = new JScrollPane ( quickHelpTextPane , JScrollPane . VERTICAL_SCROLLBAR_AS_NEEDED , JScrollPane . HORIZONTAL_SCROLLBAR_NEVER ) ;
quickHelpScroll . setPreferredSize ( new Dimension ( 200 , 0 ) ) ;
quickHelpScroll . setBorder ( BorderFactory . createCompoundBorder (
2012-03-23 15:14:24 +01:00
BorderFactory . createLineBorder ( Color . GRAY ) ,
2009-06-30 12:45:51 +00:00
BorderFactory . createEmptyBorder ( 0 , 3 , 0 , 0 )
) ) ;
quickHelpScroll . setVisible ( false ) ;
2012-06-01 10:49:56 +02:00
loadQuickHelp ( " GETTING_STARTED " ) ;
2012-03-23 15:14:24 +01:00
2007-03-22 13:59:33 +00:00
// Load default and overwrite with user settings (if any)
loadExternalToolsDefaultSettings ( ) ;
loadExternalToolsUserSettings ( ) ;
2007-08-22 11:23:50 +00:00
2012-06-01 10:49:56 +02:00
final boolean showQuickhelp = getExternalToolsSetting ( " SHOW_QUICKHELP " , " true " ) . equalsIgnoreCase ( " true " ) ;
if ( showQuickhelp ) {
SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
JCheckBoxMenuItem checkBox = ( ( JCheckBoxMenuItem ) showQuickHelpAction . getValue ( " checkbox " ) ) ;
if ( checkBox = = null ) {
return ;
}
if ( checkBox . isSelected ( ) ) {
return ;
}
checkBox . doClick ( ) ;
}
} ) ;
}
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 ) ;
}
} ) ; * /
2012-05-31 18:01:53 +02:00
// Register default extension 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 ) {
2009-10-28 12:07:37 +00:00
File projectDir = restorePortablePath ( new File ( p ) ) ;
2010-12-02 15:29:07 +00:00
currentProjects . add ( new COOJAProject ( projectDir ) ) ;
2006-12-01 14:12:50 +00:00
}
2009-10-29 10:16:05 +00:00
}
2007-01-10 14:57:42 +00:00
2012-05-31 18:01:53 +02:00
/* Parse current extension configuration */
2009-10-29 10:16:05 +00:00
try {
reparseProjectConfig ( ) ;
} catch ( ParseProjectsException e ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Error when loading extensions: " + e . getMessage ( ) , e ) ;
2009-10-29 10:16:05 +00:00
if ( isVisualized ( ) ) {
2010-12-02 15:29:07 +00:00
JOptionPane . showMessageDialog ( GUI . getTopParentContainer ( ) ,
2012-05-31 18:01:53 +02:00
" All Cooja extensions could not load. \ n \ n " +
" To manage Cooja extensions: \ n " +
" Menu->Settings->Cooja extensions " ,
" Reconfigure Cooja extensions " , JOptionPane . INFORMATION_MESSAGE ) ;
showErrorDialog ( getTopParentContainer ( ) , " Cooja extensions load error " , e , false ) ;
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 ) ;
}
/ * *
2009-06-30 12:45:51 +00:00
* Delete 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 ) {
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 ( ) ;
2010-12-10 15:54:52 +00:00
updateOpenHistoryMenuItems ( openFilesHistory ) ;
2009-05-27 23:23:41 +00:00
}
2007-08-22 11:23:50 +00:00
2010-12-10 15:54:52 +00:00
private void populateMenuWithHistory ( JMenu menu , final boolean quick , File [ ] openFilesHistory ) {
2009-05-27 23:23:41 +00:00
JMenuItem lastItem ;
2010-12-10 15:54:52 +00:00
int index = 0 ;
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 ( ) ) ;
}
2010-12-10 15:54:52 +00:00
final File f = file ;
lastItem . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
doLoadConfigAsync ( true , quick , f ) ;
}
} ) ;
2007-03-22 13:59:33 +00:00
lastItem . putClientProperty ( " file " , file ) ;
lastItem . setToolTipText ( file . getAbsolutePath ( ) ) ;
2009-05-27 23:23:41 +00:00
menu . add ( lastItem ) ;
2007-03-22 13:59:33 +00:00
}
}
2012-03-23 15:14:24 +01:00
2010-12-10 15:54:52 +00:00
private void doLoadConfigAsync ( final boolean ask , final boolean quick , final File file ) {
new Thread ( new Runnable ( ) {
public void run ( ) {
myGUI . doLoadConfig ( ask , quick , file ) ;
}
} ) . start ( ) ;
}
private void updateOpenHistoryMenuItems ( File [ ] openFilesHistory ) {
menuOpenSimulation . removeAll ( ) ;
/* Reconfigure submenu */
JMenu reconfigureMenu = new JMenu ( " Open and Reconfigure " ) ;
JMenuItem browseItem2 = new JMenuItem ( " Browse... " ) ;
browseItem2 . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
doLoadConfigAsync ( true , false , null ) ;
}
} ) ;
reconfigureMenu . add ( browseItem2 ) ;
reconfigureMenu . add ( new JSeparator ( ) ) ;
populateMenuWithHistory ( reconfigureMenu , false , openFilesHistory ) ;
/* Open menu */
JMenuItem browseItem = new JMenuItem ( " Browse... " ) ;
browseItem . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
doLoadConfigAsync ( true , true , null ) ;
}
} ) ;
menuOpenSimulation . add ( browseItem ) ;
menuOpenSimulation . add ( new JSeparator ( ) ) ;
menuOpenSimulation . add ( reconfigureMenu ) ;
menuOpenSimulation . add ( new JSeparator ( ) ) ;
populateMenuWithHistory ( menuOpenSimulation , true , openFilesHistory ) ;
}
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
}
2012-03-23 15:14:24 +01: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
}
2012-03-23 15:14:24 +01:00
2006-08-21 12:11:16 +00:00
private JMenuBar createMenuBar ( ) {
2012-06-04 16:14:05 +02:00
2006-08-21 12:11:16 +00:00
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 ) ;
2012-05-31 18:01:53 +02:00
/* guiActions.add(closePluginsAction);*/
2009-10-29 10:16:05 +00:00
guiActions . add ( exportExecutableJARAction ) ;
2009-05-28 12:55:14 +00:00
guiActions . add ( exitCoojaAction ) ;
guiActions . add ( startStopSimulationAction ) ;
guiActions . add ( removeAllMotesAction ) ;
2009-07-03 13:37:40 +00:00
guiActions . add ( showBufferSettingsAction ) ;
2012-03-23 15:14:24 +01:00
2012-06-04 13:30:33 +02:00
/* Menus */
JMenuBar menuBar = new JMenuBar ( ) ;
JMenu fileMenu = new JMenu ( " File " ) ;
JMenu simulationMenu = new JMenu ( " Simulation " ) ;
JMenu motesMenu = new JMenu ( " Motes " ) ;
2012-06-05 17:03:07 +02:00
final JMenu toolsMenu = new JMenu ( " Tools " ) ;
2012-06-04 13:30:33 +02:00
JMenu settingsMenu = new JMenu ( " Settings " ) ;
JMenu helpMenu = new JMenu ( " Help " ) ;
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
menuBar . add ( fileMenu ) ;
menuBar . add ( simulationMenu ) ;
menuBar . add ( motesMenu ) ;
menuBar . add ( toolsMenu ) ;
menuBar . add ( settingsMenu ) ;
menuBar . add ( helpMenu ) ;
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
fileMenu . setMnemonic ( KeyEvent . VK_F ) ;
simulationMenu . setMnemonic ( KeyEvent . VK_S ) ;
motesMenu . setMnemonic ( KeyEvent . VK_M ) ;
toolsMenu . setMnemonic ( KeyEvent . VK_T ) ;
helpMenu . setMnemonic ( KeyEvent . VK_H ) ;
2012-06-04 16:14:05 +02:00
2009-05-28 12:55:14 +00:00
/* File menu */
2012-06-04 13:30:33 +02:00
fileMenu . addMenuListener ( new MenuListener ( ) {
2007-03-22 13:59:33 +00:00
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 ) {
}
} ) ;
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
fileMenu . add ( new JMenuItem ( newSimulationAction ) ) ;
2006-08-21 12:11:16 +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 ) ;
2012-06-04 13:30:33 +02:00
fileMenu . 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
2012-06-04 13:30:33 +02:00
fileMenu . add ( new JMenuItem ( closeSimulationAction ) ) ;
2012-05-31 18:01:53 +02:00
2009-05-27 23:23:41 +00:00
hasFileHistoryChanged = true ;
2007-01-09 10:27:53 +00:00
2012-06-04 13:30:33 +02:00
fileMenu . add ( new JMenuItem ( saveSimulationAction ) ) ;
2007-01-09 10:27:53 +00:00
2012-06-04 13:30:33 +02:00
fileMenu . add ( new JMenuItem ( exportExecutableJARAction ) ) ;
2012-05-31 18:01:53 +02:00
/* menu.addSeparator();*/
/* menu.add(new JMenuItem(closePluginsAction));*/
2012-06-04 13:30:33 +02:00
fileMenu . addSeparator ( ) ;
2007-01-09 10:27:53 +00:00
2012-06-04 13:30:33 +02:00
fileMenu . add ( new JMenuItem ( exitCoojaAction ) ) ;
2006-08-21 12:11:16 +00:00
2009-05-28 12:55:14 +00:00
/* Simulation menu */
2012-06-04 13:30:33 +02:00
simulationMenu . addMenuListener ( new MenuListener ( ) {
2009-05-28 12:55:14 +00:00
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
2009-03-21 16:45:42 +00:00
}
} ) ;
2012-03-23 15:14:24 +01:00
2012-06-04 13:30:33 +02:00
simulationMenu . add ( new JMenuItem ( startStopSimulationAction ) ) ;
JMenuItem reloadSimulationMenuItem = new JMenu ( " Reload simulation " ) ;
reloadSimulationMenuItem . add ( new JMenuItem ( reloadSimulationAction ) ) ;
reloadSimulationMenuItem . add ( new JMenuItem ( reloadRandomSimulationAction ) ) ;
simulationMenu . add ( reloadSimulationMenuItem ) ;
2009-03-21 16:45:42 +00:00
2012-05-31 18:01:53 +02:00
GUIAction guiAction = new StartPluginGUIAction ( " Control panel... " ) ;
2009-05-28 14:53:26 +00:00
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 ) ;
2012-06-04 13:30:33 +02:00
simulationMenu . add ( menuItem ) ;
2006-08-21 12:11:16 +00:00
2012-05-31 18:01:53 +02:00
guiAction = new StartPluginGUIAction ( " Simulation... " ) ;
2009-05-28 14:53:26 +00:00
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 ) ;
2012-06-04 13:30:33 +02:00
simulationMenu . add ( menuItem ) ;
2006-08-21 12:11:16 +00:00
// Mote type menu
2012-06-04 13:30:33 +02:00
motesMenu . addMenuListener ( new MenuListener ( ) {
2009-05-28 12:55:14 +00:00
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
// Mote type classes sub menu
2012-06-04 13:30:33 +02:00
menuMoteTypeClasses = new JMenu ( " Create new mote type " ) ;
2006-08-21 12:11:16 +00:00
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 ) ;
2012-06-11 15:31:39 +02:00
menuItem = new JMenuItem ( description + " ... " ) ;
2006-08-21 12:11:16 +00:00
menuItem . setActionCommand ( " create mote type " ) ;
menuItem . putClientProperty ( " class " , moteTypeClass ) ;
2012-06-04 13:30:33 +02: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 ) {
}
} ) ;
2012-06-04 16:14:05 +02:00
2006-08-21 12:11:16 +00:00
// Mote menu
2012-06-04 13:30:33 +02:00
motesMenu . addMenuListener ( new MenuListener ( ) {
2009-05-28 12:55:14 +00:00
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2012-06-04 16:14:05 +02:00
2006-08-21 12:11:16 +00:00
// Mote types sub menu
2012-06-04 13:30:33 +02:00
menuMoteTypes = new JMenu ( " Add motes " ) ;
2006-08-21 12:11:16 +00:00
menuMoteTypes . setMnemonic ( KeyEvent . VK_A ) ;
menuMoteTypes . addMenuListener ( new MenuListener ( ) {
public void menuSelected ( MenuEvent e ) {
// Clear menu
menuMoteTypes . removeAll ( ) ;
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
if ( mySimulation ! = null ) {
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
// Recreate menu items
JMenuItem menuItem ;
2006-08-21 12:11:16 +00:00
2012-06-04 13:30:33 +02:00
for ( MoteType moteType : mySimulation . getMoteTypes ( ) ) {
menuItem = new JMenuItem ( moteType . getDescription ( ) ) ;
menuItem . setActionCommand ( " add motes " ) ;
menuItem . setToolTipText ( getDescriptionOf ( moteType . getClass ( ) ) ) ;
menuItem . putClientProperty ( " motetype " , moteType ) ;
menuItem . addActionListener ( guiEventHandler ) ;
menuMoteTypes . add ( menuItem ) ;
}
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
if ( mySimulation . getMoteTypes ( ) . length > 0 ) {
menuMoteTypes . add ( new JSeparator ( ) ) ;
}
2006-08-21 12:11:16 +00:00
}
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
menuMoteTypes . add ( menuMoteTypeClasses ) ;
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 ) {
}
} ) ;
2012-06-04 13:30:33 +02:00
motesMenu . add ( menuMoteTypes ) ;
2006-08-21 12:11:16 +00:00
2012-06-04 13:30:33 +02:00
guiAction = new StartPluginGUIAction ( " Mote types... " ) ;
menuItem = new JMenuItem ( guiAction ) ;
guiActions . add ( guiAction ) ;
menuItem . putClientProperty ( " class " , MoteTypeInformation . class ) ;
2012-05-31 18:01:53 +02:00
2012-06-04 13:30:33 +02:00
motesMenu . add ( menuItem ) ;
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
motesMenu . add ( new JMenuItem ( removeAllMotesAction ) ) ;
2009-02-18 17:25:14 +00:00
2012-06-05 17:03:07 +02:00
/* Tools menu */
2012-06-04 13:30:33 +02:00
toolsMenu . addMenuListener ( new MenuListener ( ) {
2012-06-05 17:03:07 +02:00
private ActionListener menuItemListener = new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
Object pluginClass = ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " class " ) ;
Object mote = ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " mote " ) ;
tryStartPlugin ( ( Class < ? extends Plugin > ) pluginClass , myGUI , getSimulation ( ) , ( Mote ) mote ) ;
}
} ;
private JMenuItem createMenuItem ( Class < ? extends Plugin > newPluginClass , int pluginType ) {
String description = getDescriptionOf ( newPluginClass ) ;
JMenuItem menuItem = new JMenuItem ( description + " ... " ) ;
menuItem . putClientProperty ( " class " , newPluginClass ) ;
menuItem . addActionListener ( menuItemListener ) ;
String tooltip = " <html><pre> " ;
if ( pluginType = = PluginType . COOJA_PLUGIN | | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
tooltip + = " Cooja plugin: " ;
} else if ( pluginType = = PluginType . SIM_PLUGIN | | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
tooltip + = " Simulation plugin: " ;
if ( getSimulation ( ) = = null ) {
menuItem . setEnabled ( false ) ;
2012-05-24 14:02:45 +02:00
}
2012-06-05 17:03:07 +02:00
} else if ( pluginType = = PluginType . MOTE_PLUGIN ) {
tooltip + = " Mote plugin: " ;
}
tooltip + = description + " ( " + newPluginClass . getName ( ) + " ) " ;
/* Check if simulation plugin depends on any particular radio medium */
if ( pluginType = = PluginType . SIM_PLUGIN | | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
if ( newPluginClass . getAnnotation ( SupportedArguments . class ) ! = null ) {
boolean active = false ;
Class < ? extends RadioMedium > [ ] radioMediums = newPluginClass . getAnnotation ( SupportedArguments . class ) . radioMediums ( ) ;
for ( Class < ? extends Object > o : radioMediums ) {
if ( o . isAssignableFrom ( getSimulation ( ) . getRadioMedium ( ) . getClass ( ) ) ) {
active = true ;
break ;
}
}
if ( ! active ) {
menuItem . setVisible ( false ) ;
}
2012-05-24 14:02:45 +02:00
}
2012-06-05 17:03:07 +02:00
}
/* Check if plugin was imported by a extension directory */
File project =
getProjectConfig ( ) . getUserProjectDefining ( GUI . class , " PLUGINS " , newPluginClass . getName ( ) ) ;
if ( project ! = null ) {
tooltip + = " \ nLoaded by extension: " + project . getPath ( ) ;
}
tooltip + = " </html> " ;
/*menuItem.setToolTipText(tooltip);*/
return menuItem ;
}
2012-05-24 14:02:45 +02:00
2012-06-05 17:03:07 +02:00
public void menuSelected ( MenuEvent e ) {
/* Populate tools menu */
toolsMenu . removeAll ( ) ;
/* Cooja plugins */
boolean hasCoojaPlugins = false ;
for ( Class < ? extends Plugin > pluginClass : pluginClasses ) {
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
if ( pluginType ! = PluginType . COOJA_PLUGIN & & pluginType ! = PluginType . COOJA_STANDARD_PLUGIN ) {
2012-05-24 14:02:45 +02:00
continue ;
}
2012-06-05 17:03:07 +02:00
toolsMenu . add ( createMenuItem ( pluginClass , pluginType ) ) ;
hasCoojaPlugins = true ;
}
/* Simulation plugins */
boolean hasSimPlugins = false ;
for ( Class < ? extends Plugin > pluginClass : pluginClasses ) {
if ( pluginClass . equals ( SimControl . class ) ) {
continue ; /* ignore */
}
if ( pluginClass . equals ( SimInformation . class ) ) {
continue ; /* ignore */
2012-05-24 14:02:45 +02:00
}
2012-06-05 17:03:07 +02:00
if ( pluginClass . equals ( MoteTypeInformation . class ) ) {
continue ; /* ignore */
}
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
2012-05-24 14:02:45 +02:00
if ( pluginType ! = PluginType . SIM_PLUGIN & & pluginType ! = PluginType . SIM_STANDARD_PLUGIN ) {
continue ;
}
2012-06-05 17:03:07 +02:00
if ( hasCoojaPlugins ) {
hasCoojaPlugins = false ;
toolsMenu . addSeparator ( ) ;
}
toolsMenu . add ( createMenuItem ( pluginClass , pluginType ) ) ;
hasSimPlugins = true ;
}
for ( Class < ? extends Plugin > pluginClass : pluginClasses ) {
int pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
if ( pluginType ! = PluginType . MOTE_PLUGIN ) {
2012-05-24 14:02:45 +02:00
continue ;
}
2012-06-05 17:03:07 +02:00
if ( hasSimPlugins ) {
hasSimPlugins = false ;
toolsMenu . addSeparator ( ) ;
2012-05-24 14:02:45 +02:00
}
2012-06-05 17:03:07 +02:00
toolsMenu . add ( createMotePluginsSubmenu ( pluginClass ) ) ;
2012-05-24 14:02:45 +02:00
}
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
// Settings menu
2012-06-04 13:30:33 +02:00
settingsMenu . addMenuListener ( new MenuListener ( ) {
2009-05-28 12:55:14 +00:00
public void menuSelected ( MenuEvent e ) {
updateGUIComponentState ( ) ;
}
public void menuDeselected ( MenuEvent e ) {
}
public void menuCanceled ( MenuEvent e ) {
}
} ) ;
2006-08-21 12:11:16 +00:00
2012-05-31 18:01:53 +02:00
menuItem = new JMenuItem ( " External tools paths... " ) ;
2006-08-21 12:11:16 +00:00
menuItem . setActionCommand ( " edit paths " ) ;
menuItem . addActionListener ( guiEventHandler ) ;
2012-06-04 13:30:33 +02:00
settingsMenu . 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
2012-05-31 18:01:53 +02:00
menuItem = new JMenuItem ( " Cooja extensions... " ) ;
menuItem . setActionCommand ( " manage extensions " ) ;
2006-08-21 12:11:16 +00:00
menuItem . addActionListener ( guiEventHandler ) ;
2012-06-04 13:30:33 +02:00
settingsMenu . add ( menuItem ) ;
2008-02-18 08:18:01 +00:00
if ( isVisualizedInApplet ( ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2012-03-23 15:14:24 +01:00
2012-05-31 18:01:53 +02:00
menuItem = new JMenuItem ( " Cooja mote configuration wizard... " ) ;
2009-02-20 16:50:16 +00:00
menuItem . setActionCommand ( " configuration wizard " ) ;
menuItem . addActionListener ( guiEventHandler ) ;
2012-06-04 13:30:33 +02:00
settingsMenu . add ( menuItem ) ;
2009-02-20 16:50:16 +00:00
if ( isVisualizedInApplet ( ) ) {
menuItem . setEnabled ( false ) ;
menuItem . setToolTipText ( " Not available in applet version " ) ;
}
2012-06-04 13:30:33 +02:00
settingsMenu . add ( new JMenuItem ( showBufferSettingsAction ) ) ;
2012-03-23 15:14:24 +01:00
2012-06-04 16:14:05 +02:00
/* Help */
2012-06-04 13:30:33 +02:00
helpMenu . add ( new JMenuItem ( showGettingStartedAction ) ) ;
helpMenu . add ( new JMenuItem ( showKeyboardShortcutsAction ) ) ;
2009-06-30 12:45:51 +00:00
JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem ( showQuickHelpAction ) ;
showQuickHelpAction . putValue ( " checkbox " , checkBox ) ;
2012-06-04 13:30:33 +02:00
helpMenu . add ( checkBox ) ;
2009-06-30 12:45:51 +00:00
2012-06-04 13:30:33 +02:00
helpMenu . addSeparator ( ) ;
2012-03-09 14:57:21 +01:00
menuItem = new JMenuItem ( " Java version: "
+ System . getProperty ( " java.version " ) + " ( "
+ System . getProperty ( " java.vendor " ) + " ) " ) ;
menuItem . setEnabled ( false ) ;
2012-06-04 13:30:33 +02:00
helpMenu . add ( menuItem ) ;
2012-05-31 18:01:53 +02:00
menuItem = new JMenuItem ( " System \" os.arch \" : "
2012-03-09 14:57:21 +01:00
+ System . getProperty ( " os.arch " ) ) ;
menuItem . setEnabled ( false ) ;
2012-06-04 13:30:33 +02:00
helpMenu . add ( menuItem ) ;
2012-05-31 18:01:53 +02:00
menuItem = new JMenuItem ( " System \" sun.arch.data.model \" : "
2012-03-09 14:57:21 +01:00
+ System . getProperty ( " sun.arch.data.model " ) ) ;
menuItem . setEnabled ( false ) ;
2012-06-04 13:30:33 +02:00
helpMenu . add ( menuItem ) ;
2012-03-23 15:14:24 +01: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
2009-01-08 15:43:49 +00:00
if ( frame = = null ) {
2012-05-31 18:01:53 +02:00
frame = new JFrame ( WINDOW_TITLE ) ;
2009-01-08 15:43:49 +00:00
}
2006-08-21 12:11:16 +00:00
frame . setDefaultCloseOperation ( JFrame . DO_NOTHING_ON_CLOSE ) ;
2009-06-30 12:45:51 +00:00
/* Menu bar */
2007-05-28 09:01:49 +00:00
frame . setJMenuBar ( gui . createMenuBar ( ) ) ;
2007-01-09 10:27:53 +00:00
2009-06-30 12:45:51 +00:00
/* Scrollable desktop */
JComponent desktop = gui . getDesktopPane ( ) ;
desktop . setOpaque ( true ) ;
JScrollPane scroll = new JScrollPane ( desktop ) ;
scroll . setBorder ( null ) ;
JPanel container = new JPanel ( new BorderLayout ( ) ) ;
container . add ( BorderLayout . CENTER , scroll ) ;
container . add ( BorderLayout . EAST , gui . quickHelpScroll ) ;
frame . setContentPane ( container ) ;
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 ) ;
2009-06-30 12:45:51 +00:00
frame . addWindowListener ( new WindowAdapter ( ) {
public void windowClosing ( WindowEvent e ) {
gui . doQuit ( true ) ;
}
} ) ;
frame . addComponentListener ( new ComponentAdapter ( ) {
public void componentResized ( ComponentEvent e ) {
updateDesktopSize ( gui . getDesktopPane ( ) ) ;
}
} ) ;
2007-01-09 10:27:53 +00:00
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 ;
}
2009-10-29 10:16:05 +00:00
public static void setLookAndFeel ( ) {
2008-10-29 10:39:04 +00:00
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 ) ;
2012-06-04 16:14:05 +02: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 " ) ) {
2012-06-04 13:30:33 +02:00
try {
for ( LookAndFeelInfo info : UIManager . getInstalledLookAndFeels ( ) ) {
if ( " Nimbus " . equals ( info . getName ( ) ) ) {
UIManager . setLookAndFeel ( info . getClassName ( ) ) ;
break ;
}
}
2012-06-04 16:14:05 +02:00
2012-06-04 13:30:33 +02:00
} catch ( UnsupportedLookAndFeelException e ) {
UIManager . setLookAndFeel ( UIManager . getCrossPlatformLookAndFeelClassName ( ) ) ;
2012-06-04 16:14:05 +02:00
}
2009-02-08 18:33:05 +00:00
} 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 ) {
}
2009-06-30 12:45:51 +00:00
}
private static void updateDesktopSize ( final JDesktopPane desktop ) {
if ( desktop = = null | | ! desktop . isVisible ( ) | | desktop . getParent ( ) = = null ) {
return ;
}
2008-11-21 13:09:53 +00:00
2009-06-30 12:45:51 +00:00
Rectangle rect = desktop . getVisibleRect ( ) ;
Dimension pref = new Dimension ( rect . width - 1 , rect . height - 1 ) ;
for ( JInternalFrame frame : desktop . getAllFrames ( ) ) {
if ( pref . width < frame . getX ( ) + frame . getWidth ( ) - 20 ) {
pref . width = frame . getX ( ) + frame . getWidth ( ) ;
}
if ( pref . height < frame . getY ( ) + frame . getHeight ( ) - 20 ) {
pref . height = frame . getY ( ) + frame . getHeight ( ) ;
}
}
desktop . setPreferredSize ( pref ) ;
desktop . revalidate ( ) ;
}
private static JDesktopPane createDesktopPane ( ) {
final JDesktopPane desktop = new JDesktopPane ( ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 8272040875621119329L ;
public void setBounds ( int x , int y , int w , int h ) {
2009-06-30 12:45:51 +00:00
super . setBounds ( x , y , w , h ) ;
updateDesktopSize ( this ) ;
}
public void remove ( Component c ) {
super . remove ( c ) ;
updateDesktopSize ( this ) ;
}
public Component add ( Component comp ) {
Component c = super . add ( comp ) ;
updateDesktopSize ( this ) ;
return c ;
}
} ;
desktop . setDesktopManager ( new DefaultDesktopManager ( ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 5987404936292377152L ;
public void endResizingFrame ( JComponent f ) {
2009-06-30 12:45:51 +00:00
super . endResizingFrame ( f ) ;
updateDesktopSize ( desktop ) ;
}
public void endDraggingFrame ( JComponent f ) {
super . endDraggingFrame ( f ) ;
updateDesktopSize ( desktop ) ;
}
} ) ;
desktop . setDragMode ( JDesktopPane . OUTLINE_DRAG_MODE ) ;
return desktop ;
2008-10-29 10:39:04 +00:00
}
2009-10-29 10:16:05 +00:00
public static Simulation quickStartSimulationConfig ( File config , boolean vis ) {
2012-05-31 18:01:53 +02:00
logger . info ( " > Starting Cooja " ) ;
2009-06-30 12:45:51 +00:00
JDesktopPane desktop = createDesktopPane ( ) ;
2009-06-09 09:47:04 +00:00
if ( vis ) {
2012-05-31 18:01:53 +02:00
frame = new JFrame ( WINDOW_TITLE ) ;
2009-06-09 09:47:04 +00:00
}
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 ) {
2012-05-31 18:01:53 +02:00
logger . info ( " > Starting Cooja " ) ;
2009-06-30 12:45:51 +00:00
JDesktopPane desktop = createDesktopPane ( ) ;
2012-05-31 18:01:53 +02:00
frame = new JFrame ( WINDOW_TITLE ) ;
2009-03-11 07:45:54 +00:00
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 ) ) ;
2012-06-04 13:30:33 +02:00
moteType . setDescription ( " Cooja mote type ( " + source + " ) " ) ;
2009-03-11 07:45:54 +00:00
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 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 ;
}
/ * *
2012-05-31 18:01:53 +02:00
* Builds new extension configuration using current extension directories settings .
2010-12-02 15:29:07 +00:00
* Reregisters mote types , plugins , positioners and radio
2006-08-21 12:11:16 +00:00
* mediums . This method may still return true even if all classes could not be
2012-05-31 18:01:53 +02:00
* registered , but always returns false if all extension directory configuration
2006-08-21 12:11:16 +00:00
* files were not parsed correctly .
* /
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 " ;
}
}
2010-12-02 15:29:07 +00:00
/* Remove current dependencies */
2006-08-21 12:11:16 +00:00
unregisterMoteTypes ( ) ;
unregisterPlugins ( ) ;
unregisterPositioners ( ) ;
unregisterRadioMediums ( ) ;
2010-12-02 15:29:07 +00:00
projectDirClassLoader = null ;
2012-03-23 15:14:24 +01:00
2010-12-02 15:29:07 +00:00
/* Build cooja configuration */
2006-08-21 12:11:16 +00:00
try {
2007-03-23 23:33:54 +00:00
projectConfig = new ProjectConfig ( true ) ;
2006-08-22 15:28:17 +00:00
} catch ( FileNotFoundException e ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Could not find default extension config file: " + PROJECT_DEFAULT_CONFIG_FILENAME ) ;
2007-09-21 16:14:19 +00:00
throw ( ParseProjectsException ) new ParseProjectsException (
2012-05-31 18:01:53 +02:00
" Could not find default extension config file: " + PROJECT_DEFAULT_CONFIG_FILENAME ) . initCause ( e ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException e ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Error when reading default extension config file: " + PROJECT_DEFAULT_CONFIG_FILENAME ) ;
2007-09-21 16:14:19 +00:00
throw ( ParseProjectsException ) new ParseProjectsException (
2012-05-31 18:01:53 +02:00
" Error when reading default extension 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 ( ) ) {
2010-12-02 15:29:07 +00:00
for ( COOJAProject project : currentProjects ) {
2008-02-18 08:18:01 +00:00
try {
2010-12-02 15:29:07 +00:00
projectConfig . appendProjectDir ( project . dir ) ;
2008-02-18 08:18:01 +00:00
} catch ( FileNotFoundException e ) {
throw ( ParseProjectsException ) new ParseProjectsException (
2012-05-31 18:01:53 +02:00
" Error when loading extension: " + e . getMessage ( ) ) . initCause ( e ) ;
2008-02-18 08:18:01 +00:00
} catch ( IOException e ) {
throw ( ParseProjectsException ) new ParseProjectsException (
2012-05-31 18:01:53 +02:00
" Error when reading extension config: " + e . getMessage ( ) ) . initCause ( e ) ;
2008-02-18 08:18:01 +00:00
}
}
2012-03-23 15:14:24 +01:00
2012-05-31 18:01:53 +02:00
/* Create extension class loader */
2006-08-21 12:11:16 +00:00
try {
2010-12-02 15:29:07 +00:00
projectDirClassLoader = createClassLoader ( currentProjects ) ;
2008-02-18 08:18:01 +00:00
} 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
}
}
// 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
2012-06-05 17:03:07 +02:00
registerPlugin ( SimControl . class ) ;
registerPlugin ( SimInformation . class ) ;
registerPlugin ( MoteTypeInformation . class ) ;
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 ) ;
}
}
}
// 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 ) ;
}
}
}
}
/ * *
2012-05-31 18:01:53 +02:00
* Returns the current extension configuration common to the entire simulator .
2007-08-22 11:23:50 +00:00
*
2012-05-31 18:01:53 +02:00
* @return Current extension 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
}
/ * *
2012-05-31 18:01:53 +02:00
* Returns the current extension directories common to the entire simulator .
2007-08-22 11:23:50 +00:00
*
2012-05-31 18:01:53 +02:00
* @return Current extension directories .
2006-08-21 12:11:16 +00:00
* /
2010-12-02 15:29:07 +00:00
public COOJAProject [ ] getProjects ( ) {
return currentProjects . toArray ( new COOJAProject [ 0 ] ) ;
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 ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Failed trying to show plugin without visualizer. " ) ;
2008-12-16 15:10:49 +00:00
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 ) {
2009-11-13 08:49:26 +00:00
for ( Plugin p : startedPlugins . toArray ( new Plugin [ 0 ] ) ) {
2010-01-15 10:47:36 +00:00
if ( ! ( p instanceof MotePlugin ) ) {
2008-03-17 08:35:10 +00:00
continue ;
}
2010-01-15 10:47:36 +00:00
Mote pluginMote = ( ( MotePlugin ) p ) . getMote ( ) ;
2008-03-17 08:35:10 +00:00
if ( pluginMote = = mote ) {
2009-11-13 08:49:26 +00:00
removePlugin ( p , false ) ;
2008-03-17 08:35:10 +00:00
}
}
}
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 .
2012-03-23 15:14:24 +01:00
*
2009-06-10 15:57:08 +00:00
* @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
* /
2009-12-14 13:29:35 +00:00
private Plugin tryStartPlugin ( final Class < ? extends Plugin > pluginClass ,
final GUI argGUI , final Simulation argSimulation , final Mote argMote , boolean activate ) {
2009-06-10 15:57:08 +00:00
try {
2009-12-14 13:29:35 +00:00
return startPlugin ( pluginClass , argGUI , argSimulation , argMote , activate ) ;
2009-06-10 15:57:08 +00:00
} 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 */
2010-03-19 12:34:03 +00:00
Throwable cause = ex ;
2009-06-11 10:23:29 +00:00
do {
if ( cause instanceof PluginRequiresVisualizationException ) {
logger . info ( " Visualized plugin was not started: " + pluginClass ) ;
return null ;
}
2010-03-19 12:34:03 +00:00
} while ( cause ! = null & & ( cause = cause . getCause ( ) ) ! = null ) ;
2012-03-23 15:14:24 +01:00
2009-06-10 15:57:08 +00:00
logger . fatal ( " Error when starting plugin " , ex ) ;
}
}
return null ;
}
2009-12-14 13:29:35 +00:00
public Plugin tryStartPlugin ( final Class < ? extends Plugin > pluginClass ,
final GUI argGUI , final Simulation argSimulation , final Mote argMote ) {
return tryStartPlugin ( pluginClass , argGUI , argSimulation , argMote , true ) ;
}
public Plugin startPlugin ( final Class < ? extends Plugin > pluginClass ,
2012-03-23 15:14:24 +01:00
final GUI argGUI , final Simulation argSimulation , final Mote argMote )
throws PluginConstructionException
2009-12-14 13:29:35 +00:00
{
return startPlugin ( pluginClass , argGUI , argSimulation , argMote , true ) ;
}
2009-06-10 15:57:08 +00:00
/ * *
* Starts given plugin . If visualized , the plugin is also shown .
2012-03-23 15:14:24 +01:00
*
2009-06-10 15:57:08 +00:00
* @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
* /
2009-12-14 13:29:35 +00:00
private Plugin startPlugin ( final Class < ? extends Plugin > pluginClass ,
final GUI argGUI , final Simulation argSimulation , final Mote argMote , boolean activate )
2009-06-10 15:57:08 +00:00
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 ) ) {
2012-05-31 18:01:53 +02:00
throw new PluginConstructionException ( " Tool 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
2012-03-23 15:14:24 +01:00
plugin =
2009-06-10 15:57:08 +00:00
pluginClass . getConstructor ( new Class [ ] { Mote . class , Simulation . class , GUI . class } )
. newInstance ( argMote , argSimulation , argGUI ) ;
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
2012-03-23 15:14:24 +01:00
plugin =
2009-06-10 15:57:08 +00:00
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 ) {
2012-05-31 18:01:53 +02:00
PluginConstructionException ex = new PluginConstructionException ( " Tool class requires visualization: " + pluginClass . getName ( ) ) ;
2009-06-10 15:57:08 +00:00
ex . initCause ( e ) ;
throw ex ;
2008-12-16 15:10:49 +00:00
} catch ( Exception e ) {
2012-05-31 18:01:53 +02:00
PluginConstructionException ex = new PluginConstructionException ( " Construction error for tool of class: " + pluginClass . getName ( ) ) ;
2009-06-10 15:57:08 +00:00
ex . initCause ( e ) ;
throw ex ;
2007-08-22 11:23:50 +00:00
}
2006-08-21 12:11:16 +00:00
2009-12-14 13:29:35 +00:00
if ( activate ) {
plugin . startPlugin ( ) ;
}
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
2009-12-14 13:29:35 +00:00
if ( activate & & plugin . getGUI ( ) ! = null ) {
2008-12-16 15:10:49 +00:00
myGUI . showPlugin ( plugin ) ;
2007-01-09 10:27:53 +00:00
}
2012-03-23 15:14:24 +01:00
2008-12-16 15:10:49 +00:00
return plugin ;
2006-08-21 12:11:16 +00:00
}
/ * *
* Unregister a plugin class . Removes any plugin menu items links as well .
2007-08-22 11:23:50 +00:00
*
2010-12-02 15:29:07 +00:00
* @param pluginClass Plugin class
2006-08-21 12:11:16 +00:00
* /
2007-01-09 10:27:53 +00:00
public void unregisterPlugin ( Class < ? extends Plugin > pluginClass ) {
2010-12-02 15:29:07 +00:00
pluginClasses . remove ( pluginClass ) ;
2012-06-05 17:03:07 +02:00
menuMotePluginClasses . remove ( pluginClass ) ;
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
*
2012-06-05 17:03:07 +02:00
* @param pluginClass New plugin to register
2006-08-21 12:11:16 +00:00
* @return True if this plugin was registered ok , false otherwise
* /
2012-06-05 17:03:07 +02:00
public boolean registerPlugin ( final Class < ? extends Plugin > pluginClass ) {
2006-08-21 12:11:16 +00:00
2012-06-05 17:03:07 +02:00
/* Check plugin type */
2008-11-04 14:32:32 +00:00
final int pluginType ;
2012-06-05 17:03:07 +02:00
if ( pluginClass . isAnnotationPresent ( PluginType . class ) ) {
pluginType = pluginClass . getAnnotation ( PluginType . class ) . value ( ) ;
2006-08-21 12:11:16 +00:00
} else {
2012-06-05 17:03:07 +02:00
logger . fatal ( " Could not register plugin, no plugin type found: " + pluginClass ) ;
return false ;
2006-08-21 12:11:16 +00:00
}
2012-06-05 17:03:07 +02:00
/* Check plugin constructor */
2006-08-21 12:11:16 +00:00
try {
2012-06-05 17:03:07 +02:00
if ( pluginType = = PluginType . COOJA_PLUGIN | | pluginType = = PluginType . COOJA_STANDARD_PLUGIN ) {
pluginClass . getConstructor ( new Class [ ] { GUI . class } ) ;
} else if ( pluginType = = PluginType . SIM_PLUGIN | | pluginType = = PluginType . SIM_STANDARD_PLUGIN ) {
pluginClass . getConstructor ( new Class [ ] { Simulation . class , GUI . class } ) ;
} else if ( pluginType = = PluginType . MOTE_PLUGIN ) {
pluginClass . getConstructor ( new Class [ ] { Mote . class , Simulation . class , GUI . class } ) ;
menuMotePluginClasses . add ( pluginClass ) ;
2006-08-21 12:11:16 +00:00
} else {
2012-06-05 17:03:07 +02:00
logger . fatal ( " Could not register plugin, bad plugin type: " + pluginType ) ;
2006-08-21 12:11:16 +00:00
return false ;
}
2012-06-05 17:03:07 +02:00
pluginClasses . add ( pluginClass ) ;
2010-03-09 08:27:48 +00:00
} catch ( NoClassDefFoundError e ) {
2012-06-05 17:03:07 +02:00
logger . fatal ( " No plugin class: " + pluginClass + " : " + e . getMessage ( ) ) ;
2010-03-09 08:27:48 +00:00
return false ;
2006-08-21 12:11:16 +00:00
} catch ( NoSuchMethodException e ) {
2012-06-05 17:03:07 +02:00
logger . fatal ( " No plugin class constructor: " + pluginClass + " : " + e . getMessage ( ) ) ;
2006-08-21 12:11:16 +00:00
return false ;
}
return true ;
}
/ * *
2010-12-02 15:29:07 +00:00
* Unregister all plugin classes
2006-08-21 12:11:16 +00:00
* /
public void unregisterPlugins ( ) {
2012-06-05 17:03:07 +02:00
menuMotePluginClasses . clear ( ) ;
2006-08-21 12:11:16 +00:00
pluginClasses . clear ( ) ;
}
2009-10-27 09:31:22 +00:00
/ * *
2011-03-14 19:54:58 +01:00
* Returns started plugin that ends with given class name , if any .
2012-03-23 15:14:24 +01:00
*
2009-10-27 09:31:22 +00:00
* @param classname Class name
* @return Plugin instance
* /
2011-03-14 19:54:58 +01:00
public Plugin getPlugin ( String classname ) {
2009-10-27 09:31:22 +00:00
for ( Plugin p : startedPlugins ) {
2011-03-14 19:54:58 +01:00
if ( p . getClass ( ) . getName ( ) . endsWith ( classname ) ) {
2009-10-27 09:31:22 +00:00
return p ;
}
}
return null ;
}
2012-03-23 15:14:24 +01:00
2011-03-14 19:54:58 +01:00
/ * *
* Returns started plugin with given class name , if any .
2012-03-23 15:14:24 +01:00
*
2011-03-14 19:54:58 +01:00
* @param classname Class name
* @return Plugin instance
* @deprecated
* /
2012-06-01 10:49:56 +02:00
@Deprecated
2011-03-14 19:54:58 +01:00
public Plugin getStartedPlugin ( String classname ) {
return getPlugin ( classname ) ;
}
2009-10-29 10:16:05 +00:00
public Plugin [ ] getStartedPlugins ( ) {
return startedPlugins . toArray ( new Plugin [ 0 ] ) ;
}
2012-06-05 17:03:07 +02:00
private boolean isMotePluginCompatible ( Class < ? extends Plugin > motePluginClass , Mote mote ) {
if ( motePluginClass . getAnnotation ( SupportedArguments . class ) = = null ) {
return true ;
}
/* Check mote interfaces */
boolean moteInterfacesOK = true ;
Class < ? extends MoteInterface > [ ] moteInterfaces =
motePluginClass . getAnnotation ( SupportedArguments . class ) . moteInterfaces ( ) ;
StringBuilder moteTypeInterfacesError = new StringBuilder ( ) ;
moteTypeInterfacesError . append (
" The plugin: \ n " +
getDescriptionOf ( motePluginClass ) +
" \ nrequires the following mote interfaces: \ n "
) ;
for ( Class < ? extends MoteInterface > requiredMoteInterface : moteInterfaces ) {
moteTypeInterfacesError . append ( getDescriptionOf ( requiredMoteInterface ) + " \ n " ) ;
if ( mote . getInterfaces ( ) . getInterfaceOfType ( requiredMoteInterface ) = = null ) {
moteInterfacesOK = false ;
}
}
/* Check mote type */
boolean moteTypeOK = false ;
Class < ? extends Mote > [ ] motes =
motePluginClass . getAnnotation ( SupportedArguments . class ) . motes ( ) ;
StringBuilder moteTypeError = new StringBuilder ( ) ;
moteTypeError . append (
" The plugin: \ n " +
getDescriptionOf ( motePluginClass ) +
" \ ndoes not support motes of type: \ n " +
getDescriptionOf ( mote ) +
" \ n \ nIt only supports motes of types: \ n "
) ;
for ( Class < ? extends Mote > supportedMote : motes ) {
moteTypeError . append ( getDescriptionOf ( supportedMote ) + " \ n " ) ;
if ( supportedMote . isAssignableFrom ( mote . getClass ( ) ) ) {
moteTypeOK = true ;
}
}
/ * if ( ! moteInterfacesOK ) {
menuItem . setToolTipText (
" <html><pre> " + moteTypeInterfacesError + " </html> "
) ;
}
if ( ! moteTypeOK ) {
menuItem . setToolTipText (
" <html><pre> " + moteTypeError + " </html> "
) ;
} * /
return moteInterfacesOK & & moteTypeOK ;
}
public JMenu createMotePluginsSubmenu ( Class < ? extends Plugin > pluginClass ) {
JMenu menu = new JMenu ( getDescriptionOf ( pluginClass ) ) ;
if ( getSimulation ( ) = = null | | getSimulation ( ) . getMotesCount ( ) = = 0 ) {
menu . setEnabled ( false ) ;
return menu ;
}
ActionListener menuItemListener = new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
Object pluginClass = ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " class " ) ;
Object mote = ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " mote " ) ;
tryStartPlugin ( ( Class < ? extends Plugin > ) pluginClass , myGUI , getSimulation ( ) , ( Mote ) mote ) ;
}
} ;
final int MAX_PER_ROW = 30 ;
final int MAX_COLUMNS = 5 ;
int added = 0 ;
for ( Mote mote : getSimulation ( ) . getMotes ( ) ) {
if ( ! isMotePluginCompatible ( pluginClass , mote ) ) {
continue ;
}
JMenuItem menuItem = new JMenuItem ( mote . toString ( ) + " ... " ) ;
menuItem . putClientProperty ( " class " , pluginClass ) ;
menuItem . putClientProperty ( " mote " , mote ) ;
menuItem . addActionListener ( menuItemListener ) ;
menu . add ( menuItem ) ;
added + + ;
if ( added = = MAX_PER_ROW ) {
menu . getPopupMenu ( ) . setLayout ( new GridLayout ( MAX_PER_ROW , MAX_COLUMNS ) ) ;
}
if ( added > = MAX_PER_ROW * MAX_COLUMNS ) {
break ;
}
}
if ( added = = 0 ) {
menu . setEnabled ( false ) ;
}
return menu ;
}
2006-08-21 12:11:16 +00:00
/ * *
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 ) {
2012-05-31 18:01:53 +02:00
JMenu menuMotePlugins = new JMenu ( " Mote tools for " + mote ) ;
2007-03-22 11:14:27 +00:00
for ( Class < ? extends Plugin > motePluginClass : menuMotePluginClasses ) {
2012-06-05 17:03:07 +02:00
if ( ! isMotePluginCompatible ( motePluginClass , mote ) ) {
continue ;
}
GUIAction guiAction = new StartPluginGUIAction ( getDescriptionOf ( motePluginClass ) + " ... " ) ;
2009-06-02 15:04:49 +00:00
JMenuItem menuItem = new JMenuItem ( guiAction ) ;
2007-03-22 11:14:27 +00:00
menuItem . putClientProperty ( " class " , motePluginClass ) ;
menuItem . putClientProperty ( " mote " , mote ) ;
2012-05-09 13:47:03 +02:00
2007-03-22 11:14:27 +00:00
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 ) {
2012-06-01 13:20:03 +02:00
frame . setTitle ( sim . getTitle ( ) + " - " + WINDOW_TITLE ) ;
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 .
2009-11-13 08:49:26 +00:00
* This may include displaying a dialog for user configurations .
2012-03-23 15:14:24 +01:00
*
2009-11-13 08:49:26 +00:00
* If mote type is created successfully , the add motes dialog will appear .
2012-03-23 15:14:24 +01:00
*
2009-11-13 08:49:26 +00:00
* @param moteTypeClass Mote type class
2006-08-21 12:11:16 +00:00
* /
public void doCreateMoteType ( Class < ? extends MoteType > moteTypeClass ) {
2009-11-13 08:49:26 +00:00
doCreateMoteType ( moteTypeClass , true ) ;
}
2012-03-23 15:14:24 +01:00
2009-11-13 08:49:26 +00:00
/ * *
* Creates a new mote type of the given mote type class .
* This may include displaying a dialog for user configurations .
2012-03-23 15:14:24 +01:00
*
2009-11-13 08:49:26 +00:00
* @param moteTypeClass Mote type class
2012-03-23 15:14:24 +01:00
* @param addMotes Show add motes dialog after successfully adding mote type
2009-11-13 08:49:26 +00:00
* /
public void doCreateMoteType ( Class < ? extends MoteType > moteTypeClass , boolean addMotes ) {
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 ;
}
2007-01-09 10:27:53 +00:00
mySimulation . stopSimulation ( ) ;
2006-08-21 12:11:16 +00:00
// Create mote type
MoteType newMoteType = null ;
try {
newMoteType = moteTypeClass . newInstance ( ) ;
2009-11-13 08:49:26 +00:00
if ( ! newMoteType . configureAndInit ( GUI . getTopParentContainer ( ) , mySimulation , isVisualized ( ) ) ) {
return ;
}
mySimulation . addMoteType ( newMoteType ) ;
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 ;
}
2009-11-13 08:49:26 +00:00
/* Allow user to immediately add motes */
if ( addMotes ) {
2008-10-03 13:17:28 +00:00
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 ,
2012-06-04 13:30:33 +02:00
JOptionPane . QUESTION_MESSAGE , null , options , s2 ) ;
2008-11-04 14:32:32 +00:00
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-11-13 08:49:26 +00:00
mySimulation . removed ( ) ;
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
// Reset frame title
if ( isVisualizedInFrame ( ) ) {
2012-05-31 18:01:53 +02:00
frame . setTitle ( WINDOW_TITLE ) ;
2008-11-04 14:32:32 +00:00
}
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
2010-02-23 22:53:34 +00:00
/* Warn about memory usage */
if ( warnMemory ( ) ) {
return ;
}
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
2009-11-13 14:25:43 +00:00
addToFileHistory ( configFile ) ;
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 ( ) {
2009-11-13 08:49:26 +00:00
final JDialog progressDialog = new JDialog ( ( Window ) GUI . getTopParentContainer ( ) , 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 */
2012-05-31 18:01:53 +02:00
button = new JButton ( " Abort " ) ;
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 ) ;
}
}
} ) ;
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 ) ;
2009-11-13 14:25:43 +00:00
PROGRESS_WARNINGS . clear ( ) ;
2009-03-21 14:24:55 +00:00
newSim = loadSimulationConfig ( fileToLoad , quick ) ;
2009-06-09 09:47:04 +00:00
myGUI . setSimulation ( newSim , false ) ;
2012-03-23 15:14:24 +01:00
2009-11-13 14:25:43 +00:00
/* Optionally show compilation warnings */
boolean hideWarn = Boolean . parseBoolean (
GUI . getExternalToolsSetting ( " HIDE_WARNINGS " , " false " )
) ;
if ( quick & & ! hideWarn & & ! PROGRESS_WARNINGS . isEmpty ( ) ) {
showWarningsDialog ( frame , PROGRESS_WARNINGS . toArray ( new String [ 0 ] ) ) ;
}
PROGRESS_WARNINGS . clear ( ) ;
2012-03-23 15:14:24 +01:00
2009-03-21 14:24:55 +00:00
} 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
2010-02-03 15:49:24 +00:00
* @param randomSeed Simulation ' s next random 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
2010-02-23 22:53:34 +00:00
/* Warn about memory usage */
if ( warnMemory ( ) ) {
return ;
}
2012-03-23 15:14:24 +01: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 ) ;
2009-11-13 14:25:43 +00:00
PROGRESS_WARNINGS . clear ( ) ;
2009-06-24 07:56:15 +00:00
Simulation newSim = loadSimulationConfig ( root , true , new Long ( randomSeed ) ) ;
2009-06-09 09:47:04 +00:00
myGUI . setSimulation ( newSim , false ) ;
2009-02-18 10:09:32 +00:00
2008-04-22 13:04:43 +00:00
if ( autoStart ) {
newSim . startSimulation ( ) ;
}
2012-03-23 15:14:24 +01:00
2009-11-13 14:25:43 +00:00
/* Optionally show compilation warnings */
boolean hideWarn = Boolean . parseBoolean (
GUI . getExternalToolsSetting ( " HIDE_WARNINGS " , " false " )
) ;
if ( ! hideWarn & & ! PROGRESS_WARNINGS . isEmpty ( ) ) {
showWarningsDialog ( frame , PROGRESS_WARNINGS . toArray ( new String [ 0 ] ) ) ;
}
PROGRESS_WARNINGS . clear ( ) ;
2012-03-23 15:14:24 +01:00
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 */
2012-05-31 18:01:53 +02:00
JButton button = new JButton ( " Abort " ) ;
2007-03-23 11:25:19 +00:00
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 ) ;
}
}
} ) ;
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
2010-02-23 22:53:34 +00:00
private boolean warnMemory ( ) {
long max = Runtime . getRuntime ( ) . maxMemory ( ) ;
long used = Runtime . getRuntime ( ) . totalMemory ( ) - Runtime . getRuntime ( ) . freeMemory ( ) ;
double memRatio = ( double ) used / ( double ) max ;
if ( memRatio < 0 . 8 ) {
return false ;
}
DecimalFormat format = new DecimalFormat ( " 0.000 " ) ;
2012-05-31 18:01:53 +02:00
logger . warn ( " Memory usage is getting critical. Reboot Cooja to avoid out of memory error. Current memory usage is " + format . format ( 100 * memRatio ) + " %. " ) ;
2010-02-23 22:53:34 +00:00
if ( isVisualized ( ) ) {
int n = JOptionPane . showOptionDialog (
GUI . getTopParentContainer ( ) ,
2012-05-31 18:01:53 +02:00
" Reboot Cooja to avoid out of memory error. \ n " +
" Current memory usage is " + format . format ( 100 * memRatio ) + " %. " ,
2010-02-23 22:53:34 +00:00
" Out of memory warning " ,
JOptionPane . YES_NO_OPTION ,
JOptionPane . WARNING_MESSAGE , null ,
new String [ ] { " Continue " , " Abort " } , " Abort " ) ;
if ( n ! = JOptionPane . YES_OPTION ) {
return true ;
}
}
return false ;
}
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 .
*
2010-02-03 15:49:24 +00:00
* @see # reloadCurrentSimulation ( boolean , long )
2008-12-08 09:38:42 +00:00
* @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 ( ) ;
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 ) ) {
2010-12-10 15:54:52 +00:00
saveFile = new File ( saveFile . getParent ( ) , saveFile . getName ( ) + SAVED_SIMULATIONS_FILES ) ;
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
}
if ( ! saveFile . exists ( ) | | saveFile . canWrite ( ) ) {
saveSimulationConfig ( saveFile ) ;
addToFileHistory ( saveFile ) ;
return saveFile ;
2006-08-21 12:11:16 +00:00
} else {
2010-12-10 15:54:52 +00:00
JOptionPane . showMessageDialog (
2012-03-23 15:14:24 +01:00
getTopParentContainer ( ) , " No write access to " + saveFile , " Save failed " ,
2010-12-10 15:54:52 +00:00
JOptionPane . ERROR_MESSAGE ) ;
logger . fatal ( " No write access to file: " + saveFile . getAbsolutePath ( ) ) ;
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
}
2012-06-05 14:51:47 +02:00
updateGUIComponentState ( ) ;
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
*
2012-06-01 16:04:39 +02:00
* @param askForConfirmation Should we ask for confirmation before quitting ?
2006-08-21 12:11:16 +00:00
* /
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 ) {
2012-06-01 16:04:39 +02:00
if ( getSimulation ( ) ! = null ) {
/* Save? */
String s1 = " Yes " ;
String s2 = " No " ;
String s3 = " Cancel " ;
Object [ ] options = { s1 , s2 , s3 } ;
int n = JOptionPane . showOptionDialog ( GUI . getTopParentContainer ( ) ,
" Do you want to save the current simulation? " ,
WINDOW_TITLE , JOptionPane . YES_NO_CANCEL_OPTION ,
JOptionPane . WARNING_MESSAGE , null , options , s1 ) ;
if ( n = = JOptionPane . YES_OPTION ) {
if ( myGUI . doSaveConfig ( true ) = = null ) {
return ;
}
} else if ( n = = JOptionPane . CANCEL_OPTION ) {
return ;
} else if ( n ! = JOptionPane . NO_OPTION ) {
return ;
}
2007-08-22 11:23:50 +00:00
}
2007-01-09 10:27:53 +00:00
}
2009-11-13 08:49:26 +00:00
if ( getSimulation ( ) ! = null ) {
doRemoveSimulation ( false ) ;
}
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 ) {
2009-10-29 17:05:13 +00:00
return getExternalToolsSetting ( name , null ) ;
2006-08-21 12:11:16 +00:00
}
/ * *
* @param name
* Name of setting
* @param defaultValue
* Default value
* @return Value
* /
public static String getExternalToolsSetting ( String name , String defaultValue ) {
2009-10-28 13:37:29 +00:00
if ( specifiedContikiPath ! = null & & " PATH_CONTIKI " . equals ( name ) ) {
return specifiedContikiPath ;
}
2006-08-21 12:11:16 +00:00
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 ) {
2009-10-28 13:37:29 +00:00
if ( specifiedContikiPath ! = null & & " PATH_CONTIKI " . equals ( name ) ) {
specifiedContikiPath = newVal ;
} else {
currentExternalToolsSettings . setProperty ( name , newVal ) ;
}
2006-08-21 12:11:16 +00:00
}
/ * *
* 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 ;
2009-08-27 12:25:11 +00:00
} else if ( osName . startsWith ( " freebsd " ) ) {
filename = GUI . EXTERNAL_TOOLS_FREEBSD_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
try {
2012-06-01 11:17:54 +02:00
InputStream in = GUI . class . getResourceAsStream ( EXTERNAL_TOOLS_SETTINGS_FILENAME ) ;
2006-08-21 12:11:16 +00:00
if ( in = = null ) {
throw new FileNotFoundException ( filename + " not found " ) ;
}
Properties settings = new Properties ( ) ;
settings . load ( in ) ;
in . close ( ) ;
2012-06-01 11:17:54 +02:00
in = GUI . class . getResourceAsStream ( filename ) ;
if ( in = = null ) {
throw new FileNotFoundException ( filename + " not found " ) ;
}
settings . load ( in ) ;
in . close ( ) ;
2006-08-21 12:11:16 +00:00
currentExternalToolsSettings = settings ;
2007-03-22 16:41:50 +00:00
defaultExternalToolsSettings = ( Properties ) currentExternalToolsSettings . clone ( ) ;
2010-03-19 11:32:59 +00:00
logger . info ( " External tools default settings: " + filename ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException e ) {
2010-03-19 11:32:59 +00:00
logger . warn ( " Error when reading external tools settings from " + filename , e ) ;
2006-08-21 12:11:16 +00:00
} 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 ( ) ;
2010-03-19 11:32:59 +00:00
Enumeration < Object > en = settings . keys ( ) ;
2006-08-21 12:11:16 +00:00
while ( en . hasMoreElements ( ) ) {
String key = ( String ) en . nextElement ( ) ;
setExternalToolsSetting ( key , settings . getProperty ( key ) ) ;
}
2010-03-19 11:32:59 +00:00
logger . info ( " External tools user settings: " + externalToolsUserSettingsFile ) ;
2006-08-21 12:11:16 +00:00
} catch ( FileNotFoundException e ) {
2010-03-19 11:32:59 +00:00
logger . warn ( " Error when reading user settings from: " + externalToolsUserSettingsFile ) ;
2006-08-21 12:11:16 +00:00
} catch ( IOException e ) {
2010-03-19 11:32:59 +00:00
logger . warn ( " Error when reading user 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 , " " ) ;
2009-10-28 13:37:29 +00:00
String currentSetting = currentExternalToolsSettings . getProperty ( key , " " ) ;
2007-04-04 08:04:48 +00:00
if ( ! defaultSetting . equals ( currentSetting ) ) {
differingSettings . setProperty ( key , currentSetting ) ;
}
}
2007-08-22 11:23:50 +00:00
2012-05-31 18:01:53 +02: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 ////
2009-06-30 12:45:51 +00:00
private class GUIEventHandler implements ActionListener {
2006-08-21 12:11:16 +00:00
public void actionPerformed ( ActionEvent e ) {
2010-12-10 15:54:52 +00:00
if ( e . getActionCommand ( ) . equals ( " create mote type " ) ) {
2006-08-21 12:11:16 +00:00
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 ( ) ) ;
2012-05-31 18:01:53 +02:00
} else if ( e . getActionCommand ( ) . equals ( " manage extensions " ) ) {
2010-12-02 15:29:07 +00:00
COOJAProject [ ] newProjects = ProjectDirectoriesDialog . showDialog (
2012-03-23 15:14:24 +01:00
GUI . getTopParentContainer ( ) ,
GUI . this ,
2010-12-02 15:29:07 +00:00
getProjects ( )
2009-10-28 12:07:37 +00:00
) ;
2007-03-23 23:33:54 +00:00
if ( newProjects ! = null ) {
2010-12-02 15:29:07 +00:00
currentProjects . clear ( ) ;
for ( COOJAProject p : newProjects ) {
currentProjects . add ( p ) ;
}
2007-09-21 16:14:19 +00:00
try {
reparseProjectConfig ( ) ;
2009-10-28 12:07:37 +00:00
} catch ( ParseProjectsException ex ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Error when loading extensions: " + ex . getMessage ( ) , ex ) ;
2009-10-28 12:07:37 +00:00
if ( isVisualized ( ) ) {
2010-12-02 15:29:07 +00:00
JOptionPane . showMessageDialog ( GUI . getTopParentContainer ( ) ,
2012-05-31 18:01:53 +02:00
" All Cooja extensions could not load. \ n \ n " +
" To manage Cooja extensions: \ n " +
" Menu->Settings->Cooja extensions " ,
" Reconfigure Cooja extensions " , JOptionPane . INFORMATION_MESSAGE ) ;
2007-09-21 16:14:19 +00:00
}
2012-05-31 18:01:53 +02:00
showErrorDialog ( getTopParentContainer ( ) , " Cooja extensions load error " , ex , false ) ;
2007-09-21 16:14:19 +00:00
}
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
*
2009-11-25 20:47:18 +00:00
* @param < N > Class extending given class type
* @param classType Class type
* @param className Class name
2006-08-21 12:11:16 +00:00
* @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 ;
}
2010-12-02 15:29:07 +00:00
private ClassLoader createClassLoader ( Collection < COOJAProject > projects )
throws ClassLoaderCreationException {
return createClassLoader ( ClassLoader . getSystemClassLoader ( ) , projects ) ;
2006-08-22 12:25:24 +00:00
}
2010-12-02 15:29:07 +00:00
public static 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 ;
}
2010-12-02 15:29:07 +00:00
private ClassLoader createClassLoader ( ClassLoader parent , Collection < COOJAProject > projects )
throws ClassLoaderCreationException {
if ( projects = = null | | projects . isEmpty ( ) ) {
2006-08-22 12:25:24 +00:00
return parent ;
}
2007-01-10 14:57:42 +00:00
2010-12-02 15:29:07 +00:00
/* Create class loader from JARs */
2006-08-22 12:25:24 +00:00
ArrayList < URL > urls = new ArrayList < URL > ( ) ;
2010-12-02 15:29:07 +00:00
for ( COOJAProject project : projects ) {
File projectDir = project . dir ;
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 ) {
2012-03-28 11:01:17 +02:00
String logConfigFile = null ;
2012-03-28 10:55:01 +02:00
for ( String element : args ) {
2012-03-28 11:01:17 +02:00
if ( element . startsWith ( " -log4j= " ) ) {
String arg = element . substring ( " -log4j= " . length ( ) ) ;
logConfigFile = arg ;
}
2012-03-28 10:55:01 +02:00
}
2012-03-28 11:01:17 +02:00
2008-02-18 08:18:01 +00:00
try {
2008-04-02 16:41:46 +00:00
// Configure logger
2012-03-28 11:01:17 +02:00
if ( logConfigFile ! = null ) {
if ( new File ( logConfigFile ) . exists ( ) ) {
DOMConfigurator . configure ( logConfigFile ) ;
} else {
System . err . println ( " Failed to open " + logConfigFile ) ;
System . exit ( 1 ) ;
}
} else if ( new File ( LOG_CONFIG_FILE ) . exists ( ) ) {
2008-04-02 16:41:46 +00:00
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 ( ) ;
2010-03-10 12:48:35 +00:00
/* Warn at no JAVA_HOME */
String javaHome = System . getenv ( ) . get ( " JAVA_HOME " ) ;
if ( javaHome = = null | | javaHome . equals ( " " ) ) {
2012-05-31 18:01:53 +02:00
logger . warn ( " JAVA_HOME environment variable not set, Cooja motes may not compile " ) ;
2010-03-10 12:48:35 +00:00
}
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 ( ) ) ;
2009-10-28 12:07:37 +00:00
File configFile = new File ( config ) ;
2009-06-09 09:47:04 +00:00
Simulation sim = quickStartSimulationConfig ( configFile , false ) ;
if ( sim = = null ) {
System . exit ( 1 ) ;
}
GUI gui = sim . getGUI ( ) ;
2012-03-23 15:14:24 +01:00
2009-06-09 09:47:04 +00:00
/* 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 ) ;
2012-03-23 15:14:24 +01:00
try {
plugin . setScriptActive ( true ) ;
} catch ( Exception e ) {
logger . fatal ( " Error: " + e . getMessage ( ) , e ) ;
System . exit ( 1 ) ;
}
2009-06-09 09:47:04 +00:00
} else {
logger . fatal ( " No test editor controlling simulation, aborting " ) ;
2008-04-22 13:04:43 +00:00
System . exit ( 1 ) ;
}
}
2012-10-30 11:41:55 +01:00
sim . setSpeedLimit ( null ) ;
sim . startSimulation ( ) ;
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 ( ) {
2009-06-30 12:45:51 +00:00
JDesktopPane desktop = createDesktopPane ( ) ;
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 ( ) {
2009-06-30 12:45:51 +00:00
JDesktopPane desktop = createDesktopPane ( ) ;
2012-05-31 18:01:53 +02:00
frame = new JFrame ( WINDOW_TITLE ) ;
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 */
2011-11-01 09:20:49 +01:00
try {
this . currentConfigFile = this . currentConfigFile . getCanonicalFile ( ) ;
} catch ( IOException e ) {
}
2009-03-12 15:10:00 +00:00
2007-03-23 11:25:19 +00:00
try {
SAXBuilder builder = new SAXBuilder ( ) ;
2010-12-10 15:54:52 +00:00
InputStream in = new FileInputStream ( file ) ;
if ( file . getName ( ) . endsWith ( " .gz " ) ) {
in = new GZIPInputStream ( in ) ;
}
Document doc = builder . build ( in ) ;
2007-03-23 11:25:19 +00:00
Element root = doc . getRootElement ( ) ;
2010-12-10 15:54:52 +00:00
in . close ( ) ;
2007-01-09 10:27:53 +00:00
2009-06-24 07:56:15 +00:00
return loadSimulationConfig ( root , quick , null ) ;
2007-03-23 11:25:19 +00:00
} catch ( JDOMException e ) {
2009-11-13 14:25:43 +00:00
throw ( SimulationCreationException ) new SimulationCreationException ( " Config not wellformed " ) . initCause ( e ) ;
2007-03-23 11:25:19 +00:00
} catch ( IOException e ) {
2009-11-13 14:25:43 +00:00
throw ( SimulationCreationException ) new SimulationCreationException ( " Load simulation error " ) . initCause ( e ) ;
2007-03-23 11:25:19 +00:00
}
}
2007-01-09 10:27:53 +00:00
2009-11-13 08:49:26 +00:00
public Simulation loadSimulationConfig ( Element root , boolean quick , Long manualRandomSeed )
2007-04-02 12:45:19 +00:00
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 " ) ) {
2012-05-31 18:01:53 +02:00
logger . fatal ( " Not a valid Cooja simulation config. " ) ;
2007-01-09 10:27:53 +00:00
return null ;
}
2012-05-31 18:01:53 +02:00
/* Verify extension directories */
2008-12-08 10:26:21 +00:00
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 ( ) ;
2009-06-24 07:56:15 +00:00
boolean createdOK = newSim . setConfigXML ( config , ! quick , manualRandomSeed ) ;
2007-01-09 10:27:53 +00:00
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
* /
2009-10-29 10:16:05 +00:00
public void saveSimulationConfig ( File file ) {
2009-03-12 15:10:00 +00:00
this . currentConfigFile = file ; /* Used to generate config relative paths */
2011-11-01 09:20:49 +01:00
try {
this . currentConfigFile = this . currentConfigFile . getCanonicalFile ( ) ;
} catch ( IOException e ) {
}
2007-01-09 10:27:53 +00:00
try {
// Create and write to document
2009-10-29 10:16:05 +00:00
Document doc = new Document ( extractSimulationConfig ( ) ) ;
2010-12-10 15:54:52 +00:00
OutputStream out = new FileOutputStream ( file ) ;
2012-03-23 15:14:24 +01:00
2010-12-10 15:54:52 +00:00
if ( file . getName ( ) . endsWith ( " .gz " ) ) {
out = new GZIPOutputStream ( out ) ;
}
2012-03-23 15:14:24 +01:00
2007-01-09 10:27:53 +00:00
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 ( ) ;
}
}
2012-03-23 15:14:24 +01:00
2009-10-29 10:16:05 +00:00
public Element extractSimulationConfig ( ) {
// Create simulation config
Element root = new Element ( " simconf " ) ;
2012-05-31 18:01:53 +02:00
/* Store extension directories meta data */
2010-12-02 15:29:07 +00:00
for ( COOJAProject project : currentProjects ) {
2009-10-29 10:16:05 +00:00
Element projectElement = new Element ( " project " ) ;
2010-12-02 15:29:07 +00:00
projectElement . addContent ( createPortablePath ( project . dir ) . getPath ( ) . replaceAll ( " \\ \\ " , " / " ) ) ;
2010-03-19 15:04:51 +00:00
projectElement . setAttribute ( " EXPORT " , " discard " ) ;
2009-10-29 10:16:05 +00:00
root . addContent ( projectElement ) ;
}
Element simulationElement = new Element ( " simulation " ) ;
simulationElement . addContent ( mySimulation . getConfigXML ( ) ) ;
root . addContent ( simulationElement ) ;
// Create started plugins config
Collection < Element > pluginsConfig = getPluginsConfigXML ( ) ;
if ( pluginsConfig ! = null ) {
root . addContent ( pluginsConfig ) ;
}
return root ;
}
2007-01-09 10:27:53 +00:00
/ * *
* 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 ( ) {
2010-01-15 10:47:36 +00:00
ArrayList < Element > config = new ArrayList < Element > ( ) ;
2007-01-09 10:27:53 +00:00
Element pluginElement , pluginSubElement ;
2010-01-15 10:47:36 +00:00
/* Loop over all plugins */
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)
2010-01-15 10:47:36 +00:00
if ( pluginType = = PluginType . MOTE_PLUGIN ) {
2007-01-09 10:27:53 +00:00
pluginSubElement = new Element ( " mote_arg " ) ;
2010-01-15 10:47:36 +00:00
Mote taggedMote = ( ( MotePlugin ) startedPlugin ) . getMote ( ) ;
2007-01-09 10:27:53 +00:00
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
2010-04-26 08:19:32 +00:00
if ( pluginFrame . isIcon ( ) ) {
pluginSubElement = new Element ( " minimized " ) ;
pluginSubElement . setText ( " " + true ) ;
pluginElement . addContent ( pluginSubElement ) ;
}
2007-01-09 10:27:53 +00:00
}
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 ;
2012-05-31 18:01:53 +02:00
/* Match current extensions against extensions in simulation config */
2008-12-08 10:26:21 +00:00
for ( final Element pluginElement : configXML . toArray ( new Element [ 0 ] ) ) {
if ( pluginElement . getName ( ) . equals ( " project " ) ) {
2009-10-28 12:07:37 +00:00
File projectFile = restorePortablePath ( new File ( pluginElement . getText ( ) ) ) ;
try {
projectFile = projectFile . getCanonicalFile ( ) ;
} catch ( IOException e ) {
}
2012-03-23 15:14:24 +01:00
2008-12-08 10:26:21 +00:00
boolean found = false ;
2010-12-02 15:29:07 +00:00
for ( COOJAProject currentProject : currentProjects ) {
2009-10-28 12:07:37 +00:00
if ( projectFile . getPath ( ) . replaceAll ( " \\ \\ " , " / " ) .
2010-12-02 15:29:07 +00:00
equals ( currentProject . dir . getPath ( ) . replaceAll ( " \\ \\ " , " / " ) ) ) {
2008-12-08 10:26:21 +00:00
found = true ;
break ;
}
}
if ( ! found ) {
2012-05-31 18:01:53 +02:00
logger . warn ( " Loaded simulation may depend on not found extension: ' " + projectFile + " ' " ) ;
2008-12-08 10:26:21 +00:00
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-12-14 13:29:35 +00:00
final Plugin startedPlugin = tryStartPlugin ( pluginClass , this , simulation , mote , false ) ;
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
}
}
2009-12-14 13:29:35 +00:00
/* Activate plugin */
startedPlugin . startPlugin ( ) ;
2012-03-23 15:14:24 +01: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 ( ) ) ;
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 " ) ) {
2010-04-26 08:19:32 +00:00
boolean minimized = Boolean . parseBoolean ( pluginSubElement . getText ( ) ) ;
final JInternalFrame pluginGUI = startedPlugin . getGUI ( ) ;
if ( minimized & & pluginGUI ! = null ) {
SwingUtilities . invokeLater ( new Runnable ( ) {
public void run ( ) {
try {
pluginGUI . setIcon ( true ) ;
} catch ( PropertyVetoException e ) {
}
2012-03-23 15:14:24 +01:00
} ;
2010-04-26 08:19:32 +00:00
} ) ;
}
2008-11-04 14:32:32 +00:00
}
2008-12-16 15:10:49 +00:00
}
2008-11-04 14:32:32 +00:00
2009-12-14 13:29:35 +00:00
showPlugin ( startedPlugin ) ;
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
}
}
2010-09-24 12:48:04 +00:00
/* Z order visualized plugins */
try {
for ( int z = 0 ; z < getDesktopPane ( ) . getAllFrames ( ) . length ; z + + ) {
for ( JInternalFrame plugin : getDesktopPane ( ) . getAllFrames ( ) ) {
if ( plugin . getClientProperty ( " zorder " ) = = null ) {
continue ;
}
int zOrder = ( ( Integer ) plugin . getClientProperty ( " zorder " ) ) . intValue ( ) ;
if ( zOrder ! = z ) {
continue ;
}
getDesktopPane ( ) . setComponentZOrder ( plugin , zOrder ) ;
if ( z = = 0 ) {
plugin . setSelected ( true ) ;
}
plugin . putClientProperty ( " zorder " , null ) ;
break ;
}
getDesktopPane ( ) . repaint ( ) ;
}
} catch ( Exception e ) { }
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 {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 1508168026300714850L ;
public ParseProjectsException ( String message ) {
2007-09-21 16:14:19 +00:00
super ( message ) ;
}
}
public class ClassLoaderCreationException extends Exception {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 1578001681266277774L ;
public ClassLoaderCreationException ( String message ) {
2007-09-21 16:14:19 +00:00
super ( message ) ;
}
}
public class SimulationCreationException extends Exception {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 2414899187405770448L ;
public SimulationCreationException ( String message ) {
2007-04-02 12:45:19 +00:00
super ( message ) ;
}
}
2007-05-10 17:05:01 +00:00
2009-06-10 15:57:08 +00:00
public class PluginConstructionException extends Exception {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 8004171223353676751L ;
public PluginConstructionException ( String message ) {
2009-06-10 15:57:08 +00:00
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 ) {
2010-02-21 21:50:58 +00:00
/* Contiki error */
if ( exception instanceof ContikiError ) {
String contikiError = ( ( ContikiError ) exception ) . getContikiError ( ) ;
MessageList list = new MessageList ( ) ;
for ( String l : contikiError . split ( " \ n " ) ) {
list . addMessage ( l ) ;
}
list . addPopupMenuItem ( null , true ) ;
tabbedPane . addTab ( " Contiki error " , new JScrollPane ( list ) ) ;
}
2012-03-23 15:14:24 +01:00
2009-03-21 14:24:55 +00:00
/* 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 ) ;
2010-02-21 21:50:58 +00:00
tabbedPane . addTab ( " Compilation output " , new JScrollPane ( compilationOutput ) ) ;
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 ) ;
2010-02-21 21:50:58 +00:00
tabbedPane . addTab ( " Java stack trace " , new JScrollPane ( stackTrace ) ) ;
2009-03-21 14:24:55 +00:00
/* 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 ( ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 2370456199250998435L ;
public void actionPerformed ( ActionEvent e ) {
2009-03-21 14:24:55 +00:00
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 ( ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 6225539435993362733L ;
public void actionPerformed ( ActionEvent e ) {
2009-03-21 14:24:55 +00:00
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 ( ) ;
}
2009-11-13 14:25:43 +00:00
private static void showWarningsDialog ( final Frame parent , final String [ ] warnings ) {
new RunnableInEDT < Boolean > ( ) {
public Boolean work ( ) {
2012-03-23 15:14:24 +01:00
final JDialog dialog = new JDialog ( parent , " Compilation warnings " , false ) ;
2009-11-13 14:25:43 +00:00
Box buttonBox = Box . createHorizontalBox ( ) ;
/* Warnings message list */
MessageList compilationOutput = new MessageList ( ) ;
for ( String w : warnings ) {
compilationOutput . addMessage ( w , MessageList . ERROR ) ;
}
compilationOutput . addPopupMenuItem ( null , true ) ;
/* Checkbox */
buttonBox . add ( Box . createHorizontalGlue ( ) ) ;
JCheckBox hideButton = new JCheckBox ( " Hide compilation warnings " , false ) ;
hideButton . addActionListener ( new ActionListener ( ) {
public void actionPerformed ( ActionEvent e ) {
GUI . setExternalToolsSetting ( " HIDE_WARNINGS " ,
" " + ( ( JCheckBox ) e . getSource ( ) ) . isSelected ( ) ) ;
} ;
} ) ;
buttonBox . add ( Box . createHorizontalStrut ( 10 ) ) ;
buttonBox . add ( hideButton ) ;
/* Close on escape */
AbstractAction closeAction = new AbstractAction ( ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 2646163984382201634L ;
public void actionPerformed ( ActionEvent e ) {
2009-11-13 14:25:43 +00:00
dialog . dispose ( ) ;
}
} ;
InputMap inputMap = dialog . getRootPane ( ) . getInputMap (
JComponent . WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ) ;
inputMap . put ( KeyStroke . getKeyStroke ( KeyEvent . VK_ESCAPE , 0 , false ) , " close " ) ;
dialog . getRootPane ( ) . getActionMap ( ) . put ( " close " , closeAction ) ;
/* Layout */
dialog . getContentPane ( ) . add ( BorderLayout . CENTER , new JScrollPane ( compilationOutput ) ) ;
dialog . getContentPane ( ) . add ( BorderLayout . SOUTH , buttonBox ) ;
dialog . setSize ( 700 , 500 ) ;
dialog . setLocationRelativeTo ( parent ) ;
dialog . setVisible ( true ) ;
return true ;
}
} . invokeAndWait ( ) ;
}
2012-03-23 15:14:24 +01:00
2008-11-04 14:32:32 +00:00
/ * *
* 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 ) {
2010-12-10 17:50:48 +00:00
addMoteRelation ( source , dest , null ) ;
}
/ * *
* Adds directed relation between given motes .
*
* @param source Source mote
* @param dest Destination mote
* @param color The color to use when visualizing the mote relation
* /
public void addMoteRelation ( Mote source , Mote dest , Color color ) {
2009-02-26 13:35:45 +00:00
if ( source = = null | | dest = = null ) {
return ;
}
removeMoteRelation ( source , dest ) ; /* Unique relations */
2010-12-10 17:50:48 +00:00
moteRelations . add ( new MoteRelation ( source , dest , color ) ) ;
2009-02-26 13:35:45 +00:00
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 ) ;
2010-12-10 17:50:48 +00:00
/* Relations are unique */
moteRelationObservable . setChangedAndNotify ( ) ;
break ;
2009-02-26 13:35:45 +00:00
}
}
}
/ * *
* @return All current mote relations .
*
* @see # addMoteRelationsObserver ( Observer )
* /
public MoteRelation [ ] getMoteRelations ( ) {
2010-12-10 17:50:48 +00:00
return moteRelations . toArray ( new MoteRelation [ moteRelations . size ( ) ] ) ;
2009-02-26 13:35:45 +00:00
}
/ * *
* 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-10-28 12:07:37 +00:00
/ * *
* Tries to convert given file to be " portable " .
* The portable path is either relative to Contiki , or to the configuration ( . csc ) file .
2012-03-23 15:14:24 +01:00
*
2009-10-28 12:07:37 +00:00
* If this method fails , it returns the original file .
2012-03-23 15:14:24 +01:00
*
2009-10-28 12:07:37 +00:00
* @param file Original file
* @return Portable file , or original file is conversion failed
* /
2009-03-12 15:10:00 +00:00
public File createPortablePath ( File file ) {
2010-06-11 09:10:52 +00:00
return createPortablePath ( file , true ) ;
}
public File createPortablePath ( File file , boolean allowConfigRelativePaths ) {
2009-10-28 12:07:37 +00:00
File portable = null ;
2012-03-23 15:14:24 +01:00
2009-10-28 12:07:37 +00:00
portable = createContikiRelativePath ( file ) ;
if ( portable ! = null ) {
/*logger.info("Generated Contiki relative path '" + file.getPath() + "' to '" + portable.getPath() + "'");*/
return portable ;
}
2010-06-11 09:10:52 +00:00
if ( allowConfigRelativePaths ) {
portable = createConfigRelativePath ( file ) ;
if ( portable ! = null ) {
/*logger.info("Generated config relative path '" + file.getPath() + "' to '" + portable.getPath() + "'");*/
return portable ;
}
2009-10-28 12:07:37 +00:00
}
2012-03-23 15:14:24 +01:00
2009-10-28 12:07:37 +00:00
logger . warn ( " Path is not portable: ' " + file . getPath ( ) ) ;
return file ;
}
/ * *
* Tries to restore a previously " portable " file to be " absolute " .
* If the given file already exists , no conversion is performed .
2012-03-23 15:14:24 +01:00
*
2009-10-28 12:07:37 +00:00
* @see # createPortablePath ( File )
* @param file Portable file
* @return Absolute file
* /
public File restorePortablePath ( File file ) {
if ( file = = null | | file . exists ( ) ) {
/* No conversion possible/needed */
return file ;
}
File absolute = null ;
absolute = restoreContikiRelativePath ( file ) ;
if ( absolute ! = null ) {
/*logger.info("Restored Contiki relative path '" + file.getPath() + "' to '" + absolute.getPath() + "'");*/
return absolute ;
}
absolute = restoreConfigRelativePath ( file ) ;
if ( absolute ! = null ) {
/*logger.info("Restored config relative path '" + file.getPath() + "' to '" + absolute.getPath() + "'");*/
return absolute ;
}
2012-03-23 15:14:24 +01:00
2009-10-28 12:07:37 +00:00
/*logger.info("Portable path was not restored: '" + file.getPath());*/
return file ;
}
private final static String PATH_CONTIKI_IDENTIFIER = " [CONTIKI_DIR] " ;
private File createContikiRelativePath ( 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 contikiCanonical = contikiPath . getCanonicalPath ( ) ;
String fileCanonical = file . getCanonicalPath ( ) ;
if ( ! fileCanonical . startsWith ( contikiCanonical ) ) {
2009-10-28 12:07:37 +00:00
/* File is not in a Contiki subdirectory */
/*logger.info("File is not in a Contiki subdirectory: " + file.getAbsolutePath());*/
return null ;
2008-09-18 14:04:13 +00:00
}
2009-10-28 12:07:37 +00:00
/* Replace Contiki's canonical path with Contiki identifier */
String portablePath = fileCanonical . replaceFirst (
2012-03-23 15:14:24 +01:00
java . util . regex . Matcher . quoteReplacement ( contikiCanonical ) ,
2009-10-28 12:07:37 +00:00
java . util . regex . Matcher . quoteReplacement ( PATH_CONTIKI_IDENTIFIER ) ) ;
File portable = new File ( portablePath ) ;
2012-03-23 15:14:24 +01:00
2009-10-28 12:07:37 +00:00
/* Verify conversion */
File verify = restoreContikiRelativePath ( portable ) ;
if ( verify = = null | | ! verify . exists ( ) ) {
/* Error: did file even exist pre-conversion? */
return null ;
2009-03-12 15:10:00 +00:00
}
2009-10-28 12:07:37 +00:00
return portable ;
2009-03-12 15:10:00 +00:00
} catch ( IOException e1 ) {
/*logger.warn("Error when converting to Contiki relative path: " + e1.getMessage());*/
2009-10-28 12:07:37 +00:00
return null ;
2009-03-12 15:10:00 +00:00
}
}
2009-10-28 12:07:37 +00:00
private File restoreContikiRelativePath ( File portable ) {
try {
File contikiPath = new File ( GUI . getExternalToolsSetting ( " PATH_CONTIKI " , null ) ) ;
String contikiCanonical = contikiPath . getCanonicalPath ( ) ;
2009-03-12 15:10:00 +00:00
2009-10-28 12:07:37 +00:00
String portablePath = portable . getPath ( ) ;
if ( ! portablePath . startsWith ( PATH_CONTIKI_IDENTIFIER ) ) {
return null ;
}
File absolute = new File ( portablePath . replace ( PATH_CONTIKI_IDENTIFIER , contikiCanonical ) ) ;
return absolute ;
} catch ( IOException e ) {
return null ;
}
2009-03-12 15:10:00 +00:00
}
2009-10-28 12:07:37 +00:00
private final static String PATH_CONFIG_IDENTIFIER = " [CONFIG_DIR] " ;
2009-03-22 13:47:38 +00:00
public File currentConfigFile = null ; /* Used to generate config relative paths */
2009-10-28 12:07:37 +00:00
private File createConfigRelativePath ( File file ) {
String id = PATH_CONFIG_IDENTIFIER ;
2009-03-12 15:10:00 +00:00
if ( currentConfigFile = = null ) {
2009-10-28 12:07:37 +00:00
return null ;
2009-03-12 15:10:00 +00:00
}
try {
File configPath = currentConfigFile . getParentFile ( ) ;
2009-03-22 13:47:38 +00:00
if ( configPath = = null ) {
2009-10-28 13:37:29 +00:00
/* File is in current directory */
configPath = new File ( " " ) ;
2009-03-22 13:47:38 +00:00
}
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 */
2009-10-30 15:27:26 +00:00
File parent = new File ( configCanonical ) . getParentFile ( ) ;
if ( parent ! = null ) {
configCanonical = parent . getCanonicalPath ( ) ;
id + = " /.. " ;
}
2009-10-28 12:07:37 +00:00
}
if ( ! fileCanonical . startsWith ( configCanonical ) ) {
/* File is not in a config subdirectory */
2009-11-02 13:18:27 +00:00
/*logger.info("File is not in a config subdirectory: " + file.getAbsolutePath());*/
2009-10-28 12:07:37 +00:00
return null ;
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-10-28 12:07:37 +00:00
String portablePath = fileCanonical . replaceFirst (
2012-03-23 15:14:24 +01:00
java . util . regex . Matcher . quoteReplacement ( configCanonical ) ,
2009-10-28 12:07:37 +00:00
java . util . regex . Matcher . quoteReplacement ( id ) ) ;
File portable = new File ( portablePath ) ;
2012-03-23 15:14:24 +01:00
2009-10-28 12:07:37 +00:00
/* Verify conversion */
File verify = restoreConfigRelativePath ( portable ) ;
if ( verify = = null | | ! verify . exists ( ) ) {
/* Error: did file even exist pre-conversion? */
return null ;
2009-06-15 18:13:45 +00:00
}
2009-10-28 12:07:37 +00:00
return portable ;
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());*/
2009-10-28 12:07:37 +00:00
return null ;
2008-09-18 14:04:13 +00:00
}
}
2009-10-28 12:07:37 +00:00
private File restoreConfigRelativePath ( File portable ) {
2010-03-19 15:04:51 +00:00
return restoreConfigRelativePath ( currentConfigFile , portable ) ;
}
public static File restoreConfigRelativePath ( File configFile , File portable ) {
if ( configFile = = null ) {
2009-10-28 12:07:37 +00:00
return null ;
2009-03-12 15:10:00 +00:00
}
2010-03-19 15:04:51 +00:00
File configPath = configFile . getParentFile ( ) ;
2009-03-22 13:47:38 +00:00
if ( configPath = = null ) {
2009-10-28 13:37:29 +00:00
/* File is in current directory */
configPath = new File ( " " ) ;
2009-03-22 13:47:38 +00:00
}
2009-10-28 12:07:37 +00:00
String portablePath = portable . getPath ( ) ;
if ( ! portablePath . startsWith ( PATH_CONFIG_IDENTIFIER ) ) {
return null ;
2009-03-12 15:10:00 +00:00
}
2009-10-28 12:07:37 +00:00
File absolute = new File ( portablePath . replace ( PATH_CONFIG_IDENTIFIER , configPath . getAbsolutePath ( ) ) ) ;
return absolute ;
2009-03-12 15:10:00 +00:00
}
2009-03-11 20:14:52 +00:00
private static JProgressBar PROGRESS_BAR = null ;
2009-11-13 14:25:43 +00:00
private static ArrayList < String > PROGRESS_WARNINGS = new ArrayList < String > ( ) ;
2009-03-11 20:14:52 +00:00
public static void setProgressMessage ( String msg ) {
2009-11-13 14:25:43 +00:00
setProgressMessage ( msg , MessageList . NORMAL ) ;
}
public static void setProgressMessage ( String msg , int type ) {
2009-03-11 20:14:52 +00:00
if ( PROGRESS_BAR ! = null & & PROGRESS_BAR . isShowing ( ) ) {
PROGRESS_BAR . setString ( msg ) ;
PROGRESS_BAR . setStringPainted ( true ) ;
}
2009-11-13 14:25:43 +00:00
if ( type ! = MessageList . NORMAL ) {
PROGRESS_WARNINGS . add ( msg ) ;
}
2009-03-11 20:14:52 +00:00
}
2009-06-30 12:45:51 +00:00
/ * *
* Load quick help for given object or identifier . Note that this method does not
* show the quick help pane .
2012-03-23 15:14:24 +01:00
*
2009-06-30 12:45:51 +00:00
* @param obj If string : help identifier . Else , the class name of the argument
* is used as help identifier .
* /
public void loadQuickHelp ( final Object obj ) {
if ( obj = = null ) {
return ;
}
String key ;
if ( obj instanceof String ) {
key = ( String ) obj ;
} else {
key = obj . getClass ( ) . getName ( ) ;
}
2012-03-23 15:14:24 +01:00
2009-06-30 12:45:51 +00:00
String help = null ;
if ( obj instanceof HasQuickHelp ) {
help = ( ( HasQuickHelp ) obj ) . getQuickHelp ( ) ;
} else {
if ( quickHelpProperties = = null ) {
/* Load quickhelp.txt */
try {
quickHelpProperties = new Properties ( ) ;
quickHelpProperties . load ( new FileReader ( " quickhelp.txt " ) ) ;
} catch ( Exception e ) {
quickHelpProperties = null ;
help = " <html><b>Failed to read quickhelp.txt:</b><p> " + e . getMessage ( ) + " </html> " ;
}
}
if ( quickHelpProperties ! = null ) {
help = quickHelpProperties . getProperty ( key ) ;
}
}
if ( help ! = null ) {
quickHelpTextPane . setText ( " <html> " + help + " </html> " ) ;
} else {
quickHelpTextPane . setText (
" <html><b> " + getDescriptionOf ( obj ) + " </b> " +
" <p>No help available</html> " ) ;
}
quickHelpTextPane . setCaretPosition ( 0 ) ;
}
2009-05-28 12:55:14 +00:00
/* GUI actions */
2009-05-28 14:53:26 +00:00
abstract class GUIAction extends AbstractAction {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 6946179457635198477L ;
public GUIAction ( String name ) {
2009-05-28 14:53:26 +00:00
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 ( ) ;
}
2012-05-31 18:01:53 +02:00
GUIAction newSimulationAction = new GUIAction ( " New simulation... " , KeyEvent . VK_N , KeyStroke . getKeyStroke ( KeyEvent . VK_N , ActionEvent . CTRL_MASK ) ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 5053703908505299911L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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 ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 4783032948880161189L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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 ;
}
} ;
2012-05-31 18:01:53 +02:00
GUIAction reloadSimulationAction = new GUIAction ( " Reload with same random seed " , KeyEvent . VK_K , KeyStroke . getKeyStroke ( KeyEvent . VK_R , ActionEvent . CTRL_MASK ) ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 66579555555421977L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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
} ;
2012-05-31 18:01:53 +02:00
GUIAction reloadRandomSimulationAction = new GUIAction ( " Reload with new random seed " , KeyEvent . VK_N , KeyStroke . getKeyStroke ( KeyEvent . VK_R , ActionEvent . CTRL_MASK | ActionEvent . SHIFT_MASK ) ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 4494402222740250203L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
/* Replace seed before reloading */
2009-06-30 13:31:42 +00:00
if ( getSimulation ( ) ! = null ) {
getSimulation ( ) . setRandomSeed ( getSimulation ( ) . getRandomSeed ( ) + 1 ) ;
reloadSimulationAction . actionPerformed ( null ) ;
}
2009-05-28 12:55:14 +00:00
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
return getSimulation ( ) ! = null ;
2009-05-28 12:55:14 +00:00
}
} ;
2012-05-31 18:01:53 +02:00
GUIAction saveSimulationAction = new GUIAction ( " Save simulation as... " , KeyEvent . VK_S ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 1132582220401954286L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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 ;
}
} ;
2012-05-31 18:01:53 +02:00
/ * GUIAction closePluginsAction = new GUIAction ( " Close all plugins " ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 37575622808266989L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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 ( ) ;
}
2012-05-31 18:01:53 +02:00
} ; * /
GUIAction exportExecutableJARAction = new GUIAction ( " Export simulation... " ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = - 203601967460630049L ;
public void actionPerformed ( ActionEvent e ) {
2009-10-29 10:16:05 +00:00
getSimulation ( ) . stopSimulation ( ) ;
/* Info message */
2009-10-29 17:05:13 +00:00
String [ ] options = new String [ ] { " OK " , " Cancel " } ;
int n = JOptionPane . showOptionDialog (
GUI . getTopParentContainer ( ) ,
2012-05-31 18:01:53 +02:00
" This function attempts to build an executable Cooja JAR from the current simulation. \ n " +
" The JAR will contain all simulation dependencies, including extension JAR files and mote firmware files. \ n " +
2009-10-29 10:16:05 +00:00
" \ nExecutable simulations can be used to run already prepared simulations on several computers. \ n " +
2012-05-31 18:01:53 +02:00
" \ nThis is an experimental feature. " ,
2009-10-29 17:05:13 +00:00
" Export simulation to executable JAR " , JOptionPane . OK_CANCEL_OPTION ,
JOptionPane . INFORMATION_MESSAGE , null , options , options [ 0 ] ) ;
if ( n ! = JOptionPane . OK_OPTION ) {
return ;
}
2009-10-29 10:16:05 +00:00
2009-10-29 17:05:13 +00:00
/* Select output file */
2009-10-29 10:16:05 +00:00
JFileChooser fc = new JFileChooser ( ) ;
2009-10-29 17:05:13 +00:00
FileFilter jarFilter = new FileFilter ( ) {
public boolean accept ( File file ) {
if ( file . isDirectory ( ) ) {
return true ;
}
if ( file . getName ( ) . endsWith ( " .jar " ) ) {
return true ;
}
return false ;
}
public String getDescription ( ) {
return " Java archive " ;
}
public String toString ( ) {
return " .jar " ;
}
} ;
fc . setFileFilter ( jarFilter ) ;
2009-11-25 10:29:21 +00:00
File suggest = new File ( getExternalToolsSetting ( " EXECUTE_JAR_LAST " , " cooja_simulation.jar " ) ) ;
fc . setSelectedFile ( suggest ) ;
2009-10-29 17:05:13 +00:00
int returnVal = fc . showSaveDialog ( GUI . getTopParentContainer ( ) ) ;
2009-10-29 10:16:05 +00:00
if ( returnVal ! = JFileChooser . APPROVE_OPTION ) {
return ;
}
2009-10-29 17:05:13 +00:00
File outputFile = fc . getSelectedFile ( ) ;
if ( outputFile . exists ( ) ) {
options = new String [ ] { " Overwrite " , " Cancel " } ;
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 , options [ 0 ] ) ;
if ( n ! = JOptionPane . YES_OPTION ) {
return ;
}
outputFile . delete ( ) ;
2009-10-29 10:16:05 +00:00
}
2012-03-23 15:14:24 +01:00
2009-10-29 17:05:13 +00:00
final File finalOutputFile = outputFile ;
2009-11-25 10:29:21 +00:00
setExternalToolsSetting ( " EXECUTE_JAR_LAST " , outputFile . getPath ( ) ) ;
2009-10-29 17:05:13 +00:00
new Thread ( ) {
public void run ( ) {
try {
2012-03-23 15:14:24 +01:00
ExecuteJAR . buildExecutableJAR ( GUI . this , finalOutputFile ) ;
2009-10-29 17:05:13 +00:00
} catch ( RuntimeException ex ) {
JOptionPane . showMessageDialog ( GUI . getTopParentContainer ( ) ,
ex . getMessage ( ) ,
" Error " , JOptionPane . ERROR_MESSAGE ) ;
}
}
} . start ( ) ;
2009-10-29 10:16:05 +00:00
}
public boolean shouldBeEnabled ( ) {
return getSimulation ( ) ! = null ;
}
} ;
2012-06-08 12:16:47 +02:00
GUIAction exitCoojaAction = new GUIAction ( " Exit " , 'x' ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 7523822251658687665L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
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 ;
}
} ;
2012-05-31 18:01:53 +02:00
GUIAction startStopSimulationAction = new GUIAction ( " Start simulation " , KeyStroke . getKeyStroke ( KeyEvent . VK_S , ActionEvent . CTRL_MASK ) ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 6750107157493939710L ;
public void actionPerformed ( ActionEvent e ) {
2009-05-28 12:55:14 +00:00
/* 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 ) {
2012-05-31 18:01:53 +02:00
putValue ( NAME , " Start simulation " ) ;
2009-05-28 12:55:14 +00:00
} else if ( getSimulation ( ) . isRunning ( ) ) {
2012-05-31 18:01:53 +02:00
putValue ( NAME , " Pause simulation " ) ;
2009-05-28 12:55:14 +00:00
} else {
putValue ( NAME , " Start simulation " ) ;
}
super . setEnabled ( newValue ) ;
}
2009-05-28 14:53:26 +00:00
public boolean shouldBeEnabled ( ) {
2012-06-04 16:14:05 +02:00
return getSimulation ( ) ! = null & & getSimulation ( ) . isRunnable ( ) ;
2009-05-28 12:55:14 +00:00
}
} ;
2009-05-28 14:53:26 +00:00
class StartPluginGUIAction extends GUIAction {
2012-06-05 17:03:07 +02:00
private static final long serialVersionUID = 7368495576372376196L ;
public StartPluginGUIAction ( String name ) {
2009-05-28 14:53:26 +00:00
super ( name ) ;
}
2009-09-18 16:13:31 +00:00
public void actionPerformed ( final ActionEvent e ) {
new Thread ( new Runnable ( ) {
public void run ( ) {
2012-03-23 15:14:24 +01:00
Class < Plugin > pluginClass =
2009-09-18 16:13:31 +00:00
( Class < Plugin > ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " class " ) ;
Mote mote = ( Mote ) ( ( JMenuItem ) e . getSource ( ) ) . getClientProperty ( " mote " ) ;
tryStartPlugin ( pluginClass , myGUI , mySimulation , mote ) ;
}
} ) . start ( ) ;
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
}
2012-06-05 17:03:07 +02:00
2009-05-28 14:53:26 +00:00
GUIAction removeAllMotesAction = new GUIAction ( " Remove all motes " ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 4709776747913364419L ;
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
}
} ;
2009-06-30 12:45:51 +00:00
GUIAction showQuickHelpAction = new GUIAction ( " Quick help " , KeyStroke . getKeyStroke ( KeyEvent . VK_F1 , 0 ) ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 3151729036597971681L ;
public void actionPerformed ( ActionEvent e ) {
2009-06-30 12:45:51 +00:00
if ( ! ( e . getSource ( ) instanceof JCheckBoxMenuItem ) ) {
return ;
}
boolean show = ( ( JCheckBoxMenuItem ) e . getSource ( ) ) . isSelected ( ) ;
quickHelpTextPane . setVisible ( show ) ;
quickHelpScroll . setVisible ( show ) ;
2012-06-01 10:49:56 +02:00
setExternalToolsSetting ( " SHOW_QUICKHELP " , new Boolean ( show ) . toString ( ) ) ;
2009-06-30 12:45:51 +00:00
( ( JPanel ) frame . getContentPane ( ) ) . revalidate ( ) ;
updateDesktopSize ( getDesktopPane ( ) ) ;
}
public boolean shouldBeEnabled ( ) {
2012-06-01 10:49:56 +02:00
return true ;
}
} ;
GUIAction showGettingStartedAction = new GUIAction ( " Getting started " ) {
private static final long serialVersionUID = 2382848024856978524L ;
public void actionPerformed ( ActionEvent e ) {
loadQuickHelp ( " GETTING_STARTED " ) ;
JCheckBoxMenuItem checkBox = ( ( JCheckBoxMenuItem ) showQuickHelpAction . getValue ( " checkbox " ) ) ;
if ( checkBox = = null ) {
return ;
}
if ( checkBox . isSelected ( ) ) {
return ;
}
checkBox . doClick ( ) ;
}
public boolean shouldBeEnabled ( ) {
2009-06-30 12:45:51 +00:00
return true ;
}
} ;
GUIAction showKeyboardShortcutsAction = new GUIAction ( " Keyboard shortcuts " ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 2382848024856978524L ;
public void actionPerformed ( ActionEvent e ) {
2009-06-30 12:45:51 +00:00
loadQuickHelp ( " KEYBOARD_SHORTCUTS " ) ;
JCheckBoxMenuItem checkBox = ( ( JCheckBoxMenuItem ) showQuickHelpAction . getValue ( " checkbox " ) ) ;
if ( checkBox = = null ) {
return ;
}
if ( checkBox . isSelected ( ) ) {
return ;
}
checkBox . doClick ( ) ;
}
public boolean shouldBeEnabled ( ) {
return true ;
}
} ;
2012-05-31 18:01:53 +02:00
GUIAction showBufferSettingsAction = new GUIAction ( " Buffer sizes... " ) {
2010-12-02 15:29:07 +00:00
private static final long serialVersionUID = 7018661735211901837L ;
public void actionPerformed ( ActionEvent e ) {
2009-07-03 13:37:40 +00:00
if ( mySimulation = = null ) {
return ;
}
BufferSettings . showDialog ( myDesktopPane , mySimulation ) ;
}
public boolean shouldBeEnabled ( ) {
return mySimulation ! = null ;
}
} ;
2012-03-23 15:14:24 +01:00
2006-08-21 12:11:16 +00:00
}