//======================================== // Package //======================================== package trick.simcontrol.utils; //======================================== // Imports //======================================== import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import javax.swing.Box; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; import trick.common.ui.UIUtils; import trick.common.ui.components.DoubleJSlider; import trick.common.utils.VariableServerConnection; import trick.simcontrol.SimControlApplication; /** * The action controller class controls the actions that need to be handled * for {@link SimControlApplication}. There are certain actions done directly * in {@link SimControlApplication} if that way is more convenient. * * @author Hong Chen * @since Trick 09 */ public class SimControlActionController { //======================================== // Public data //======================================== //======================================== // Protected data //======================================== //======================================== // Private Data //======================================== /* For sending or receiving data to/from variable server. */ private VariableServerConnection simcom = null; //======================================== // Constructors //======================================== /** * Default constructor. */ public SimControlActionController() { } public SimControlActionController(VariableServerConnection simcom) { this.simcom = simcom; } //======================================== // Set/Get methods //======================================== /** * Sets VariableServerConnection for communicating with Variable Server. * * @param simcom The VariableServerConnection for Variable Server communication. */ public void setVariableServerConnection(VariableServerConnection simcom) { this.simcom = simcom; } //======================================== // Methods //======================================== /** * Invoked when the user selects Freeze At ... from Actions menu. */ public void handleFreezeAt(double execOutTime, Component dialogParent) { freeze(execOutTime, 0, "Freeze sim at (enter RET):", "Freeze sim at specified time", dialogParent); } /** * Private helper method that serves both handleFreezeAt and handleFreezeIn. * * @see #handleFreezeAt * @see #handleFreezeIn */ private void freeze(double execOutTime, int isRelative, String dialogMsg, String dialogTitle, Component dialogParent) { double inputTime = 0.0; boolean isValid = true; do { String input = (String)JOptionPane.showInputDialog(dialogParent, dialogMsg, dialogTitle, JOptionPane.INFORMATION_MESSAGE); if (input == null || input == "") { return; } else { try { inputTime = Double.parseDouble(input); if (isRelative == 1) { inputTime = inputTime+execOutTime; } if (inputTime < execOutTime) { int choice = JOptionPane.showConfirmDialog(dialogParent, "Can't freeze to time in past! Enter another time?", "Freeze time error", JOptionPane.YES_NO_OPTION); if (choice == JOptionPane.NO_OPTION) { return; } } else { isValid = false; } } catch (NumberFormatException nfe) { } } } while (isValid); try { simcom.put("trick.freeze("+ inputTime + ")\n"); } catch (IOException e) { } } /** * Invoked when the user selects Freeze In ... from Actions menu. */ public void handleFreezeIn(double execOutTime, Component dialogParent) { freeze(execOutTime, 1, "Freeze in this many seconds:", "Freeze sim in specified time", dialogParent); } /** * Invoked when the user selects Checkpoint Objects ... from Actions menu. */ public String handleCheckpointObjects(Component dialogParent, String initObjects) { return (String)JOptionPane.showInputDialog(dialogParent, "Enter checkpoint objects (separated by ,):", "Specify checkpoints objects", JOptionPane.INFORMATION_MESSAGE, null, null, initObjects); } /** * Invoked when the user selects Throttle ... from Actions menu. */ public void handleThrottle(Component dialogParent) { double newRatio = -1.0; JOptionPane optionPane = new JOptionPane(); double min = 0.1; double max = 10.0; final DoubleJSlider slider = new DoubleJSlider(min, max, 1.0, 10.0); slider.setMajorTickSpacing(10); slider.setMinorTickSpacing(1); slider.setPaintTicks(true); slider.setSnapToTicks(true); JLabel minLabel = new JLabel("Min:"); final JTextField minField = new JTextField(Double.toString(min)); minField.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { slider.setDoubleMinimum(Double.valueOf(minField.getText())); } }); JLabel maxLabel = new JLabel("Max:"); final JTextField maxField = new JTextField(Double.toString(max)); maxField.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { slider.setDoubleMaximum(Double.valueOf(maxField.getText())); } }); Box minMaxBox = Box.createHorizontalBox(); minMaxBox.add(Box.createVerticalStrut(10)); minMaxBox.add(minLabel); minMaxBox.add(minField); minMaxBox.add(Box.createHorizontalStrut(30)); minMaxBox.add(maxLabel); minMaxBox.add(maxField); Object msg[] = {"Select a value:", minMaxBox, slider}; optionPane.setMessage(msg); optionPane.setMessageType(JOptionPane.QUESTION_MESSAGE); optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION); JDialog dialog = optionPane.createDialog(dialogParent, "Select Value"); dialog.setVisible(true); int choice = -1; if (optionPane.getValue() != null) { choice = ((Integer)optionPane.getValue()).intValue(); } if (choice == JOptionPane.OK_OPTION) { newRatio = slider.getDoubleValue(); } // If the user selects a new ratio if (newRatio != -1.0) { try { simcom.put("trick.real_time_set_rt_clock_ratio(" + newRatio +")\n"); } catch (IOException e) { } } } /** * Invoked when the users presses the Step button. */ public void handleStep( int debug_flag ) { try { if ( debug_flag == 0 ) { simcom.put("trick.debug_pause_on()\n" + "trick.exec_run()\n") ; } else { simcom.put("trick.debug_signal()\n") ; } } catch (IOException e) { } } /** * Invoked when the user presses the Data Rec On button. */ public void handleRecOnOff(boolean recording) { try { if (recording) { simcom.put("trick.dr_enable()\n"); } else { simcom.put("trick.dr_disable()\n"); } } catch (IOException e) { } } /** * Invoked when the user presses the Start button. */ public void handleStartSim() { try { simcom.put("trick.exec_run()\n"); } catch (IOException e) { System.out.println("Put failed!"); } } /** * Invoked when the user presses the Freeze button. */ public void handleFreeze( int debug_flag ) { try { simcom.put("trick.exec_freeze()\n"); if ( debug_flag == 1 ) { simcom.put("trick.debug_pause_off()\n" ) ; } } catch (IOException e) { System.out.println("Put failed!"); } } /** * Invoked when the user presses Real Time button. */ public void handleRealtime(boolean isRealtime) { try { if (isRealtime) { simcom.put("trick.real_time_enable() \n"); } else { simcom.put("trick.real_time_disable() \n"); } } catch (IOException e) { } } /** * Invoked when the user presses Dump ASCII Chkpnt button. */ public void handleDumpChkpntASCII(String checkpointObjects, String dir, String fileName, Component dialogParent) { if (dir == null) { dir = "."; } // The file name can be redefined by the user. File selectedFile = UIUtils.chooseSaveFile(dir, fileName, null, dialogParent); if (selectedFile != null) { try { // Make sure there are quotes for file name. if (checkpointObjects == null || "".equals(checkpointObjects)) { //Note: it seems that checkpoint command always put RUN_test in front of the file name, //so passing the file name instead of the whole path. //TODO: if users don't like to be forced to save the checkpoing file in RUN_ dir, // modify to use the whole path. simcom.put("trick.checkpoint(\"" + selectedFile.getName() + "\")\n"); } else { simcom.put("trick.checkpoint_objects(\"" + selectedFile.getName() + "\", \""+ checkpointObjects + "\")\n"); } } catch (IOException e) { } } } /** * Invoked when the user presses Dump DMTCP Chkpnt button. */ public void handleDumpDMTCPChkpnt(String dir, String fileName, Component dialogParent) { File selectedFile = UIUtils.chooseSaveFile(dir, fileName, null, dialogParent); if (selectedFile != null) { String parentPath = selectedFile.getParent(); if ( !dir.equals(parentPath) ) { System.out.println("Path was not updated! DMTCP checkpoints are saved in the --chkpt directory specified in s_main_dmtcp." ); } try { simcom.put("trick.dmtcp_checkpoint(\"" + selectedFile.getName() + "\")\n"); } catch (IOException e) {} } } /** * Invoked when the user presses Shutdown button. */ public void handleShutdown() { try { simcom.put("trick.stop()\n"); } catch (IOException e) { } } /** * Invoked when the user presses Load ASCII Chkpnt button. */ public void handleLoadChkpnt(String dir, Component dialogParent) { // If the Sim Run dir is unknown, current dir will be used for the file chooser. if (dir == null) { dir = "."; } // The file name can be redefined by the user. File file = UIUtils.chooseOpenFile(dir, "chkpnt_", null, dialogParent); if (file != null) { try { //simcom.put("sys.exec.sim_com.filename = \"" + fileName + "\";"); //simcom.put("sys.exec.sim_com.command = LdChckCmd ;"); simcom.put("trick.load_checkpoint(\"" + file.getAbsolutePath() + "\")\n"); } catch (IOException e) { } } } /** * Invoked when the user presses Lite button. */ public void handleLite() { // TODO: System.out.println("lite..."); } }