1 package nl.tudelft.simulation.dsol.swing.animation.d2;
2
3 import org.djutils.draw.bounds.Bounds2d;
4 import org.djutils.event.Event;
5 import org.djutils.exceptions.Throw;
6 import org.djutils.logger.CategoryLogger;
7
8 import nl.tudelft.simulation.dsol.experiment.Replication;
9 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
10 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
11 import nl.tudelft.simulation.language.DsolException;
12 import nl.tudelft.simulation.naming.context.ContextInterface;
13 import nl.tudelft.simulation.naming.context.util.ContextUtil;
14
15 /**
16 * The AnimationPanel to display animated (Locatable) objects as an extension of the VisualizationPanel. The difference is that
17 * the AnimationPanel is Simulator and Replication aware. When a new replication starts, a context for that replication is
18 * created, and Renderable objects for that replication are stored in a subcontext that is specific for that replication. This
19 * means that even when multiple replications run in parallel, animations can be stored internally and the user could
20 * theoretically shift between the different animations (or show multiple animations at once).
21 * <p>
22 * Copyright (c) 2002-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
23 * for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
24 * project is distributed under a three-clause BSD-style license, which can be found at
25 * <a href="https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
26 * </p>
27 * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
28 * @author <a href="http://www.peter-jacobs.com">Peter Jacobs </a>
29 */
30 public class AnimationPanel extends VisualizationPanel
31 {
32 /** */
33 private static final long serialVersionUID = 1L;
34
35 /** the simulator. */
36 private SimulatorInterface<?> simulator;
37
38 /**
39 * constructs a new AnimationPanel.
40 * @param homeExtent the home (initial) extent of the panel
41 * @param simulator the simulator of which we want to know the events for animation
42 * @throws DsolException when the simulator is not implementing the AnimatorInterface
43 */
44 public AnimationPanel(final Bounds2d homeExtent, final SimulatorInterface<?> simulator) throws DsolException
45 {
46 super(homeExtent, simulator);
47 Throw.when(!(simulator instanceof AnimatorInterface), DsolException.class,
48 "Simulator must implement the AnimatorInterface");
49 this.simulator = simulator;
50 simulator.addListener(this, Replication.START_REPLICATION_EVENT);
51 }
52
53 @Override
54 public void notify(final Event event)
55 {
56 super.notify(event);
57
58 if (event.getType().equals(Replication.START_REPLICATION_EVENT))
59 {
60 synchronized (this.elementList)
61 {
62 this.elements.clear();
63 try
64 {
65 if (this.context != null)
66 {
67 this.context.removeListener(this, ContextInterface.OBJECT_ADDED_EVENT);
68 this.context.removeListener(this, ContextInterface.OBJECT_REMOVED_EVENT);
69 }
70 this.context =
71 ContextUtil.lookupOrCreateSubContext(this.simulator.getReplication().getContext(), "animation/2D");
72 subscribeToContext();
73 }
74 catch (Exception exception)
75 {
76 CategoryLogger.always().warn(exception, "notify");
77 }
78 }
79 }
80 }
81
82 }