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 }