View Javadoc

1   /*
2    * @(#) AnimationPanel.java Nov 3, 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.animation2D;
11  
12  import java.awt.Color;
13  import java.awt.Dimension;
14  import java.awt.Graphics;
15  import java.awt.Graphics2D;
16  import java.awt.event.MouseListener;
17  import java.awt.geom.Rectangle2D;
18  import java.lang.reflect.Constructor;
19  import java.rmi.RemoteException;
20  import java.util.Collections;
21  import java.util.Iterator;
22  import java.util.SortedSet;
23  import java.util.TreeSet;
24  
25  import javax.naming.Binding;
26  import javax.naming.NamingEnumeration;
27  import javax.naming.event.EventContext;
28  import javax.naming.event.NamespaceChangeListener;
29  import javax.naming.event.NamingEvent;
30  import javax.naming.event.NamingExceptionEvent;
31  import javax.vecmath.Point4i;
32  
33  import nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface;
34  import nl.tudelft.simulation.dsol.experiment.Experiment;
35  import nl.tudelft.simulation.dsol.gui.DSOLApplicationInterface;
36  import nl.tudelft.simulation.dsol.gui.animation2D.mouse.InputListener;
37  import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
38  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
39  import nl.tudelft.simulation.event.Event;
40  import nl.tudelft.simulation.event.EventInterface;
41  import nl.tudelft.simulation.event.EventListenerInterface;
42  import nl.tudelft.simulation.language.reflection.ClassUtil;
43  import nl.tudelft.simulation.logger.Logger;
44  import nl.tudelft.simulation.naming.InitialEventContext;
45  
46  /***
47   * The AnimationPanel <br>
48   * (c) copyright 2002-2005 <a href="http://www.simulation.tudelft.nl">Delft
49   * University of Technology </a>, the Netherlands. <br>
50   * See for project information <a
51   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
52   * License of use: <a href="http://www.gnu.org/copyleft/lesser.html">Lesser
53   * General Public License (LGPL) </a>, no warranty.
54   * 
55   * @version $Revision$ $Date$
56   * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja">Peter Jacobs </a>
57   */
58  public class AnimationPanel extends GridPanel implements
59  		EventListenerInterface, NamespaceChangeListener
60  {
61  	/*** the elements of this panel */
62  	private SortedSet elements = Collections.synchronizedSortedSet(new TreeSet(
63  			new Renderable2DComparator()));
64  
65  	/*** the application */
66  	private DSOLApplicationInterface application = null;
67  
68  	/*** the eventContext */
69  	private EventContext context = null;
70  
71  	/***
72  	 * the grid must be drawn after all other elements. Therefore we must
73  	 * override the gridPanel.paintGrid.
74  	 */
75  	private boolean showGrid = true;
76  
77  	/*** a line that helps the user to see where he is dragging */
78  	private Point4i dragLine = new Point4i();
79  
80  	/*** enable drag line */
81  	private boolean dragLineEnabled = false;
82  
83  	/***
84  	 * constructs a new AnimationPanel
85  	 * 
86  	 * @param extent the extent of the panel
87  	 * @param size the size of the panel.
88  	 * @param application the application
89  	 */
90  	public AnimationPanel(final Rectangle2D extent, final Dimension size,
91  			final DSOLApplicationInterface application)
92  	{
93  		super(extent, size);
94  		super.showGrid = false;
95  		this.application = application;
96  		String mouseEditorClassName = this.application.getProperties()
97  				.getProperty("dsol-gui.animation.panel.mouseEditor");
98  		InputListener listener = new InputListener(application, this);
99  		if (mouseEditorClassName != null)
100 		{
101 			try
102 			{
103 				Class editorClass = Class.forName(mouseEditorClassName);
104 				Constructor constructor = ClassUtil.resolveConstructor(
105 						editorClass, new Class[]{
106 								DSOLApplicationInterface.class,
107 								AnimationPanel.class});
108 				this.addMouseListener((MouseListener) constructor
109 						.newInstance(new Object[]{application, this}));
110 
111 			} catch (Exception exception)
112 			{
113 				Logger.warning(this, "<init>", "could not load "
114 						+ mouseEditorClassName);
115 				listener = new InputListener(application, this);
116 			}
117 		} else
118 		{
119 			this.addMouseListener(listener);
120 		}
121 		this.addMouseMotionListener(listener);
122 		this.addMouseWheelListener(listener);
123 		this.addKeyListener(listener);
124 		this.initialize();
125 	}
126 
127 	/***
128 	 * initializes the panel
129 	 */
130 	private void initialize()
131 	{
132 		try
133 		{
134 			this.application.addListener(this,
135 					DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT);
136 			this.notify(new Event(
137 					DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT,
138 					this.application, this.application.getExperiment()));
139 		} catch (RemoteException exception)
140 		{
141 			Logger.warning(this, "initialize", exception);
142 		}
143 	}
144 
145 	/***
146 	 * @see javax.swing.JComponent #paintComponent(java.awt.Graphics)
147 	 */
148 	public void paintComponent(final Graphics g)
149 	{
150 		super.paintComponent(g);
151 		Graphics2D g2 = (Graphics2D) g;
152 		synchronized (this.elements)
153 		{
154 			for (Iterator i = this.elements.iterator(); i.hasNext();)
155 			{
156 				((Renderable2DInterface) i.next()).paint(g2, this.getExtent(),
157 						this.getSize(), this);
158 			}
159 		}
160 		if (this.showGrid)
161 		{
162 			this.drawGrid(g);
163 		}
164 
165 		// Draw dragline
166 		if (this.dragLineEnabled)
167 		{
168 			g.setColor(Color.BLACK);
169 			g.drawLine(this.dragLine.w, this.dragLine.x, this.dragLine.y,
170 					this.dragLine.z);
171 			this.dragLineEnabled = false;
172 		}
173 	}
174 
175 	/***
176 	 * @see nl.tudelft.simulation.event.EventListenerInterface
177 	 *      #notify(nl.tudelft.simulation.event.EventInterface)
178 	 */
179 	public void notify(final EventInterface event) throws RemoteException
180 	{
181 		if (event.getSource() instanceof AnimatorInterface
182 				&& event.getType().equals(
183 						AnimatorInterface.UPDATE_ANIMATION_EVENT))
184 		{
185 			if (this.getWidth() > 0 || this.getHeight() > 0)
186 			{
187 				this.repaint();
188 			}
189 			return;
190 		}
191 		if (event.getSource() instanceof AnimatorInterface
192 				&& event.getType().equals(
193 						SimulatorInterface.START_REPLICATION_EVENT))
194 		{
195 			this.elements.clear();
196 			AnimatorInterface simulator = (AnimatorInterface) event.getSource();
197 			String contextName = this.application.getExperiment().getRun()
198 					+ "/treatment("
199 					+ simulator.getReplication().getRunControl().getTreatment()
200 							.getNumber() + ")/replication("
201 					+ simulator.getReplication().getNumber() + ")/animation/2D";
202 			try
203 			{
204 				if (this.context != null)
205 				{
206 					this.context.removeNamingListener(this);
207 				}
208 				this.context = (EventContext) new InitialEventContext()
209 						.lookup(contextName);
210 				this.context.addNamingListener("", EventContext.SUBTREE_SCOPE,
211 						this);
212 				NamingEnumeration list = this.context.listBindings("");
213 				while (list.hasMore())
214 				{
215 					Binding binding = (Binding) list.next();
216 					this.objectAdded(new NamingEvent(this.context, -1, binding,
217 							binding, null));
218 				}
219 				this.repaint();
220 			} catch (Exception exception)
221 			{
222 				Logger.warning(this, "notify", exception);
223 			}
224 		}
225 		if (event.getSource() instanceof Experiment
226 				&& event.getType().equals(Experiment.SIMULATOR_CHANGED_EVENT))
227 		{
228 			this.elements.clear();
229 			this.repaint();
230 			if (event.getContent() instanceof AnimatorInterface
231 					&& event.getContent() != null)
232 			{
233 				AnimatorInterface simulator = (AnimatorInterface) event
234 						.getContent();
235 				simulator.addListener(this,
236 						AnimatorInterface.UPDATE_ANIMATION_EVENT);
237 				if (simulator.getReplication() != null)
238 				{
239 					this.notify(new Event(
240 							SimulatorInterface.START_REPLICATION_EVENT,
241 							simulator, simulator));
242 				} else
243 				{
244 					simulator.addListener(this,
245 							SimulatorInterface.START_REPLICATION_EVENT);
246 				}
247 			}
248 		}
249 		if (event.getSource().equals(this.application)
250 				&& event.getType().equals(
251 						DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT))
252 		{
253 			this.elements.clear();
254 			this.repaint();
255 			if (event.getContent() != null)
256 			{
257 				Experiment experiment = (Experiment) event.getContent();
258 				experiment
259 						.addListener(this, Experiment.SIMULATOR_CHANGED_EVENT);
260 				this.notify(new Event(Experiment.SIMULATOR_CHANGED_EVENT,
261 						experiment, experiment.getSimulator()));
262 			}
263 			return;
264 		}
265 	}
266 
267 	/***
268 	 * @see javax.naming.event.NamespaceChangeListener
269 	 *      #objectAdded(javax.naming.event.NamingEvent)
270 	 */
271 	public void objectAdded(final NamingEvent namingEvent)
272 	{
273 		Renderable2DInterface element = (Renderable2DInterface) namingEvent
274 				.getNewBinding().getObject();
275 		this.elements.add(element);
276 	}
277 
278 	/***
279 	 * @see javax.naming.event.NamespaceChangeListener
280 	 *      #objectRemoved(javax.naming.event.NamingEvent)
281 	 */
282 	public void objectRemoved(final NamingEvent namingEvent)
283 	{
284 		Renderable2DInterface element = (Renderable2DInterface) namingEvent
285 				.getOldBinding().getObject();
286 		this.elements.remove(element);
287 	}
288 
289 	/***
290 	 * @see javax.naming.event.NamespaceChangeListener
291 	 *      #objectRenamed(javax.naming.event.NamingEvent)
292 	 */
293 	public void objectRenamed(final NamingEvent namingEvent)
294 	{
295 		this.objectRemoved(namingEvent);
296 		this.objectAdded(namingEvent);
297 	}
298 
299 	/***
300 	 * @see javax.naming.event.NamingListener
301 	 *      #namingExceptionThrown(javax.naming.event.NamingExceptionEvent)
302 	 */
303 	public void namingExceptionThrown(final NamingExceptionEvent namingEvent)
304 	{
305 		Logger.warning(this, "namingExceptionThrown", namingEvent
306 				.getException());
307 	}
308 
309 	/***
310 	 * @return Returns the elements.
311 	 */
312 	public SortedSet getElements()
313 	{
314 		return this.elements;
315 	}
316 
317 	/***
318 	 * @see nl.tudelft.simulation.dsol.gui.animation2D.GridPanel#isShowGrid()
319 	 */
320 	public boolean isShowGrid()
321 	{
322 		return this.showGrid;
323 	}
324 
325 	/***
326 	 * @see nl.tudelft.simulation.dsol.gui.animation2D.GridPanel#showGrid(boolean)
327 	 */
328 	public synchronized void showGrid(final boolean bool)
329 	{
330 		this.showGrid = bool;
331 		this.repaint();
332 	}
333 
334 	/***
335 	 * @return returns the dragLine.
336 	 */
337 	public Point4i getDragLine()
338 	{
339 		return this.dragLine;
340 	}
341 
342 	/***
343 	 * @return returns the dragLineEnabled.
344 	 */
345 	public boolean isDragLineEnabled()
346 	{
347 		return this.dragLineEnabled;
348 	}
349 
350 	/***
351 	 * @param dragLineEnabled the dragLineEnabled to set.
352 	 */
353 	public void setDragLineEnabled(final boolean dragLineEnabled)
354 	{
355 		this.dragLineEnabled = dragLineEnabled;
356 	}
357 }