package com.plectix.simulator.gui.panel; import java.awt.GridBagConstraints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.apache.log4j.Logger; import com.plectix.simulator.controller.SimulationService; import com.plectix.simulator.controller.SimulatorInputData; import com.plectix.simulator.controller.SimulatorStatusInterface; import com.plectix.simulator.gui.lib.GridBagPanel; import com.plectix.simulator.gui.lib.UIProperties; import com.plectix.simulator.simulator.DefaultSimulatorFactory; import com.plectix.simulator.simulator.SimulatorCommandLine; import com.plectix.simulator.simulator.options.SimulatorArgumentsDefaultValues; import com.plectix.simulator.streaming.LiveData; /** * <p>TODO document ControlPanel * </p> * @version $Id$ * @author ecemis */ @SuppressWarnings("serial") public class ControlPanel extends GridBagPanel implements ActionListener { private static final Logger LOGGER = Logger.getLogger(ControlPanel.class); private static final PrintStream DEFAULT_OUTPUT_STREAM = System.err; private static final int MINIMUM_LIVE_DATA_INTERVAL = 50; private static final int MAXIMUM_LIVE_DATA_INTERVAL = 30050; private static final String SIMULATION_COMBOBOX_ACTION_COMMAND = "SIMULATION_COMBOBOX_ACTION_COMMAND"; private static final String COMMAND_LINE_OPTIONS = "--operation-mode 1 --agents-limit 100 --xml-session-name Session.xml --seed 1"; private long simulationJobID = -1; private JComboBox simulationComboBox = null; private JButton startButton = null; private JButton stopButton = null; private JTextField commandLineOptionsTextField = null; private JProgressBar progressBar = null; private GraphPanel graphPanel = null; private List<SimulationSettings> simulationSettingsList = null; private List<ControlPanelListener> listeners = new ArrayList<ControlPanelListener>(); private Timer timer = null; private SimulationService simulationService = null; private JLabel graphUpdatePeriodLabel = null; private JSlider graphUpdatePeriodSlider = null; private int graphUpdatePeriod = 200; private JLabel liveDataIntervalLabel = null; private JSlider liveDataIntervalSlider = null; private int liveDataInterval = 200; private int liveDataPoints = SimulatorArgumentsDefaultValues.DEFAULT_LIVE_DATA_POINTS; public ControlPanel() { super(); simulationService = new SimulationService(new DefaultSimulatorFactory()); // simulationService.shutdown(); } public void initialize() { GridBagConstraintsEx gc = createNewConstraints().insets(5, 5, 5, 5); JLabel label = new JLabel(UIProperties.getString("controlpanel.simulation.label")); add(label, gc.fillBoth()); simulationComboBox = new JComboBox(); simulationComboBox.setActionCommand(SIMULATION_COMBOBOX_ACTION_COMMAND); simulationComboBox.addActionListener(this); add(simulationComboBox, gc.incx().fillNone()); startButton = new JButton(UIProperties.getString("controlpanel.startbutton.label")); stopButton = new JButton(UIProperties.getString("controlpanel.stopbutton.label")); progressBar = new JProgressBar(); progressBar.setStringPainted(true); startButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { LOGGER.info("Pressed button: " + startButton.getText()); startSimulation(); } }); stopButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { LOGGER.info("Pressed button: " + stopButton.getText()); stopSimulation(); } }); stopButton.setEnabled(false); commandLineOptionsTextField = new JTextField(); addGlue(gc, GridBagConstraints.BOTH); updatePanel(); } public boolean addListener(ControlPanelListener listener) { // let's make sure that this listener is up-to-date: // listener.setCurrentTerminal(currentTerminal); boolean ret = listeners.add(listener); // notifyListeners(currentTerminal); return ret; } public boolean removeListener(ControlPanelListener listener) { return listeners.remove(listener); } private void updatePanel() { LOGGER.info("Updating panel"); removeAll(); GridBagConstraintsEx gc = createNewConstraints().insets(5, 5, 5, 5); JLabel label = new JLabel(UIProperties.getString("controlpanel.simulation.label")); add(label, gc.fillNone().anchorLeft()); simulationComboBox.removeAllItems(); if (simulationSettingsList != null) { for (SimulationSettings simulationSettings : simulationSettingsList) { simulationComboBox.addItem(simulationSettings); } } add(simulationComboBox, gc.incx()); add(startButton, gc.incx().fillNone()); add(stopButton, gc.incx().fillNone()); add(progressBar, gc.incx().fillHorizontal()); label = new JLabel(UIProperties.getString("controlpanel.commandline.label")); add(label, gc.col(0).incy().fillNone().anchorLeft()); add(commandLineOptionsTextField, gc.incx().span(4, 1).fillHorizontal()); label = new JLabel(UIProperties.getString("controlpanel.livedatainterval.label")); add(label, gc.col(0).incy().span(1, 1).fillNone().anchorLeft()); liveDataIntervalLabel = new JLabel(liveDataInterval + " msecs"); add(liveDataIntervalLabel, gc.incx().anchorRight()); liveDataIntervalSlider = new JSlider(MINIMUM_LIVE_DATA_INTERVAL, MAXIMUM_LIVE_DATA_INTERVAL, liveDataInterval); liveDataIntervalSlider.setExtent(MINIMUM_LIVE_DATA_INTERVAL); liveDataIntervalSlider.setMinorTickSpacing(10*MINIMUM_LIVE_DATA_INTERVAL); liveDataIntervalSlider.setMajorTickSpacing(100*MINIMUM_LIVE_DATA_INTERVAL); // liveDataIntervalSlider.setSnapToTicks(true); liveDataIntervalSlider.setPaintTicks(true); liveDataIntervalSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { liveDataInterval = liveDataIntervalSlider.getValue(); liveDataIntervalLabel.setText(liveDataInterval + " msecs"); } } ); add(liveDataIntervalSlider, gc.incx().span(3, 1).fillHorizontal()); label = new JLabel(UIProperties.getString("controlpanel.graphupdateperiod.label")); add(label, gc.col(0).incy().span(1, 1).fillNone().anchorLeft()); graphUpdatePeriodLabel = new JLabel(graphUpdatePeriod + " msecs"); add(graphUpdatePeriodLabel, gc.incx().anchorRight()); graphUpdatePeriodSlider = new JSlider(MINIMUM_LIVE_DATA_INTERVAL, MAXIMUM_LIVE_DATA_INTERVAL, graphUpdatePeriod); graphUpdatePeriodSlider.setExtent(MINIMUM_LIVE_DATA_INTERVAL); graphUpdatePeriodSlider.setMinorTickSpacing(10*MINIMUM_LIVE_DATA_INTERVAL); graphUpdatePeriodSlider.setMajorTickSpacing(100*MINIMUM_LIVE_DATA_INTERVAL); // graphUpdatePeriodSlider.setSnapToTicks(true); graphUpdatePeriodSlider.setPaintTicks(true); graphUpdatePeriodSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { graphUpdatePeriod = graphUpdatePeriodSlider.getValue(); graphUpdatePeriodLabel.setText(graphUpdatePeriod + " msecs"); } } ); add(graphUpdatePeriodSlider, gc.incx().span(3, 1).fillHorizontal()); gc.col(0).incy().span(1, 1).insets(0, 5, 0, 0).fillHorizontal(); // finally add a glue: gc.col(0).incy().span(1, 1).insets(0, 5, 0, 0); addGlue(gc, GridBagConstraints.BOTH); invalidate(); validate(); repaint(); } private final void startSimulation() { String commandLineOptions = commandLineOptionsTextField.getText() + " --live-data-interval " + liveDataInterval + " --live-data-points " + liveDataPoints; if (commandLineOptions == null || commandLineOptions.length() == 0) { LOGGER.warn("commandLineOptions is null!!!"); } else { LOGGER.info("Command line options:" + commandLineOptions); try { SimulatorCommandLine commandLine = new SimulatorCommandLine(commandLineOptions); graphPanel.clearConsole(); LOGGER.info("Calling Simulator"); Runtime.getRuntime().gc(); simulationJobID = simulationService.submit(new SimulatorInputData(commandLine.getSimulationArguments(), new ConsolePrintStream(graphPanel.getTextArea())), null); setComponentsEnabled(true); progressBar.setIndeterminate(true); graphPanel.resetCharts(); timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { checkStatus(); } }, 0, graphUpdatePeriod); } catch (Exception exception) { if (simulationJobID >= 0) { simulationService.cancel(simulationJobID, true, true); simulationJobID = -1; } exception.printStackTrace(); } } } private final void stopSimulation() { LOGGER.info("Stopping Simulator"); if (simulationJobID >= 0) { simulationService.cancel(simulationJobID, true, true); setComponentsEnabled(false); Runtime.getRuntime().gc(); } simulationJobID = -1; LOGGER.info("Done with Simulator."); } private final void setComponentsEnabled(boolean simulationRunning) { startButton.setEnabled(!simulationRunning); stopButton.setEnabled(simulationRunning); simulationComboBox.setEnabled(!simulationRunning); commandLineOptionsTextField.setEnabled(!simulationRunning); liveDataIntervalSlider.setEnabled(!simulationRunning); graphUpdatePeriodSlider.setEnabled(!simulationRunning); progressBar.setEnabled(simulationRunning); } private void checkStatus() { SimulatorStatusInterface simulatorStatus = simulationService.getSimulatorStatus(simulationJobID); LiveData liveData = simulationService.getSimulatorLiveData(simulationJobID); // LOGGER.info("Simulator Status: " + simulatorStatus.getStatusMessage()); if (simulatorStatus == null) { timer.cancel(); timer.purge(); progressBar.setIndeterminate(false); progressBar.setValue(0); } else { if (simulatorStatus.getProgress() == 1.0) { timer.cancel(); timer.purge(); } // System.err.println("Progress: " + simulatorStatus.getProgress() + " " + simulatorStatus.getStatusMessage()); final int progress = (int) (100.0 * simulatorStatus.getProgress()); if (progress != 0) { progressBar.setIndeterminate(false); progressBar.setValue(progress); if (progress == 100) { stopSimulation(); progressBar.setValue(0); } } if (graphPanel != null) { graphPanel.updateMemoryUsageChart(); } } if (liveData != null) { graphPanel.updateLiveDataChart(liveData); } } @Override public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(SIMULATION_COMBOBOX_ACTION_COMMAND)) { SimulationSettings selectedSimulation = (SimulationSettings)(((JComboBox)(e.getSource())).getSelectedItem()); commandLineOptionsTextField.setText(selectedSimulation.getCommandLineOptions() + " " + COMMAND_LINE_OPTIONS); } } public final List<SimulationSettings> getSimulationSettingsList() { return simulationSettingsList; } public final void setSimulationSettingsList(List<SimulationSettings> simulationSettingsList) { this.simulationSettingsList = simulationSettingsList; /* for (SimulationSettings simulationSettings : simulationSettingsList) { System.err.println(simulationSettings.getCommandLineOptions()); } */ } public final void setGraphPanel(GraphPanel graphPanel) { this.graphPanel = graphPanel; } }