View Javadoc

    1   /*
    2    * @(#) DSOLFrame.java Oct 13, 2003
    3    *
    4    * Copyright (c) 2002-2005 Delft University of Technology Jaffalaan 5, 2628 BX
    5    * Delft, the Netherlands. All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the Lesser General Public License
    9    */
    10  package nl.tudelft.simulation.dsol.gui.windows;
    11
    12  import java.awt.BorderLayout;
    13  import java.awt.Color;
    14  import java.awt.Component;
    15  import java.awt.Dimension;
    16  import java.awt.Toolkit;
    17  import java.io.IOException;
    18  import java.lang.reflect.Constructor;
    19  import java.net.URL;
    20  import java.util.ArrayList;
    21  import java.util.Iterator;
    22  import java.util.List;
    23
    24  import javax.swing.Action;
    25  import javax.swing.BorderFactory;
    26  import javax.swing.JEditorPane;
    27  import javax.swing.JFrame;
    28  import javax.swing.JMenu;
    29  import javax.swing.JMenuBar;
    30  import javax.swing.JPanel;
    31  import javax.swing.JScrollPane;
    32  import javax.swing.JSeparator;
    33  import javax.swing.JTree;
    34  import javax.swing.SwingConstants;
    35  import javax.swing.UIManager;
    36  import javax.swing.WindowConstants;
    37
    38  import nl.tudelft.simulation.dsol.experiment.Experiment;
    39  import nl.tudelft.simulation.dsol.gui.DSOLApplicationInterface;
    40  import nl.tudelft.simulation.dsol.gui.UIInitializer;
    41  import nl.tudelft.simulation.dsol.gui.menu.HelpMenu;
    42  import nl.tudelft.simulation.dsol.gui.panels.ControlPanel;
    43  import nl.tudelft.simulation.dsol.gui.panels.ExperimentTree;
    44  import nl.tudelft.simulation.dsol.gui.panels.Statusbar;
    45  import nl.tudelft.simulation.dsol.gui.panels.TabbedPane;
    46  import nl.tudelft.simulation.event.EventInterface;
    47  import nl.tudelft.simulation.event.EventListenerInterface;
    48  import nl.tudelft.simulation.language.io.URLResource;
    49  import nl.tudelft.simulation.language.reflection.ClassUtil;
    50  import nl.tudelft.simulation.logger.Logger;
    51
    52  import org.jdom.Element;
    53  import org.jdom.input.SAXBuilder;
    54
    55  /***
    56   * DSOL Frame <br>
    57   * (c) copyright 2002-2005 <a href="http://www.simulation.tudelft.nl">Delft
    58   * University of Technology </a>, the Netherlands. <br>
    59   * See for project information <a
    60   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    61   * License of use: <a href="http://www.gnu.org/copyleft/lesser.html">Lesser
    62   * General Public License (LGPL) </a>, no warranty.
    63   *
    64   * @version $Revision$ $Date$
    65   * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja">Peter Jacobs </a>
    66   */
    67  public class DSOLFrame extends JFrame implements EventListenerInterface
    68  {
    69  	/*** builder the xerces parser with validation turned on */
    70  	private static SAXBuilder builder = new SAXBuilder(
    71  			"org.apache.xerces.parsers.SAXParser", true);
    72
    73  	static
    74  	{
    75  		// turns on Schema Validation with Xerces
    76  		builder.setFeature("http://xml.org/sax/features/validation", true);
    77  		builder.setFeature("http://apache.org/xml/features/validation/schema",
    78  				true);
    79
    80  		// Let's find the XSD file
    81  		String xsd = URLResource.getResource("/navigation.xsd")
    82  				.toExternalForm();
    83  		builder
    84  				.setProperty(
    85  						"http://apache.org/xml/properties/schema/external-schemaLocation",
    86  						"http://www.simulation.tudelft.nl/dsol " + xsd);
    87  	}
    88
    89  	/*** the preferredSize is the preferredSize of the panel */
    90  	public static final Dimension PREFERRED_SIZE = new Dimension(400, 375);
    91
    92  	/*** the application */
    93  	protected DSOLApplicationInterface application = null;
    94
    95  	/*** tabbedPanel */
    96  	protected TabbedPane tabbedPanel = null;
    97
    98  	/*** the experimentTree */
    99  	protected JTree experimentTree = null;
    100
    101 	/*** the statusbar */
    102 	protected Statusbar statusbar = null;
    103
    104 	/*** the controlPanel */
    105 	protected ControlPanel controlPanel = null;
    106
    107 	/***
    108 	 * constructs a new DSOLFrame
    109 	 *
    110 	 * @param application the application
    111 	 * @param navigation the URL address of the xml-based navigation structure.
    112 	 */
    113 	public DSOLFrame(final DSOLApplicationInterface application,
    114 			final URL navigation)
    115 	{
    116 		super("DSOL main window");
    117
    118 		try
    119 		{
    120 			UIManager
    121 					.setLookAndFeel("com.jgoodies.plaf.plastic.Plastic3DLookAndFeel");
    122
    123 			// The custom DSOL Color Look&Feel
    124 			UIInitializer.initialize();
    125 			Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    126 			this.setLocation((int) Math.round(screenSize.width * 0.5 - 0.5
    127 					* PREFERRED_SIZE.width), (int) Math.round(screenSize.height
    128 					* 0.33 - 0.5 * PREFERRED_SIZE.height));
    129 			this.application = application;
    130 			this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    131 			this.application.addListener(this,
    132 					DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT);
    133 		} catch (Exception exception)
    134 		{
    135 			Logger.warning(this, "DSOLFrame", exception);
    136 		}
    137 		this.initialize(navigation);
    138 		this.pack();
    139 		this.setVisible(true);
    140 	}
    141
    142 	/***
    143 	 * initializes the DSOL Frame
    144 	 *
    145 	 * @param navigation the navigation file
    146 	 */
    147 	private void initialize(final URL navigation)
    148 	{
    149 		JPanel contentPane = new JPanel();
    150 		contentPane.setPreferredSize(PREFERRED_SIZE);
    151 		contentPane.setLayout(new BorderLayout());
    152 		this.setContentPane(contentPane);
    153
    154 		this.setJMenuBar(this.createMenuBar(navigation));
    155
    156 		this.controlPanel = new ControlPanel(this.application);
    157
    158 		this.tabbedPanel = new TabbedPane(SwingConstants.TOP);
    159 		this.tabbedPanel.setBorder(BorderFactory.createCompoundBorder(
    160 				BorderFactory.createEtchedBorder(), BorderFactory
    161 						.createEmptyBorder()));
    162 		contentPane.add(this.tabbedPanel, BorderLayout.CENTER);
    163 		this.statusbar = new Statusbar(this.application);
    164
    165 		this.experimentTree = new JTree();
    166 		this.experimentTree.setEditable(false);
    167 		this.experimentTree.setFocusable(false);
    168
    169 		URL about = URLResource.getResource("/html/about.html");
    170 		JEditorPane aboutPane = null;
    171 		try
    172 		{
    173 			aboutPane = new JEditorPane(about);
    174 		} catch (IOException exception)
    175 		{
    176 			Logger.warning(this, "initialize", exception);
    177 		}
    178 		aboutPane.setAlignmentY(Component.BOTTOM_ALIGNMENT);
    179 		aboutPane.setEditable(false);
    180 		this.tabbedPanel.add("About", aboutPane);
    181 	}
    182
    183 	/***
    184 	 * creates a menu bar
    185 	 *
    186 	 * @param navigation the xml-based navigation
    187 	 *
    188 	 * @return the menu bar
    189 	 */
    190 	private JMenuBar createMenuBar(final URL navigation)
    191 	{
    192 		Logger.info(this, "createMenuBar", "using "
    193 				+ navigation.toExternalForm());
    194 		try
    195 		{
    196 			JMenuBar menuBar = new JMenuBar();
    197 			menuBar.setBorder(BorderFactory.createLineBorder(Color.GRAY));
    198
    199 			Element rootElement = builder.build(navigation).getRootElement();
    200 			for (Iterator i = rootElement.getChildren("menu").iterator(); i
    201 					.hasNext();)
    202 			{
    203 				Element menu = (Element) i.next();
    204 				menuBar.add(this.parseMenu(menu));
    205 			}
    206 			menuBar.add(new HelpMenu(this.application));
    207 			return menuBar;
    208 		} catch (Exception exception)
    209 		{
    210 			Logger.warning(this, "initialze2", exception.getMessage());
    211 			return null;
    212 		}
    213 	}
    214
    215 	/***
    216 	 * parses an xml-based element into a JMenu
    217 	 *
    218 	 * @param element the JDOM element
    219 	 * @return the JMenu
    220 	 * @throws Exception on IOException
    221 	 */
    222 	private JMenu parseMenu(final Element element) throws Exception
    223 	{
    224 		JMenu menu = new JMenu(element.getAttributeValue("name"));
    225 		for (Iterator i = element.getChildren().iterator(); i.hasNext();)
    226 		{
    227 			Element child = (Element) i.next();
    228 			if (child.getName().equals("menu"))
    229 			{
    230 				menu.add(this.parseMenu(child));
    231 			} else if (child.getName().equals("separator"))
    232 			{
    233 				menu.add(new JSeparator());
    234 			} else if (child.getName().equals("action"))
    235 			{
    236 				Class actionClass = Class.forName(child
    237 						.getAttributeValue("className"));
    238 				List arguments = new ArrayList();
    239 				arguments.add(this.application);
    240 				for (Iterator ii = child.getChildren("argument").iterator(); ii
    241 						.hasNext();)
    242 				{
    243 					arguments.add(((Element) ii.next()).getValue());
    244 				}
    245 				Class[] argumentClasses = new Class[arguments.size()];
    246 				argumentClasses[0] = DSOLApplicationInterface.class;
    247 				for (int loop = 0; loop < argumentClasses.length - 1; loop++)
    248 				{
    249 					argumentClasses[loop + 1] = String.class;
    250 				}
    251 				Constructor actionConstructor = ClassUtil.resolveConstructor(
    252 						actionClass, argumentClasses);
    253 				Object action = actionConstructor.newInstance(arguments
    254 						.toArray());
    255 				if (action instanceof Action)
    256 				{
    257 					menu.add((Action) action);
    258 				} else if (action instanceof JMenu)
    259 				{
    260 					menu.add((JMenu) action);
    261 				}
    262 			}
    263 		}
    264 		return menu;
    265 	}
    266
    267 	/***
    268 	 * @see nl.tudelft.simulation.event.EventListenerInterface
    269 	 *      #notify(nl.tudelft.simulation.event.EventInterface)
    270 	 */
    271 	public void notify(final EventInterface event)
    272 	{
    273 		if (event.getSource().equals(this.application)
    274 				&& event.getType().equals(
    275 						DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT))
    276 		{
    277 			this.tabbedPanel.remove("Description");
    278 			this.tabbedPanel.remove("Experiment");
    279 			this.tabbedPanel.remove("Control");
    280 			if (event.getContent() != null)
    281 			{
    282 				Experiment experiment = (Experiment) event.getContent();
    283 				try
    284 				{
    285 					String descriptionName = "/";
    286 					if (experiment.getModel().getClass().getPackage() != null)
    287 					{
    288 						descriptionName = descriptionName
    289 								+ experiment.getModel().getClass().getPackage()
    290 										.getName().replace('.', '/');
    291 					}
    292 					descriptionName = descriptionName + "/package.html";
    293 					URL description = experiment.getModel().getClass()
    294 							.getResource(descriptionName);
    295 					JEditorPane descriptionPane = null;
    296 					descriptionPane = new JEditorPane(description);
    297 					descriptionPane.setAlignmentY(Component.BOTTOM_ALIGNMENT);
    298 					descriptionPane.setEditable(false);
    299 					this.tabbedPanel.add("Description", 0, new JScrollPane(
    300 							descriptionPane));
    301 				} catch (IOException exception)
    302 				{
    303 					Logger
    304 							.fine(this, "initialize",
    305 									"experiment has no package.html describing the experiment");
    306 				}
    307 				this.setTitle("DSOL main window ("
    308 						+ experiment.getProperty(Experiment.EXPERIMENT_NAME)
    309 						+ ")");
    310 				this.experimentTree.setModel(new ExperimentTree(experiment));
    311 				this.tabbedPanel.add("Experiment", 1, new JScrollPane(
    312 						this.experimentTree));
    313 				this.tabbedPanel.add("Control", 2, this.controlPanel);
    314 				this.getContentPane().add(this.statusbar, BorderLayout.SOUTH);
    315 			} else
    316 			{
    317 				this.setTitle("DSOL main window");
    318 				this.getContentPane().remove(this.statusbar);
    319 			}
    320 			this.validate();
    321 			this.repaint();
    322 		}
    323 	}
    324 }