📄 gui.java
字号:
/* * Copyright (c) 2006, Swedish Institute of Computer Science. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. 2. Redistributions in * binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. 3. Neither the name of the * Institute nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: GUI.java,v 1.64 2007/09/30 12:02:33 fros4943 Exp $ */package se.sics.cooja;import java.awt.*;import java.awt.event.*;import java.beans.PropertyVetoException;import java.io.*;import java.net.URL;import java.net.URLClassLoader;import java.util.*;import java.util.List;import javax.swing.*;import javax.swing.event.MenuEvent;import javax.swing.event.MenuListener;import javax.swing.filechooser.FileFilter;import org.apache.log4j.Logger;import org.apache.log4j.xml.DOMConfigurator;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;import se.sics.cooja.MoteType.MoteTypeCreationException;import se.sics.cooja.contikimote.*;import se.sics.cooja.dialogs.*;import se.sics.cooja.plugins.*;/** * Main file of COOJA Simulator. Typically contains a visualizer for the * simulator, but can also be started without visualizer. * * This class loads external Java classes (in project directories), and handles the * 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. * * @author Fredrik Osterlind */public class GUI { /** * External tools default Win32 settings filename. */ public static final String EXTERNAL_TOOLS_WIN32_SETTINGS_FILENAME = "/external_tools_win32.config"; /** * External tools default Mac OS X settings filename. */ public static final String EXTERNAL_TOOLS_MACOSX_SETTINGS_FILENAME = "/external_tools_macosx.config"; /** * External tools default Linux/Unix settings filename. */ public static final String EXTERNAL_TOOLS_LINUX_SETTINGS_FILENAME = "/external_tools_linux.config"; /** * External tools user settings filename. */ public static final String EXTERNAL_TOOLS_USER_SETTINGS_FILENAME = ".cooja.user.properties"; public static File externalToolsUserSettingsFile = new File(System.getProperty("user.home"), EXTERNAL_TOOLS_USER_SETTINGS_FILENAME); private static boolean externalToolsUserSettingsFileReadOnly = false; private static String specifiedContikiPath = null; /** * Logger settings filename. */ public static final String LOG_CONFIG_FILE = "log4j_config.xml"; /** * Default project configuration filename. */ public static final String PROJECT_DEFAULT_CONFIG_FILENAME = "/cooja_default.config"; /** * User project configuration filename. */ public static final String PROJECT_CONFIG_FILENAME = "cooja.config"; /** * File filter only showing saved simulations files (*.csc). */ public static final FileFilter SAVED_SIMULATIONS_FILES = new FileFilter() { public boolean accept(File file) { if (file.isDirectory()) { return true; } if (file.getName().endsWith(".csc")) { return true; } return false; } public String getDescription() { return "COOJA Configuration files"; } public String toString() { return ".csc"; } }; /** * Main frame for current GUI. Null when COOJA is run without visualizer! */ public static JFrame frame; private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(GUI.class); // External tools setting names private static Properties defaultExternalToolsSettings; private static Properties currentExternalToolsSettings; private static final String externalToolsSettingNames[] = new String[] { "PATH_CONTIKI", "PATH_COOJA_CORE_RELATIVE", "PATH_MAKE", "PATH_SHELL", "PATH_C_COMPILER", "COMPILER_ARGS", "PATH_LINKER", "LINK_COMMAND_1", "LINK_COMMAND_2", "PATH_AR", "AR_COMMAND_1", "AR_COMMAND_2", "PATH_OBJDUMP", "OBJDUMP_ARGS", "PATH_JAVAC", "CONTIKI_STANDARD_PROCESSES", "CONTIKI_MAIN_TEMPLATE_FILENAME", "CMD_GREP_PROCESSES", "REGEXP_PARSE_PROCESSES", "CMD_GREP_INTERFACES", "REGEXP_PARSE_INTERFACES", "CMD_GREP_SENSORS", "REGEXP_PARSE_SENSORS", "DEFAULT_PROJECTDIRS", "CORECOMM_TEMPLATE_FILENAME", "MAPFILE_DATA_START", "MAPFILE_DATA_SIZE", "MAPFILE_BSS_START", "MAPFILE_BSS_SIZE", "MAPFILE_VAR_NAME", "MAPFILE_VAR_ADDRESS_1", "MAPFILE_VAR_ADDRESS_2", "MAPFILE_VAR_SIZE_1", "MAPFILE_VAR_SIZE_2", "PARSE_WITH_COMMAND", "PARSE_COMMAND", "COMMAND_VAR_NAME_ADDRESS", "COMMAND_DATA_START", "COMMAND_DATA_END", "COMMAND_BSS_START", "COMMAND_BSS_END", }; private static final int FRAME_NEW_OFFSET = 30; private static final int FRAME_STANDARD_WIDTH = 150; private static final int FRAME_STANDARD_HEIGHT = 300; private GUI myGUI; private Simulation mySimulation; protected GUIEventHandler guiEventHandler = new GUIEventHandler(); private JMenu menuPlugins, menuMoteTypeClasses, menuMoteTypes; private JMenu menuOpenSimulation, menuConfOpenSimulation; private Vector<Class<? extends Plugin>> menuMotePluginClasses; private JDesktopPane myDesktopPane; private Vector<Plugin> startedPlugins = new Vector<Plugin>(); // Platform configuration variables // Maintained via method reparseProjectConfig() private ProjectConfig projectConfig; private Vector<File> currentProjectDirs = new Vector<File>(); private ClassLoader projectDirClassLoader; private Vector<Class<? extends MoteType>> moteTypeClasses = new Vector<Class<? extends MoteType>>(); private Vector<Class<? extends Plugin>> pluginClasses = new Vector<Class<? extends Plugin>>(); private Vector<Class<? extends Plugin>> pluginClassesTemporary = new Vector<Class<? extends Plugin>>(); private Vector<Class<? extends RadioMedium>> radioMediumClasses = new Vector<Class<? extends RadioMedium>>(); private Vector<Class<? extends IPDistributor>> ipDistributorClasses = new Vector<Class<? extends IPDistributor>>(); private Vector<Class<? extends Positioner>> positionerClasses = new Vector<Class<? extends Positioner>>(); // Mote highlight observable private class HighlightObservable extends Observable { private void highlightMote(Mote mote) { setChanged(); notifyObservers(mote); } } private HighlightObservable moteHighlightObservable = new HighlightObservable(); /** * Creates a new COOJA Simulator GUI. * * @param desktop Desktop pane */ public GUI(JDesktopPane desktop) { myGUI = this; mySimulation = null; myDesktopPane = desktop; if (menuPlugins == null) { menuPlugins = new JMenu("Plugins"); } if (menuMotePluginClasses == null) { menuMotePluginClasses = new Vector<Class<? extends Plugin>>(); } // Load default and overwrite with user settings (if any) loadExternalToolsDefaultSettings(); loadExternalToolsUserSettings(); if (specifiedContikiPath != null) { setExternalToolsSetting("PATH_CONTIKI", specifiedContikiPath); } // Register default project directories String defaultProjectDirs = getExternalToolsSetting( "DEFAULT_PROJECTDIRS", null); if (defaultProjectDirs != null) { String[] defaultProjectDirsArr = defaultProjectDirs.split(";"); if (defaultProjectDirsArr.length > 0) { for (String defaultProjectDir : defaultProjectDirsArr) { File projectDir = new File(defaultProjectDir); if (projectDir.exists() && projectDir.isDirectory()) { currentProjectDirs.add(projectDir); } } } } // Load extendable parts (using current project config) try { reparseProjectConfig(); } catch (ParseProjectsException e) { logger.fatal("Error when loading project directories: " + e.getMessage()); e.printStackTrace(); if (myDesktopPane != null) { JOptionPane.showMessageDialog(frame, "Loading project directories failed.\nStack trace printed to console.", "Error", JOptionPane.ERROR_MESSAGE); } } // Start all standard GUI plugins for (Class<? extends Plugin> visPluginClass : pluginClasses) { int pluginType = visPluginClass.getAnnotation(PluginType.class).value(); if (pluginType == PluginType.COOJA_STANDARD_PLUGIN) { startPlugin(visPluginClass, this, null, null); } } } /** * Add mote highlight observer. * * @see #deleteTickObserver(Observer) * @param newObserver * New observer */ public void addMoteHighligtObserver(Observer newObserver) { moteHighlightObservable.addObserver(newObserver); } /** * Delete an mote highlight observer. * * @see #addTickObserver(Observer) * @param observer * Observer to delete */ public void deleteMoteHighligtObserver(Observer observer) { moteHighlightObservable.deleteObserver(observer); } /** * @return True if simulator is visualized */ public boolean isVisualized() { return frame != null; } /** * EXPERIMENTAL! * Tries to create/remove simulator visualizer. * * @param visualized Visualized */ public void setVisualized(boolean visualized) { if (!isVisualized() && visualized) { configureFrame(myGUI, false); } else { frame.setVisible(false); frame.dispose(); frame = null; } } private Vector<File> getFileHistory() { Vector<File> history = new Vector<File>(); // Fetch current history String[] historyArray = getExternalToolsSetting("SIMCFG_HISTORY", "").split(";"); for (String file: historyArray) { history.add(new File(file)); } return history; } private void addToFileHistory(File file) { // Fetch current history String[] history = getExternalToolsSetting("SIMCFG_HISTORY", "").split(";"); // Create new history String[] newHistory = null; if (history == null || history.length <= 1 && history[0].equals("")) { newHistory = new String[1]; } else { newHistory = new String[Math.min(5, history.length+1)]; System.arraycopy(history, 0, newHistory, 1, newHistory.length-1); } newHistory[0] = file.getAbsolutePath(); // Abort if file added is equal to last file if (history.length >= 1 && file.getAbsolutePath().equals(new File(history[0]).getAbsolutePath())) { return; } String newHistoryConfig = null; for (String path: newHistory) { if (newHistoryConfig == null) { newHistoryConfig = path; } else { newHistoryConfig += ";" + path; } } setExternalToolsSetting("SIMCFG_HISTORY", newHistoryConfig); saveExternalToolsUserSettings(); } private void updateOpenHistoryMenuItems() { menuConfOpenSimulation.removeAll(); JMenuItem browseItem = new JMenuItem("Browse..."); browseItem.setActionCommand("confopen sim"); browseItem.addActionListener(guiEventHandler); menuConfOpenSimulation.add(browseItem); menuConfOpenSimulation.add(new JSeparator()); Vector<File> openFilesHistory = getFileHistory(); for (File file: openFilesHistory) { JMenuItem lastItem = new JMenuItem(file.getName()); lastItem.setActionCommand("confopen last sim"); lastItem.putClientProperty("file", file); lastItem.setToolTipText(file.getAbsolutePath());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -