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 }