/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package simulation; import java.awt.AWTEvent; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.Timer; import ilog.views.IlvManagerView; import ilog.views.IlvManagerViewInteractor; import ilog.views.IlvPoint; import ilog.views.IlvTransformer; import ilog.views.event.InteractorChangedEvent; import ilog.views.event.InteractorListener; import ilog.views.interactor.IlvPermanentInteractorInterface; import ilog.views.maps.IlvCoordinate; import ilog.views.maps.IlvCoordinateSystemProperty; import ilog.views.maps.defense.symbology.app6a.IlvApp6aSymbol; import ilog.views.maps.srs.coordsys.IlvCoordinateSystem; import ilog.views.maps.srs.coordsys.IlvGeographicCoordinateSystem; import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformation; import ilog.views.maps.srs.coordtrans.IlvCoordinateTransformationException; import ilog.views.sdm.IlvSDMEngine; import ilog.views.sdm.event.SDMModelEvent; import ilog.views.sdm.event.SDMModelListener; import ilog.views.sdm.renderer.IlvStyleSheetRenderer; import ilog.views.util.IlvImageUtil; /** * Illustrates how to log events on the symbology and to replay scenarios. */ public class SimulationController extends JToolBar { final static String NEUTRAL = "Neutral".intern(); //$NON-NLS-1$ final static String FOLLOW = "Follow".intern(); //$NON-NLS-1$ private final IlvSDMEngine symbology; // final JCheckBox pause = new JCheckBox("Stop Creating Targets"); // //$NON-NLS-1$ // final JCheckBox simulation = new JCheckBox("Run simulation"); //$NON-NLS-1$ final JButton playPauseButton = new JButton(); final JButton stopButton = new JButton(); final JToggleButton followSymbolButton = new JToggleButton(); private boolean isRunning = false; private boolean needInit = true; final JComboBox<Integer> mobileCount = new JComboBox<Integer>(new Integer[] { Integer.valueOf(10), Integer.valueOf(50), Integer.valueOf(100), Integer.valueOf(300), Integer.valueOf(1000), Integer.valueOf(1500) }); final JComboBox<String> speedCombo = new JComboBox<String>( new String[] { "x10", "x25", "x50", "x75", "x100", "x250" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ final JComboBox<Integer> fpsCombo = new JComboBox<Integer>( new Integer[] { Integer.valueOf(5), Integer.valueOf(10), Integer.valueOf(25), Integer.valueOf(50) }); SimulationContext simulationContext; Icon playIcon; Icon pauseIcon; Icon stopIcon; Icon followSymbolIcon; FollowSymbolInteractor followInteractor = new FollowSymbolInteractor(); /** * Create the replay interface. * * @param symbology */ public SimulationController(IlvSDMEngine symbology) { createUserInterface(); this.symbology = symbology; playPauseButton.addActionListener(new SimulationBoxListener()); SimulationBoxListener listener = new SimulationBoxListener(); stopButton.addActionListener(listener); followSymbolButton.addActionListener(listener); // JV-2856 InteractorListener interactorListener = new InteractorListener() { Override public void interactorChanged(InteractorChangedEvent event) { boolean isMyInteractor = (event.getNewValue() == followInteractor); if (followSymbolButton.isSelected() != isMyInteractor) { followSymbolButton.setSelected(isMyInteractor); } } }; symbology.getReferenceView().addInteractorListener(interactorListener); } private void createUserInterface() { speedCombo.setSelectedIndex(0); speedCombo.setToolTipText("Choose simulation speed factor"); //$NON-NLS-1$ (should // be // internationalized) SimulationContext.setTimeAcceleration(10); speedCombo.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { int accel = Integer.parseInt(((String) speedCombo.getSelectedItem()).substring(1)); SimulationContext.setTimeAcceleration(accel); } }); fpsCombo.setSelectedIndex(0); fpsCombo.setToolTipText("Choose target refresh rate for the display"); //$NON-NLS-1$ (should // be // internationalized) SimulationContext.setTargetFPS(((Integer) fpsCombo.getSelectedItem()).intValue()); fpsCombo.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { SimulationContext.setTargetFPS(((Integer) fpsCombo.getSelectedItem()).intValue()); } }); Dimension buttonDim = new Dimension(26, 26); Dimension comboDim = new Dimension(55, 22); configureComponentSize(playPauseButton, buttonDim); playPauseButton.setSelected(false); add(playPauseButton); configureComponentSize(stopButton, buttonDim); add(stopButton); configureComponentSize(followSymbolButton, buttonDim); add(followSymbolButton); // setLayout(new FlowLayout(FlowLayout.LEFT,2,0)); addSeparator(); add(new JLabel("Mobiles ")); //$NON-NLS-1$ (should be internationalized) // addSeparator(); mobileCount.setToolTipText("Choose number of mobiles"); //$NON-NLS-1$ (should // be // internationalized) configureComponentSize(mobileCount, comboDim); add(mobileCount); addSeparator(); add(new JLabel("Speed ")); //$NON-NLS-1$ (should be internationalized) // addSeparator(); configureComponentSize(speedCombo, comboDim); add(speedCombo); addSeparator(); add(new JLabel("Fps ")); //$NON-NLS-1$ (should be internationalized) // addSeparator(); configureComponentSize(fpsCombo, comboDim); add(fpsCombo); mobileCount.setEnabled(true); // install icons playIcon = createIcon("right.gif"); //$NON-NLS-1$ pauseIcon = createIcon("pause.gif"); //$NON-NLS-1$ stopIcon = createIcon("stop.gif"); //$NON-NLS-1$ // stopTargetCreationIcon = createIcon("stopTargetCreation.gif"); // //$NON-NLS-1$ // targetCreationIcon = createIcon("targetCreation.gif"); //$NON-NLS-1$ followSymbolIcon = createIcon("target.gif"); //$NON-NLS-1$ playPauseButton.setIcon(playIcon); playPauseButton.setToolTipText("Run simulation"); //$NON-NLS-1$ (should be // internationalized) stopButton.setIcon(stopIcon); stopButton.setToolTipText("Stop simulation"); //$NON-NLS-1$ (should be // internationalized) followSymbolButton.setIcon(followSymbolIcon); followSymbolButton.setToolTipText("Choose a symbol to follow"); //$NON-NLS-1$ (should // be // internationalized) } private void configureComponentSize(JComponent comp, Dimension buttonDim) { comp.setPreferredSize(buttonDim); comp.setMinimumSize(buttonDim); comp.setMaximumSize(buttonDim); } private Icon createIcon(String iconURL) { Image image = null; try { image = IlvImageUtil.getImageFromFile(SimulationController.class, iconURL); } catch (IOException e1) { e1.printStackTrace(); } if (image != null) { return new ImageIcon(image); } return null; } IlvApp6aSymbol dca; private final class SimulationBoxListener implements ActionListener { /** * Called when the button "Run simulation" is pressed. * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ Override public void actionPerformed(ActionEvent e) { if (e.getSource() == playPauseButton) { isRunning = !isRunning; if (isRunning) { if (needInit) { Container c = playPauseButton.getTopLevelAncestor(); Cursor oc = null; if (c.isCursorSet()) { oc = c.getCursor(); } c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); buildSimulation(); // set triple buffering IlvStyleSheetRenderer renderer = IlvStyleSheetRenderer.getInstance(symbology); symbology.getReferenceView().setTripleBufferedLayerCount(renderer.getNodesLayer()); targetProvider.start(); mobileCount.setEnabled(false); needInit = false; c.setCursor(oc); } else { // resume simulation if (targetProvider != null) // targetProvider.start(); Mobile.resume(); } playPauseButton.setToolTipText("Pause simulation"); //$NON-NLS-1$ (should // be // internationalized) playPauseButton.setIcon(pauseIcon); } else { playPauseButton.setToolTipText("Run simulation"); //$NON-NLS-1$ (should // be // internationalized) playPauseButton.setIcon(playIcon); // pause simulation isRunning = false; Mobile.pause(); } } else if (e.getSource() == stopButton) { Mobile.resume(); isRunning = false; stopSimu(); // stop triple buffering symbology.getReferenceView().setTripleBufferedLayerCount(0); mobileCount.setEnabled(true); playPauseButton.setToolTipText("Run simulation"); //$NON-NLS-1$ (should // be // internationalized) playPauseButton.setIcon(playIcon); playPauseButton.setEnabled(true); Enumeration<?> roots = symbology.getModel().getObjects(); Vector<Object> v = new Vector<Object>(); while (roots.hasMoreElements()) { v.add(roots.nextElement()); } for (int i = 0; i < v.size(); i++) { symbology.getModel().removeObject(v.get(i)); } Mobile.allMobiles.clear(); Mobile.currentMobileTask = null; needInit = true; } else if (e.getSource() == followSymbolButton) { IlvManagerView view = symbology.getReferenceView(); if (view != null) { view.requestFocus(); if (view.getInteractor() == followInteractor) { view.popInteractor(); } else { view.pushInteractor(followInteractor); } } } } void stopSimu() { if (targetProvider != null) // targetProvider.stop(); Mobile.stop(); } void buildSimulation() { SimulationContext.setSeed(124); dca = new IlvApp6aSymbol("SFGPUCFHS--CUS*", 0, 0);//$NON-NLS-1$ double lon = (SimulationContext.getLonMin() + SimulationContext.getLonMax()) / 2; double lat = (SimulationContext.getLatMin() + SimulationContext.getLatMax()) / 2; dca.setLocation(symbology, lon, lat); symbology.getModel().addObject(dca, null, null); int neutralMobilesCount = ((Integer) (mobileCount.getSelectedItem())).intValue(); // neutral mobiles. for (int i = 0; i < neutralMobilesCount; i++) { /* Target t= */new Target(NEUTRAL, symbology); } targetProvider.setInitialDelay(100); double accel = SimulationContext.getTimeAcceleration(); targetProvider.setDelay((int) (50000 / accel)); // targetProvider.start(); Mobile.start(); } } Timer targetProvider = new Timer(20000, new ActionListener() { Override public void actionPerformed(ActionEvent e) { if (!Mobile.paused && isRunning == true) { Target t = new Target(symbology); t.symbol.setProperty(IlvApp6aSymbol.ID_CODE, "SHAPMHA---FA--A"); //$NON-NLS-1$ new Missile(dca.getLongitude(), dca.getLatitude(), symbology, t); double accel = SimulationContext.getTimeAcceleration(); int newDelay = (int) (50000 / accel); if (targetProvider.getDelay() != newDelay) { targetProvider.setDelay((int) (50000 / accel)); } } } }); final static java.text.DecimalFormat NS = new java.text.DecimalFormat("0 mph"); //$NON-NLS-1$ final static java.text.DecimalFormat FS = new java.text.DecimalFormat("0 ft"); //$NON-NLS-1$ /** * @author eaullas */ private class FollowSymbolInteractor extends IlvManagerViewInteractor implements IlvPermanentInteractorInterface { /** To save cursor. */ Cursor oldCursor = null; /** The cursor for this interactor. */ Cursor myCursor = null; /** * Creates a new <code>FollowSymbolInteractor</code>. */ public FollowSymbolInteractor() { super(); enableEvents(AWTEvent.MOUSE_EVENT_MASK); myCursor = new Cursor(Cursor.CROSSHAIR_CURSOR); } Override public boolean isPermanent() { return false; } Override public void setPermanent(boolean permanent) { // ignore this.permanent = permanent; } /** * This method is called when the interactor is attached to the specified * manager view. * * @param v * view to attach to. */ Override protected void attach(IlvManagerView v) { super.attach(v); if (!getCursor().equals(v.getCursor())) { oldCursor = v.getCursor(); v.setCursor(getCursor()); } } /** * This method is called when the interactor is detached from the specified * manager view. */ Override protected void detach() { if (oldCursor != null) { getManagerView().setCursor(oldCursor); oldCursor = null; } if (modelListener != null) { symbology.getModel().removeSDMModelListener(modelListener); modelListener = null; } modelListener = null; follow(null); super.detach(); } /** * @return Returns the cursor used for edition. */ public Cursor getCursor() { if (myCursor == null) { if (getManagerView() != null) return getManagerView().getCursor(); return Cursor.getDefaultCursor(); } return myCursor; } Override protected void processMouseEvent(MouseEvent e) { switch (e.getID()) { case MouseEvent.MOUSE_RELEASED: Object dataObject = symbology.getObject(new IlvPoint(e.getX(), e.getY()), getManagerView()); // if(e.getClickCount()>1){ // if(dataObject != null){ // symbPanel.editSelectedSymbol(); // } // } if (dataObject instanceof IlvApp6aSymbol) { follow((IlvApp6aSymbol) dataObject); } else { follow(null); } break; } super.processMouseEvent(e); } IlvApp6aSymbol currentSymbol; SDMModelListener modelListener; void follow(IlvApp6aSymbol symbol) { if (currentSymbol != null) { symbology.getModel().setObjectProperty(currentSymbol, FOLLOW, "0"); //$NON-NLS-1$ } currentSymbol = symbol; if (currentSymbol != null) { symbology.getModel().setObjectProperty(currentSymbol, FOLLOW, "1");//$NON-NLS-1$ } updateForCurrentSymbol(); if (modelListener == null) { modelListener = new SDMModelListener() { Override public void adjustmentFinished(SDMModelEvent event) { if (currentSymbol != null) { updateForCurrentSymbol(); } } Override public void dataChanged(SDMModelEvent event) { if (event.getObject() == currentSymbol) { updateForCurrentSymbol(); } } Override public void linkDestinationChanged(SDMModelEvent event) {/* ignore */ } Override public void linkSourceChanged(SDMModelEvent event) {/* ignore */ } Override public void objectAdded(SDMModelEvent event) {/* ignore */ } Override public void objectRemoved(SDMModelEvent event) { if (event.getObject() == currentSymbol) { currentSymbol = null; follow(null); } } }; symbology.getModel().addSDMModelListener(modelListener); } } void updateForCurrentSymbol() { Object dir = null; if (currentSymbol != null) { dir = currentSymbol.getProperty(IlvApp6aSymbol.MODIFIER_DIRECTION_OF_MOVEMENT_INDICATOR); } double direction = -90; if (dir != null) { direction = Double.parseDouble(dir.toString()); } IlvManagerView view = getManagerView(); IlvCoordinateSystem system = IlvCoordinateSystemProperty.GetCoordinateSystem(view.getManager()); IlvCoordinateTransformation tr = IlvCoordinateTransformation .CreateTransformation(IlvGeographicCoordinateSystem.KERNEL, system); IlvTransformer t = view.getTransformer(); if (currentSymbol != null) { IlvCoordinate c1 = new IlvCoordinate(currentSymbol.getLongitude(), -currentSymbol.getLatitude()); if (tr != null) { try { tr.transform(c1, c1); } catch (IlvCoordinateTransformationException e) { e.printStackTrace(); } } IlvPoint c = new IlvPoint((float) c1.x, (float) c1.y); t.apply(c); t.translate(view.getWidth() / 2 - c.x, view.getHeight() / 2 - c.y); } double angle = Math.toDegrees(Math.atan2(t.getx21(), t.getx11())); double dangle = -90 - direction - angle; t.rotate(view.getWidth() / 2, view.getHeight() / 2, dangle); // make sure that an almost 0 rotation is exactly 0 (performance is // better) if (Math.abs(t.getx12()) < 1E-4 && Math.abs(t.getx21()) < 1E-4) {// RAZ // Rotation // when // it is // very // small. t.setValues(t.getx11(), 0, 0, t.getx22()); } view.setTransformer(t); view.invalidateView(); view.repaint(); } } }