package com.james.uicomparerunner.ui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Event; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import com.james.uicomparerunner.res.R; import com.james.uicomparerunner.ui.dialog.DialogBuilder; import com.james.uicomparerunner.ui.uiinterface.OnWindowCloseListener; import com.james.uicomparerunner.utils.PropertyUtils; import com.james.uicomparerunner.utils.ScriptGenerator; import com.james.uicomparerunner.utils.SystemUtils; public class RecorderEditFrame extends JFrame implements ActionListener { private int monitorWidth; private int monitorHeight; private JMenu[] jMenu = { new JMenu(R.string.menu_file) }; private JMenuItem[] fileMenu = { new JMenuItem(R.string.menu_file_save, KeyEvent.VK_S), new JMenuItem(R.string.menu_file_close, KeyEvent.VK_Q) }; private JMenuBar jMenuBar = new JMenuBar(); private JScrollPane scrollpane; private Box contentBoxPanel; private JButton startButton; private JButton endButton; private JButton whileButton; private JButton saveButton; private JButton clearDataButton; private JTextArea recordText; private JTextArea scriptText; private String mrPath; private String comments; public RecorderEditFrame(final OnWindowCloseListener onWindowCloseListener) { super(); GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); monitorWidth = gd.getDisplayMode().getWidth(); monitorHeight = gd.getDisplayMode().getHeight(); for (JMenuItem item : fileMenu) { jMenu[0].add(item); item.setAccelerator(KeyStroke.getKeyStroke(item.getMnemonic(), SystemUtils.isMac() ? Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() : Event.CTRL_MASK)); item.addActionListener(this); } for (JMenu temp : jMenu) { jMenuBar.add(temp); } this.setJMenuBar(jMenuBar); this.setTitle(R.string.menu_file_edit_recorder); this.setVisible(true); this.setBounds(monitorWidth * 1 / 10, monitorHeight * 1 / 10, monitorWidth * 8 / 10, monitorHeight * 8 / 10); contentBoxPanel = Box.createHorizontalBox(); scrollpane = new JScrollPane(contentBoxPanel); scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scrollpane.setSize(getWidth() * 8 / 10 - 50, getHeight() * 9 / 10 - 50); this.add(scrollpane, BorderLayout.CENTER); scrollpane.setVisible(true); Box leftBox = Box.createVerticalBox(); leftBox.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Edit Record"), BorderFactory.createEmptyBorder(5, 5, 5, 5))); Box rightBox = Box.createVerticalBox(); rightBox.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Script"), BorderFactory.createEmptyBorder(5, 5, 5, 5))); Box buttonBox1 = Box.createHorizontalBox(); Box buttonBox2 = Box.createHorizontalBox(); saveButton = new JButton(R.string.button_save); saveButton.setVerticalTextPosition(AbstractButton.CENTER); saveButton.setHorizontalTextPosition(AbstractButton.LEADING); saveButton.addActionListener(this); saveButton.setToolTipText("Click this button to save & view script code."); buttonBox1.add(saveButton); startButton = new JButton(R.string.button_start_from_desktop); startButton.setVerticalTextPosition(AbstractButton.CENTER); startButton.setHorizontalTextPosition(AbstractButton.LEADING); startButton.addActionListener(this); startButton.setToolTipText("Click this button to start from desktop."); buttonBox1.add(startButton); endButton = new JButton(R.string.button_end_to_desktop); endButton.setVerticalTextPosition(AbstractButton.CENTER); endButton.setHorizontalTextPosition(AbstractButton.LEADING); endButton.addActionListener(this); endButton.setToolTipText("Click this button to back to desktop."); buttonBox1.add(endButton); whileButton = new JButton(R.string.button_add_while); whileButton.setVerticalTextPosition(AbstractButton.CENTER); whileButton.setHorizontalTextPosition(AbstractButton.LEADING); whileButton.addActionListener(this); whileButton.setEnabled(false); whileButton.setToolTipText("Click this button to add while loop."); buttonBox2.add(whileButton); clearDataButton = new JButton(R.string.button_clear_data); clearDataButton.setVerticalTextPosition(AbstractButton.CENTER); clearDataButton.setHorizontalTextPosition(AbstractButton.LEADING); clearDataButton.addActionListener(this); clearDataButton.setToolTipText("Click this button to clear all data."); buttonBox2.add(clearDataButton); recordText = new JTextArea(); leftBox.add(buttonBox1); leftBox.add(buttonBox2); leftBox.add(recordText); scriptText = new JTextArea(); scriptText.setBackground(Color.YELLOW); scriptText.setEditable(false); rightBox.add(scriptText); scriptText.setVisible(true); contentBoxPanel.add(leftBox); contentBoxPanel.add(rightBox); addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent arg0) { } @Override public void windowIconified(WindowEvent arg0) { } @Override public void windowDeiconified(WindowEvent arg0) { } @Override public void windowDeactivated(WindowEvent arg0) { } @Override public void windowClosing(WindowEvent arg0) { String scriptPath = PropertyUtils.loadProperty(PropertyUtils.KEY_LAST_SCRIPT, PropertyUtils.NULL); onWindowCloseListener.onWindowClosing(scriptPath.equalsIgnoreCase(PropertyUtils.NULL) ? null : scriptPath); } @Override public void windowClosed(WindowEvent arg0) { } @Override public void windowActivated(WindowEvent arg0) { } }); } public RecorderEditFrame setRecorder(String mrPath) throws IOException { this.mrPath = mrPath; this.setTitle(mrPath); recordText.setText(""); // Reader rd = new FileReader(mrPath); BufferedReader reader = new BufferedReader(rd); String code = null; String line = null; while ((line = reader.readLine()) != null) { if (code == null) code = line; else code = code + "\n" + line; } reader.close(); recordText.setText(code); comments = "# " + new File(mrPath).getName() + "\n" + "# add " + ScriptGenerator.START_FROM_DESKTOP + " at the 'first' line of code\n" + "# to start app from desktop.\n" + "# add " + ScriptGenerator.END_BACK_TO_DESKTOP + " at the 'last' line of code.\n" + "# to end app back to desktop."; String originCode = getOriginCode(); recordText.setText(comments + "\n" + originCode); recordText.addCaretListener(new CaretListener() { @Override public void caretUpdate(CaretEvent e) { recordText.getSelectedText(); if (recordText.getSelectedText() == null || recordText.getText().equalsIgnoreCase("")) { whileButton.setEnabled(false); } else { whileButton.setEnabled(true); } } }); overwriteRecorder(false); updateScriptCode(); return this; } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JMenuItem) { if (((JMenuItem) e.getSource()).getText().equalsIgnoreCase(R.string.menu_file_save)) { try { overwriteRecorder(true); updateScriptCode(); } catch (IOException e1) { e1.printStackTrace(); } scriptText.setVisible(true); } else if (((JMenuItem) e.getSource()).getText().equalsIgnoreCase(R.string.menu_file_close)) { close(); } } else if (e.getSource().equals(startButton)) { addStartCode(); } else if (e.getSource().equals(endButton)) { addEndCode(); } else if (e.getSource().equals(whileButton)) { addWhileLoopCode(); } else if (e.getSource().equals(saveButton)) { try { overwriteRecorder(true); updateScriptCode(); } catch (IOException e1) { e1.printStackTrace(); } scriptText.setVisible(true); } else if (e.getSource().equals(clearDataButton)) { addClearDataCode(); } } private void addStartCode() { String code = getOriginCode(); if (code.contains(ScriptGenerator.START_FROM_DESKTOP)) return; recordText.setText(comments + "\n" + ScriptGenerator.START_FROM_DESKTOP + "\n" + code); } private void addEndCode() { String code = getOriginCode(); if (code.contains(ScriptGenerator.END_BACK_TO_DESKTOP)) return; recordText.setText(comments + "\n" + code + "\n" + ScriptGenerator.END_BACK_TO_DESKTOP); } private void addClearDataCode() { String code = getOriginCode(); if (code.contains(ScriptGenerator.CLEAR_DATA)) return; recordText.setText(comments + "\n" + ScriptGenerator.START_FROM_DESKTOP + "\n" + ScriptGenerator.CLEAR_DATA + "\n" + code); } private void addWhileLoopCode() { String loopCount = JOptionPane.showInputDialog(null, "Enter loop count : ", "5", 1); if (!isNumeric(loopCount)) { DialogBuilder.showMessageDialog(this, R.string.dialog_alert_input_number); return; } String code = getOriginCode(); String replacedCode = recordText.getSelectedText(); String loop = "LOOP(" + loopCount + ")\n" + replacedCode + (replacedCode.endsWith("\n") ? "" : "\n") + "END LOOP" + (replacedCode.endsWith("\n") ? "\n" : ""); code = code.replace(recordText.getSelectedText(), loop); recordText.setText(comments + "\n" + code); } private static boolean isNumeric(String str) { return str.matches("-?\\d+(\\.\\d+)?"); // match a number with optional '-' and decimal. } private String getOriginCode() { String originalCode = null; String[] splits = recordText.getText().split("\n"); for (String line : splits) { if (line.startsWith("#")) continue; String replaceLine = line; if (line.equalsIgnoreCase("START_FROM_DESKTOP")) { replaceLine = replaceLine.replace("START_FROM_DESKTOP", ScriptGenerator.START_FROM_DESKTOP); } if (line.equalsIgnoreCase("END_BACK_TO_DESKTOP")) { replaceLine = replaceLine.replace("END_BACK_TO_DESKTOP", ScriptGenerator.END_BACK_TO_DESKTOP); } if (originalCode == null) { originalCode = replaceLine; } else { originalCode = originalCode + "\n" + replaceLine; } } return originalCode; } private void overwriteRecorder(boolean showDialog) throws IOException { Writer wt = new FileWriter(new File(mrPath)); BufferedWriter writer = new BufferedWriter(wt); String[] codeLine = recordText.getText().split("\n"); for (int i = 0; i < codeLine.length; i++) { writer.write(codeLine[i]); writer.newLine(); } writer.close(); String monkey_runner_file_path = null; try { monkey_runner_file_path = ScriptGenerator.getScriptFilePath(mrPath); } catch (IOException e) { e.printStackTrace(); } PropertyUtils.saveProperty(PropertyUtils.KEY_LAST_SCRIPT, monkey_runner_file_path); if (showDialog) DialogBuilder.showMessageDialog(this, R.string.dialog_alert_save_success); } public void updateScriptCode() throws IOException { String scriptPath = PropertyUtils.loadProperty(PropertyUtils.KEY_LAST_SCRIPT, PropertyUtils.NULL); if (!scriptPath.equalsIgnoreCase(PropertyUtils.NULL) && new File(scriptPath).exists()) { Reader rd = new FileReader(scriptPath); BufferedReader reader = new BufferedReader(rd); String code = null; String line = null; while ((line = reader.readLine()) != null) { if (code == null) code = line; else code = code + "\n" + line; } reader.close(); scriptText.setText(code); } SwingUtilities.invokeLater(new Runnable() { public void run() { scrollpane.getViewport().setViewPosition(new java.awt.Point(0, 0)); } }); } public void close() { dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } }