package org.opentrafficsim.graphs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.awt.Component; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import javax.swing.JLabel; import javax.swing.JOptionPane; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.simulators.SimulatorInterface; import org.djunits.unit.AccelerationUnit; import org.djunits.unit.LengthUnit; import org.djunits.unit.TimeUnit; import org.djunits.unit.UNITS; import org.djunits.value.vdouble.scalar.Acceleration; import org.djunits.value.vdouble.scalar.DoubleScalar; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djunits.value.vdouble.scalar.Time; import org.jfree.chart.ChartPanel; import org.jfree.data.DomainOrder; import org.junit.Test; import org.opentrafficsim.core.dsol.OTSModelInterface; import org.opentrafficsim.core.dsol.OTSSimTimeDouble; import org.opentrafficsim.core.geometry.OTSPoint3D; import org.opentrafficsim.core.gtu.GTUType; import org.opentrafficsim.core.network.LongitudinalDirectionality; import org.opentrafficsim.core.network.OTSNetwork; import org.opentrafficsim.core.network.OTSNode; import org.opentrafficsim.road.car.CarTest; import org.opentrafficsim.road.car.LaneBasedIndividualCar; import org.opentrafficsim.road.gtu.lane.tactical.following.FixedAccelerationModel; import org.opentrafficsim.road.gtu.lane.tactical.following.SequentialFixedAccelerationModel; import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic; import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.LaneChangeModel; import org.opentrafficsim.road.network.factory.LaneFactory; import org.opentrafficsim.road.network.lane.Lane; import org.opentrafficsim.road.network.lane.LaneType; import org.opentrafficsim.simulationengine.SimpleSimulator; /** * Test the non-GUI part of the ContourPlot class. *

* Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $, * initial version Aug 21, 2014
* @author Peter Knoppers */ public class ContourPlotTest implements UNITS { /** * Create a dummy path for the tests. * @param laneType the lane type * @param gtuType the GTU type * @return List<Lane>; the dummy path * @throws Exception when something goes wrong (should not happen) */ private List dummyPath(final LaneType laneType, final GTUType gtuType) throws Exception { OTSNode b = new OTSNode("B", new OTSPoint3D(12345, 0, 0)); ArrayList result = new ArrayList(); Lane[] lanes = LaneFactory.makeMultiLane("AtoB", new OTSNode("A", new OTSPoint3D(1234, 0, 0)), b, null, 1, laneType, new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS); result.add(lanes[0]); // Make a continuation lane to prevent errors when the operational plan exceeds the available remaining length lanes = LaneFactory.makeMultiLane("BtoC", b, new OTSNode("C", new OTSPoint3D(99999, 0, 0)), null, 1, laneType, new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS); // System.out.println("continuation lane is " + lanes[0] + " length is " + lanes[0].getLength()); // System.out.println("next lanes is " + result.get(0).nextLanes(gtuType)); return result; } /** * Test the AccelerationContourPlot. * @throws Exception when something goes wrong (should not happen) */ @SuppressWarnings("static-method") @Test public final void accelerationContourTest() throws Exception { LaneType laneType = new LaneType("CarLane"); GTUType gtuType = GTUType.makeGTUType("Car"); laneType.addCompatibility(gtuType); List path = dummyPath(laneType, gtuType); AccelerationContourPlot acp = new AccelerationContourPlot("Acceleration", path); assertTrue("newly created AccelerationContourPlot should not be null", null != acp); assertEquals("SeriesKey should be \"acceleration\"", "acceleration", acp.getSeriesKey(0)); standardContourTests(acp, path.get(0), gtuType, Double.NaN, 0); } /** * Test the DensityContourPlot. * @throws Exception when something goes wrong (should not happen) */ @SuppressWarnings("static-method") @Test public final void densityContourTest() throws Exception { LaneType laneType = new LaneType("CarLane"); GTUType gtuType = GTUType.makeGTUType("Car"); laneType.addCompatibility(gtuType); List path = dummyPath(laneType, gtuType); DensityContourPlot dcp = new DensityContourPlot("Density", path); assertTrue("newly created DensityContourPlot should not be null", null != dcp); assertEquals("SeriesKey should be \"density\"", "density", dcp.getSeriesKey(0)); standardContourTests(dcp, path.get(0), gtuType, 0, Double.NaN); } /** * Debugging method. * @param cp * @param fromX * @param toX * @param fromY * @param toY */ static void printMatrix(ContourPlot cp, int fromX, int toX, int fromY, int toY) { System.out.println("Contour plot data:"); int maxItem = cp.getItemCount(0); for (int y = fromY; y <= toY; y++) { System.out.print(String.format("y=%3d ", y)); for (int x = fromX; x <= toX; x++) { // Find the item with the requested x and y int item; for (item = 0; item < maxItem; item++) { if (cp.getXValue(0, item) == x && cp.getYValue(0, item) == y) { break; } } if (item < maxItem) { System.out.print(String.format("%10.6f", cp.getZValue(0, item))); } else { System.out.print(" -------- "); } } System.out.println(""); } System.out.print(""); } /** * Test the FlowContourPlot. * @throws Exception when something goes wrong (should not happen) */ @SuppressWarnings("static-method") @Test public final void flowContourTest() throws Exception { LaneType laneType = new LaneType("CarLane"); GTUType gtuType = GTUType.makeGTUType("Car"); laneType.addCompatibility(gtuType); List path = dummyPath(laneType, gtuType); FlowContourPlot fcp = new FlowContourPlot("Density", path); assertTrue("newly created DensityContourPlot should not be null", null != fcp); assertEquals("SeriesKey should be \"flow\"", "flow", fcp.getSeriesKey(0)); standardContourTests(fcp, path.get(0), gtuType, 0, Double.NaN); } /** * Test the SpeedContourPlot. * @throws Exception when something goes wrong (should not happen) */ @SuppressWarnings("static-method") @Test public final void speedContourTest() throws Exception { LaneType laneType = new LaneType("CarLane"); GTUType gtuType = GTUType.makeGTUType("Car"); laneType.addCompatibility(gtuType); List path = dummyPath(laneType, gtuType); SpeedContourPlot scp = new SpeedContourPlot("Density", path); assertTrue("newly created DensityContourPlot should not be null", null != scp); assertEquals("SeriesKey should be \"speed\"", "speed", scp.getSeriesKey(0)); standardContourTests(scp, path.get(0), gtuType, Double.NaN, 50); } /** * Test various properties of a ContourPlot that has no observed data added. * @param cp ContourPlot; the ContourPlot to test * @param lane Lane; the lane on which the test GTUs are run * @param gtuType GTUType; the type of GTU * @param expectedZValue double; the value that getZ and getZValue should return for a valid item when no car has passed * @param expectedZValueWithTraffic double; the value that getZ and getZValue should return a valid item where a car has * traveled at constant speed of 50 km/h. Supply Double.NaN if the value varies but differs from the value * expected when no car has passed * @throws Exception when something goes wrong (should not happen) */ public static void standardContourTests(final ContourPlot cp, Lane lane, GTUType gtuType, final double expectedZValue, final double expectedZValueWithTraffic) throws Exception { assertEquals("seriesCount should be 1", 1, cp.getSeriesCount()); assertEquals("domainOrder should be ASCENDING", DomainOrder.ASCENDING, cp.getDomainOrder()); assertEquals("indexOf always returns 0", 0, cp.indexOf(0)); assertEquals("indexOf always returns 0", 0, cp.indexOf("abc")); assertEquals("getGroup always returns null", null, cp.getGroup()); int xBins = cp.xAxisBins(); int yBins = cp.yAxisBins(); int expectedXBins = (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND, ContourPlot.INITIALLOWERTIMEBOUND) .getSI()) / ContourPlot.STANDARDTIMEGRANULARITIES[ContourPlot.STANDARDINITIALTIMEGRANULARITYINDEX]); assertEquals("Initial xBins should be " + expectedXBins, expectedXBins, xBins); int expectedYBins = (int) Math.ceil(lane.getLength().getSI() / ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDINITIALDISTANCEGRANULARITYINDEX]); assertEquals("yBins should be " + expectedYBins, expectedYBins, yBins); int bins = cp.getItemCount(0); assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins); // Cache the String equivalents of minimumDistance and maximumDistance, INITIALLOWERTIMEBOUND and // INITUALUPPERTIMEBOUND String initialLowerTimeBoundString = ContourPlot.INITIALLOWERTIMEBOUND.toString(); String initialUpperTimeBoundString = ContourPlot.INITIALUPPERTIMEBOUND.toString(); // Vary the x granularity for (double timeGranularity : ContourPlot.STANDARDTIMEGRANULARITIES) { cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + timeGranularity)); for (double distanceGranularity : ContourPlot.STANDARDDISTANCEGRANULARITIES) { cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + distanceGranularity)); cp.reGraph(); expectedXBins = (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND, ContourPlot.INITIALLOWERTIMEBOUND).getSI()) / timeGranularity); xBins = cp.xAxisBins(); assertEquals("Modified xBins should be " + expectedXBins, expectedXBins, xBins); expectedYBins = (int) Math.ceil(lane.getLength().getSI() / distanceGranularity); yBins = cp.yAxisBins(); assertEquals("Modified yBins should be " + expectedYBins, expectedYBins, yBins); bins = cp.getItemCount(0); assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins); for (int item = 0; item < bins; item++) { double x = cp.getXValue(0, item); assertTrue("X should be >= " + initialLowerTimeBoundString, x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI()); assertTrue("X should be <= " + initialUpperTimeBoundString, x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI()); Number alternateX = cp.getX(0, item); assertEquals("getXValue and getX should return things that have the same value", x, alternateX.doubleValue(), 0.000001); double y = cp.getYValue(0, item); Number alternateY = cp.getY(0, item); assertEquals("getYValue and getY should return things that have the same value", y, alternateY.doubleValue(), 0.000001); double z = cp.getZValue(0, item); if (Double.isNaN(expectedZValue)) { assertTrue("Z value should be NaN", Double.isNaN(z)); } else { assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001); } Number alternateZ = cp.getZ(0, item); if (Double.isNaN(expectedZValue)) { assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue())); } else { assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue, alternateZ.doubleValue(), 0.0000); } } try { cp.getXValue(0, -1); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // Ignore } try { cp.getXValue(0, bins); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // Ignore } try { cp.yAxisBin(-1); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // Ignore } try { cp.yAxisBin(bins); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // Ignore } } } // Test some ActionEvents that ContourPlot can not handle try { cp.actionPerformed(new ActionEvent(cp, 0, "blabla")); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // Ignore } try { cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity -1")); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // ignore } try { cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity abc")); fail("Should have thrown an Exception"); } catch (RuntimeException e) { // ignore } try { cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularitIE 10")); // typo in the event name fail("Should have thrown an Exception"); } catch (RuntimeException e) { // ignore } // Make the time granularity a bit more reasonable final double useTimeGranularity = 30; // [s] cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + useTimeGranularity)); final double useDistanceGranularity = ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDDISTANCEGRANULARITIES.length - 1]; cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + useDistanceGranularity)); cp.reGraph(); bins = cp.getItemCount(0); Time.Abs initialTime = new Time.Abs(0, SECOND); Length.Rel initialPosition = new Length.Rel(100, METER); Speed initialSpeed = new Speed(50, KM_PER_HOUR); ContourPlotModel model = new ContourPlotModel(); SimpleSimulator simulator = new SimpleSimulator(initialTime, new Time.Rel(0, SECOND), new Time.Rel(1800, SECOND), model); // Create a car running 50 km.h SequentialFixedAccelerationModel gtuFollowingModel = new SequentialFixedAccelerationModel(simulator, new Acceleration(2.0, AccelerationUnit.METER_PER_SECOND_2)); // Make the car run at constant speed for one minute gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(60, SECOND))); // Make the car run at constant speed for another minute gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(600, SECOND))); // Make the car run at constant speed for five more minutes gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Time.Rel(300, SECOND))); LaneChangeModel laneChangeModel = new Egoistic(); OTSNetwork network = new OTSNetwork("network"); LaneBasedIndividualCar car = CarTest.makeReferenceCar("0", gtuType, lane, initialPosition, initialSpeed, simulator, gtuFollowingModel, laneChangeModel, network); car.getStrategicalPlanner().getDrivingCharacteristics() .setForwardHeadwayDistance(new Length.Rel(10, LengthUnit.KILOMETER)); // Check that the initial data in the graph contains no trace of any car. for (int item = 0; item < bins; item++) { double x = cp.getXValue(0, item); assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND, x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI()); assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND, x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI()); Number alternateX = cp.getX(0, item); assertEquals("getXValue and getX should return things that have the same value", x, alternateX.doubleValue(), 0.000001); double y = cp.getYValue(0, item); Number alternateY = cp.getY(0, item); assertEquals("getYValue and getY should return things that have the same value", y, alternateY.doubleValue(), 0.000001); double z = cp.getZValue(0, item); if (Double.isNaN(expectedZValue)) { assertTrue("Z value should be NaN (got " + z + ")", Double.isNaN(z)); } else { assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001); } Number alternateZ = cp.getZ(0, item); if (Double.isNaN(expectedZValue)) { assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue())); } else { assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue, alternateZ.doubleValue(), 0.0000); } } // System.out.println("Running simulator from " + simulator.getSimulatorTime().get() + " to " // + gtuFollowingModel.timeAfterCompletionOfStep(0)); double stopTime = gtuFollowingModel.timeAfterCompletionOfStep(0).si; simulator.runUpTo(new Time.Abs(stopTime + Math.ulp(stopTime), TimeUnit.SI)); while (simulator.isRunning()) { try { Thread.sleep(10); } catch (InterruptedException ie) { ie = null; // ignore } } // System.out.println("Simulator is now at " + simulator.getSimulatorTime().get()); // System.out.println("Car at start time " + car.getOperationalPlan().getStartTime() + " is at " // + car.getPosition(car.getOperationalPlan().getStartTime())); // System.out.println("At time " + simulator.getSimulator().getSimulatorTime().getTime() + " car is at " + car); for (int item = 0; item < bins; item++) { double x = cp.getXValue(0, item); assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND, x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI()); assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND, x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI()); Number alternateX = cp.getX(0, item); assertEquals("getXValue and getX should return things that have the same value", x, alternateX.doubleValue(), 0.000001); double y = cp.getYValue(0, item); Number alternateY = cp.getY(0, item); assertEquals("getYValue and getY should return things that have the same value", y, alternateY.doubleValue(), 0.000001); double z = cp.getZValue(0, item); // figure out if the car has traveled through this cell // if (x >= 180) // System.out.println(String.format("t=%.3f, x=%.3f z=%f, exp=%.3f, carLastEval=%s, carNextEval=%s", x, y, z, // expectedZValue, car.getOperationalPlan().getStartTime().getSI(), car.getOperationalPlan().getEndTime() // .getSI())); boolean hit = false; if (x + useTimeGranularity >= 0// car.getOperationalPlan().getStartTime().getSI() && x < 60)// car.getOperationalPlan().getEndTime().getSI()) { // the car MAY have contributed to this cell Time.Abs cellStartTime = new Time.Abs(Math.max(car.getOperationalPlan().getStartTime().getSI(), x), SECOND); Time.Abs cellEndTime = new Time.Abs(Math.min(car.getOperationalPlan().getEndTime().getSI(), x + useTimeGranularity), SECOND); // System.out.println("cellStartTime=" + cellStartTime + ", cellEndTime=" + cellEndTime); // The next if statement is the problem // if (cellStartTime.lt(cellEndTime) // && car.position(lane, car.getRear(), cellStartTime).getSI() <= y + useDistanceGranularity // && car.position(lane, car.getRear(), cellEndTime).getSI() >= y) double xAtCellStartTime = initialPosition.si + initialSpeed.si * cellStartTime.si; double xAtCellEndTime = initialPosition.si + initialSpeed.si * cellEndTime.si; if (xAtCellStartTime < y + useDistanceGranularity && xAtCellEndTime >= y) { hit = true; } } // System.out.println(String.format( // "hit=%s, t=%.3f, x=%.3f z=%f, exp=%.3f, carLastEval=%s, carNextEval=%s, simulatortime=%s", hit, x, y, z, // expectedZValue, car.getOperationalPlan().getStartTime().getSI(), car.getOperationalPlan().getEndTime() // .getSI(), car.getSimulator().getSimulatorTime().get())); Number alternateZ = cp.getZ(0, item); if (hit) { if (!Double.isNaN(expectedZValueWithTraffic)) { if (Double.isNaN(z)) { printMatrix(cp, 0, 10, 0, 10); System.out.println("Oops - z is NaN, expected z value with traffic is " + expectedZValueWithTraffic); } assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic, z, 0.0001); assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic, alternateZ.doubleValue(), 0.0001); } else { if (Double.isNaN(expectedZValue)) { // FIXME looks wrong / PK assertFalse("Z value should not be NaN", Double.isNaN(z)); } } } else { if (Double.isNaN(expectedZValue)) { // if (!Double.isNaN(z)) // { // System.out.println("Oops"); // Time.Abs cellStartTime = new Time.Abs(x, SECOND); // Time.Abs cellEndTime = // new Time.Abs(Math.min(car.getOperationalPlan().getEndTime().getSI(), x + useTimeGranularity), // SECOND); // double xAtCellStartTime = initialPosition.si + initialSpeed.si * cellStartTime.si; // double xAtCellEndTime = initialPosition.si + initialSpeed.si * cellEndTime.si; // System.out.println("cellStartTime=" + cellStartTime + " cellEndTime=" + cellEndTime // + " xAtCellStartTime=" + xAtCellStartTime + " xAtCellEndTime=" + xAtCellEndTime); // double cellX = cp.getXValue(0, item); // double cellY = cp.getYValue(0, item); // double cellZ = cp.getZValue(0, item); // System.out.println("cellX=" + cellX + " cellY=" + cellY + " cellZ=" + cellZ + " timeGranularity=" // + useTimeGranularity + " distanceGranularity=" + useDistanceGranularity); // cp.getZValue(0, item); // } assertTrue("Z value should be NaN", Double.isNaN(z)); } else { assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001); } if (Double.isNaN(expectedZValue)) { assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue())); } else { assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue, alternateZ.doubleValue(), 0.0000); } } } // System.out.println("Running simulator from " + simulator.getSimulatorTime().get() + " to " // + gtuFollowingModel.timeAfterCompletionOfStep(1)); stopTime = gtuFollowingModel.timeAfterCompletionOfStep(1).si; simulator.runUpTo(new Time.Abs(stopTime + Math.ulp(stopTime), TimeUnit.SI)); while (simulator.isRunning()) { try { Thread.sleep(10); } catch (InterruptedException ie) { ie = null; // ignore } } // System.out.println("Simulator is now at " + simulator.getSimulatorTime().get()); // Check that the time range has expanded xBins = cp.xAxisBins(); bins = cp.getItemCount(0); double observedHighestTime = Double.MIN_VALUE; for (int bin = 0; bin < bins; bin++) { double xValue = cp.getXValue(0, bin); if (xValue > observedHighestTime) { observedHighestTime = xValue; } } double expectedHighestTime = Math.floor((car.getSimulator().getSimulatorTime().get().si - 0.001) / useTimeGranularity) * useTimeGranularity; assertEquals("Time range should run up to " + expectedHighestTime, expectedHighestTime, observedHighestTime, 0.0001); // Check the updateHint method in the PointerHandler // First get the panel that stores the result of updateHint (this is ugly) JLabel hintPanel = null; ChartPanel chartPanel = null; for (Component c0 : cp.getComponents()) { for (Component c1 : ((Container) c0).getComponents()) { if (c1 instanceof Container) { for (Component c2 : ((Container) c1).getComponents()) { // System.out.println("c2 is " + c2); if (c2 instanceof Container) { for (Component c3 : ((Container) c2).getComponents()) { // System.out.println("c3 is " + c3); if (c3 instanceof JLabel) { if (null == hintPanel) { hintPanel = (JLabel) c3; } else { fail("There should be only one JPanel in a ContourPlot"); } } if (c3 instanceof ChartPanel) { if (null == chartPanel) { chartPanel = (ChartPanel) c3; } else { fail("There should be only one ChartPanel in a ContourPlot"); } } } } } } } } if (null == hintPanel) { fail("Could not find a JLabel in ContourPlot"); } if (null == chartPanel) { fail("Could not find a ChartPanel in ContourPlot"); } assertEquals("Initially the text should be a single space", " ", hintPanel.getText()); PointerHandler ph = null; for (MouseListener ml : chartPanel.getMouseListeners()) { if (ml instanceof PointerHandler) { if (null == ph) { ph = (PointerHandler) ml; } else { fail("There should be only one PointerHandler on the chartPanel"); } } } if (null == ph) { fail("Could not find the PointerHandler for the chartPanel"); } ph.updateHint(1, 2); // System.out.println("Hint text is now " + hintPanel.getText()); assertFalse("Hint should not be a single space", " ".equals(hintPanel.getText())); ph.updateHint(Double.NaN, Double.NaN); assertEquals("The text should again be a single space", " ", hintPanel.getText()); } /** * Run the DensityContourPlot stand-alone for profiling. * @param args String[]; the command line arguments (not used) * @throws Exception when something goes wrong (should not happen) */ public static void main(final String[] args) throws Exception { ContourPlotTest cpt = new ContourPlotTest(); System.out.println("Click the OK button"); JOptionPane.showMessageDialog(null, "ContourPlot", "Start experiment", JOptionPane.INFORMATION_MESSAGE); System.out.println("Running ..."); cpt.densityContourTest(); System.out.println("Finished"); } } /** *

* Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $, * initial version feb. 2015
* @author Peter Knoppers */ class ContourPlotModel implements OTSModelInterface { /** */ private static final long serialVersionUID = 20150209L; /** {@inheritDoc} */ @Override public void constructModel( SimulatorInterface, DoubleScalar.Rel, OTSSimTimeDouble> simulator) throws SimRuntimeException { // NOT USED } /** {@inheritDoc} */ @Override public SimulatorInterface, DoubleScalar.Rel, OTSSimTimeDouble> getSimulator() { return null; } }