package edu.calpoly.cpe205.fetter; import javax.swing.*; import java.util.*; import java.io.*; import java.lang.reflect.*; import java.lang.*; import java.awt.*; import javax.swing.event.*; import java.awt.event.*; import java.sql.Time; import java.lang.Runtime; /** * This class is the GUI for the main screen of the ETA program. It displays a * representation of all * the field-related and method-related information of an ETAMainModel. It also * displays the GUI for an ETAMainModel's Object Pool and the Status Panel that * shows informational messages from the main test class and from the ETA * program itself * */ // Author: Michael Hebron // Version History: // Nov 19, 2000 - comments/pseudocode added // Nov 20, 2000 - comments added for fields // Nov 28, 2000 - implemented constructor, updated pseudocode // - added method setModel // - implemented addMethodRow, updated pseudocode // - implemented ExitAction, updated pseudocode // - added field refToThis // - implemented OpenClassAction // Jan 12, 2001 - implemented addParameterRow // Jan 12, 2001 - uncommented System.setOut so that output goes // Status Panel // Jan 13, 2001 - implemented addReturnedRow // Jan 13, 2001 - put Status Panel JTextAreas in JTextScrollPane // Jan 13, 2001 - increased wieghty of Status Panel // Jan 31, 2001 - (Phil H) implemented // InstantiateClassAction.actionPerformed(ActionEvent) // Feb 13, 2001 - (Jonathon Lee) added pseudocode in constructor for CBDL setup (make tabs blink) // Mar 08, 2001 - (Phillip Hansen) added code to setup CBDLs public class ETAMainView extends ETAInspectorView { /** * Creates a new instance of an ETAMainView *

* The layout for the four main panels (Object Pool, Methods, Fields, Status) * is done here. * Pre-conditions: none
* Post-conditions: All panels and menus of the ETAMainView become initialized. */ public ETAMainView() { // CALL super class' constructor with null super(null); NewParameterObjectAction newParamAction; // SET methodRows to NEW Vector // SET methodClassLevel to NEW JTabbedPane // SET methodVisibility to NEW HashMap // SET parameterRows to NEW HashMap // SET returnedRows to NEW HashMap methodRows = new Vector(); methodClassLevel = new JTabbedPane(); methodVisibility = new HashMap(); parameterRows = new HashMap(); returnedRows = new HashMap(); // SET menuBar to NEW JMenuBar // SET fileMenu to NEW JMenu with "File" // SET testMenu to NEW JMenu with "Test" // SET helpMenu to NEW JMenu with "Help" // SET preview to NEW JDialog with this and false // SET createPrimitive to NEW CreatePrimitiveDialog with this // CALL setResizable on createPrimitive with false // SET openClassAction to NEW OpenClassAction with "Open Class..." // SET instantiateClassAction to NEW InstantiateClassAction // with "Instantiate Class..." // SET cleanAllAction to NEW CleanAllAction with "Clean All" // SET exitAction to NEW ExitAction with "Exit" // CALL putValue of openClassAction with Action.NAME and "Open Class..." // CALL putValue of cleanAllAction with Action.NAME and "Clean All Test Data Items" // CALL putValue of instantiateClassAction with // Action.NAME and "Instantiate ..." // CALL putValue of exitAction with Action.NAME and "Exit" preview = new JDialog(this, false); menuBar = new JMenuBar(); fileMenu = new JMenu("File"); testMenu = new JMenu("Test"); helpMenu = new JMenu("Help"); fileMenu.setMnemonic('f'); testMenu.setMnemonic('t'); helpMenu.setMnemonic('h'); createPrimitive = new CreatePrimitiveDialog(this); createPrimitive.setResizable(false); openClassAction = new OpenClassAction(); instantiateClassAction = new InstantiateClassAction(); cleanAllAction = new CleanAllAction(); exitAction = new ExitAction(); helpAction = new HelpAction(); openClassAction.putValue(Action.NAME, "Open Class..."); instantiateClassAction.putValue(Action.NAME, "Instantiate ..."); cleanAllAction.putValue(Action.NAME, "Clean All Test Data Items"); exitAction.putValue(Action.NAME, "Exit"); helpAction.putValue(Action.NAME, "Help Contents"); // SET objectPool to NEW JTabbedPane // SET returnedTab to NEW JPanel // SET parameterTab to NEW JPanel // SET statusTabbedPane to NEW JTabbedPane // SET createParam to NEW JButton with "New Test Data Item..." // SET deleteParam to NEW JButton with "Remove" // SET moveReturned to NEW JButton with "Move to 'Test Data Items'" // SET deleteReturned to NEW JButton with "Remove" objectPool = new JTabbedPane(); returnedTab = new JPanel(); parameterTab = new JPanel(); statusTabbedPane = new JTabbedPane(); createParam = new JButton("New Test Data Item..."); deleteParam = new JButton("Remove"); moveReturned = new JButton("Move to 'Test Data Items'"); deleteReturned = new JButton("Remove"); createParam.setMnemonic('n'); deleteParam.setMnemonic('r'); moveReturned.setMnemonic('m'); deleteReturned.setMnemonic('r'); // SET newParamAction to NEW NewParameterObjectAction // CALL putValue of newParamAction with Action.NAME and "New Test Data Item..." // CALL addActionListener of createParam with newParamAction newParamAction = new NewParameterObjectAction(); newParamAction.putValue(Action.NAME, "New Test Data Item..."); createParam.addActionListener(newParamAction); // INITIALIZE ta to NEW JTextArea // CALL setEditable of ta with false // INITIALIZE outStr with ta // INITIALIZE printStr to NEW PrintStream with outStr // CALL setOut of System with printStr // CALL setErr of System with printStr // CALL add of statusTabbedPane with "Output" and ta // INITIALIZE outputCBDL with ta and statusTabbedPane and 0 JTextArea ta = new JTextArea(); // text area being added to Status pane ta.setEditable(false); OutputStream outStr = new OutputAreaStream(ta, "output.txt"); // OutputAreaStream outputting to ta PrintStream printStr = new PrintStream(outStr); // PrintStream using outStr as source of data System.setOut(printStr); System.setErr(printStr); statusTabbedPane.add("Output", new JScrollPane(ta)); ChangeBackgroundDocumentListener outputCBDL = new ChangeBackgroundDocumentListener(ta, statusTabbedPane, 0); // SET ta to NEW JTextArea // CALL setEditable of ta with false // SET errOutputStream to NEW OutputAreaStream with ta // SET outOutputStream to NEW OutputAreaStream with ta // CALL add of statusTabbedPane with "Messages" and ta // INITIALIZE messageCBDL with ta and statusTabbedPane and 1 ta = new JTextArea(); ta.setEditable(false); errOutputStream = new OutputAreaStream(ta, "messages.txt"); outOutputStream = new OutputAreaStream(ta, "messages.txt"); statusTabbedPane.add("Messages", new JScrollPane(ta)); ChangeBackgroundDocumentListener messageCBDL = new ChangeBackgroundDocumentListener(ta, statusTabbedPane, 1); // SET ta to NEW JTextArea // CALL setEditable of ta with false // SET logOutputStream to NEW OutputAreaStream with ta // CALL add of statusTabbedPane with "Session Log" ta // INITIALIZE sessionCBDL with ta and statusTabbedPane and 2 ta = new JTextArea(); ta.setEditable(false); logOutputStream = new OutputAreaStream(ta, "sessionlog.txt"); statusTabbedPane.add("Session Log", new JScrollPane(ta)); ChangeBackgroundDocumentListener sessionCBDL = new ChangeBackgroundDocumentListener(ta, statusTabbedPane, 2); // CALL addMouseListener of statusTabbedPane with CBDL statusTabbedPane.addMouseListener(sessionCBDL); // CALL add of fileMenu with openClassAction // CALL addSeparator of fileMenu // CALL add of fileMenu with exitAction fileMenu.add(openClassAction).setMnemonic('o'); fileMenu.getItem(0).setAccelerator(KeyStroke.getKeyStroke("control O")); fileMenu.addSeparator(); fileMenu.add(exitAction).setMnemonic('x'); fileMenu.getItem(2).setAccelerator(KeyStroke.getKeyStroke("control X")); // CALL add of testMenu with instantiateClassAction // CALL addSeparator of testMenu // CALL add of testMenu with cleanAllAction testMenu.add(instantiateClassAction).setMnemonic('A'); testMenu.getItem(0).setAccelerator(KeyStroke.getKeyStroke("control A")); testMenu.addSeparator(); testMenu.add(newParamAction).setMnemonic('n'); testMenu.getItem(2).setAccelerator(KeyStroke.getKeyStroke("control N")); testMenu.add(cleanAllAction).setMnemonic('e'); testMenu.getItem(3).setAccelerator(KeyStroke.getKeyStroke("control E")); // CALL add of helpMenu with contentsAction // CALL addSeparator of helpMenu // CALL add of helpMenu with aboutAction // todo: add actionlistener inner classes for the above mentioned actions // add member data for new actionlistener classes // add code above to instantiate new actionlisteners/set text values helpMenu.add(helpAction).setMnemonic('H'); helpMenu.getItem(0).setAccelerator(KeyStroke.getKeyStroke("control H")); helpMenu.addSeparator(); helpMenu.add("About..."); //helpMenu.getItem(1).setAccelerator(KeyStroke.getKeyStroke("control A")); // CALL add of menuBar with fileMenu // CALL add of menuBar with testMenu // CALL add of menuBar with helpMenu menuBar.add(fileMenu); menuBar.add(testMenu); menuBar.add(helpMenu); // disable instantiateclassaction instantiateClassAction.setEnabled(false); // CALL add of objectPool with "Returned Objects" and returnedTab // CALL add of objectPool with "Test Data Items" and parameterTab // CALL add of returnedTab with moveReturned // CALL add of returnedTab with deleteReturned // CALL add of parameterTab with createParam // CALL add of parameterTab with deleteParam objectPool.add("Returned Objects", new JScrollPane(returnedTab)); objectPool.add("Test Data Items", new JScrollPane(parameterTab)); JPanel returnedPanel; // "Returned Object" tab's main panel JPanel parameterPanel; // "Test Data Items" tab's main panel JPanel buttonPanel; // panel containing the buttons found in the tabs of the Object Pool returnedPanel = new JPanel(); buttonPanel = new JPanel(); parameterPanel = new JPanel(new GridBagLayout()); returnedTab.setLayout(new GridBagLayout()); returnedPanel.setLayout(new GridBagLayout()); buttonPanel.add(moveReturned); buttonPanel.add(deleteReturned); returnedTab.add(buttonPanel, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); returnedTab.add(returnedPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); returnedTab = returnedPanel; returnedTab.add(new JLabel("Type"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 5 , 0)); returnedTab.add(new JLabel("Name"), new GridBagConstraints( GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); returnedTab.add(new JLabel("Value"), new GridBagConstraints( GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); parameterTab.setLayout(new GridBagLayout()); parameterPanel.setLayout(new GridBagLayout()); buttonPanel = new JPanel(); buttonPanel.add(createParam); buttonPanel.add(deleteParam); parameterTab.add(buttonPanel, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); parameterTab.add(parameterPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); parameterTab = parameterPanel; parameterTab.add(new JLabel("Type"), new GridBagConstraints( 0, 0, 1, 1, 0, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 5 , 0)); parameterTab.add(new JLabel("Name"), new GridBagConstraints( GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); parameterTab.add(new JLabel("Value"), new GridBagConstraints( GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0 , 0)); setTitle("Empirical Test Application"); } /** * Sets the model that this class is a view for *

* Pre-condition: none * Post-condition: The view becomes responsible for displaying * model's data * @param model The ETAMainModel whose data the view becomes responsible for * displaying */ public void setModel(ETAMainModel model) { // SET model of this to model this.model = model; } /** * Creates a new MethodRow and adds it to the collection of MethodRows the * view is responsible for displaying. *

* The new MethodRow is added to the MethodsPanel *

* This function also registers the ParameterObjectComboBoxes of the new * MethodRow as a ParameterDataListener of the ETAMainModel.

* Pre-conditions: none
* Post-conditions: The view has a new MethodRow that it's responsible for * displaying. The combo boxes in the new Method Row become * ParameterDataListeners of the ETAMainModel * @param methodData a MethodDataInterface for the MethodRow that * is being added for the View to display * @return an interface to the newly added MethodRow */ public MethodRowInterface addMethodRow(MethodDataInterface methodData) { // CONSTRUCT mr as MethodRow with methodData // CALL add of methodRows with mr // CALL getDeclaringClass of methodData returns className // CALL get of methodVisibility with className returns vtp Assert.preCondition((methodData != null), "null passed to addMethodRow"); MethodRow mr = new MethodRow(methodData); methodRows.add(mr); String className = methodData.getDeclaringClass(); VisibilityTabbedPane vtp = (VisibilityTabbedPane) methodVisibility.get(className); // IF vtp = null THEN // CONSTRUCT newVT as VisibilityTabbedPane // CALL put of methodVisibility with className and newVT // SET vtp to newVT // ENDIF if (vtp == null) { VisibilityTabbedPane newVT = new VisibilityTabbedPane(); methodVisibility.put(className, newVT); vtp = newVT; methodClassLevel.add(className, vtp); } // CALL addRow of vtp with visibility and mr // CALL getComboBoxes of mr returns arrayOfCB // CALL getLength of Array with arrayOfCB returns i // FOR x = 0 to i - 1 // CALL addParameterDataListener of model with arrayOfCB[x] // ENDFOR //todo: add pseudo for this int visibility = 0; if (Modifier.isPublic(methodData.getModifiers())) { visibility = Modifier.PUBLIC; } else if (Modifier.isProtected(methodData.getModifiers())) { visibility = Modifier.PROTECTED; } else if (Modifier.isPrivate(methodData.getModifiers())) { visibility = Modifier.PRIVATE; } vtp.addRow(visibility, mr); ParameterObjectComboBox[] arrayOfCB = mr.getComboBoxes(); int lengthofArray = Array.getLength(arrayOfCB); for (int step = 0; step < lengthofArray; step++) { model.addParameterDataListener(arrayOfCB[step]); } // RETURN mr return mr; } /** * Creates a new ParameterRow and adds it to the collection of ParameterRows the * view is responsible for displaying. *

* The new ParameterRow is added to the Test Data Item tab of the Object * Pool panel *

* Pre-conditions: none
* Post-conditions: The view has a new ParameterRow that it's responsible for * displaying * @param parameterData a ParameterDataInterface for the ParameterRow that * is being added for the View to display */ public void addParameterRow(ParameterDataInterface paramData) { // CONSTRUCT pr as ParameterRow with paramData // CALL put of parameterRows with paramData and pr // CALL getTypeLabel of pr returns typeLabel // CALL getNameTextField of pr returns nameField // CALL getValueComponent of pr returns valComp // CALL add of parameterTab with typeLabel // CALL add of parameterTab with nameField // CALL add of parameterTab with valComp // CALL getRemoveListener of pr returns remListener // CALL addActionListener of deleteParam with remListener GridBagConstraints cns = new GridBagConstraints(); cns.weightx = 0; cns.fill = GridBagConstraints.BOTH; cns.gridy = GridBagConstraints.RELATIVE; cns.gridx = 0; ParameterRow pr = new ParameterRow(paramData); parameterTab.add(pr.getTypeLabel(), cns); cns.weightx = 1; cns.gridx++; parameterTab.add(pr.getNameTextField(), cns); cns.gridx++; parameterTab.add(pr.getValueComponent(), cns); parameterRows.put(paramData, pr); deleteParam.addActionListener(pr.getRemoveListener()); // CALL validate of CALL getParent of parameterTab // CALL repaint of CALL getParent of parameterTab parameterTab.getParent().validate(); parameterTab.getParent().repaint(); } /** * Creates a new ReturnedRow and adds it to the collection of ReturnedRows the * view is responsible for displaying. *

* The new ReturnedRow is added to the Returned Object tab of the Object * Pool panel * Pre-conditions: none
* Post-conditions: The view has a new ReturnedRow that it's responsible for * displaying * @param returnedData a ReturnedDataInterface for the ReturnedRow that * is being added for the View to display */ public void addReturnedRow(ReturnedDataInterface retData) { // CONSTRUCT rr as ReturnedRow with retData // CALL put of returnedRows with retData and rr // CALL getTypeLabel of rr returns typeLabel // CALL getNameTextField of rr returns nameField // CALL getValueComponent of rr returns valComp // CALL add of returnedTab with typeLabel // CALL add of returnedTab with nameField // CALL add of returnedTab with valComp // CALL getRemoveListener of rr returns remListener // CALL addActionListener of deleteReturned with remListener // CALL getMoveListener of rr returns moveListener // CALL addActionListener of moveReturned with moveListener GridBagConstraints cns = new GridBagConstraints( 0 , GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); ReturnedRow rr = new ReturnedRow(retData); returnedTab.add(rr.getTypeLabel(), cns); cns.gridx++; returnedTab.add(rr.getNameTextField(), cns); cns.gridx++; returnedTab.add(rr.getValueComponent(), cns); returnedRows.put(retData, rr); deleteReturned.addActionListener(rr.getRemoveListener()); moveReturned.addActionListener(rr.getMoveListener()); // CALL validate of CALL getParent of returnedTab // CALL repaint of CALL getParent of returnedTab returnedTab.getParent().validate(); returnedTab.getParent().repaint(); } /** * Removes the parameterRow in the Test Data Items tab of the Object Pool * panel associated with ParameterDataInterface paramData *

* If the view has no ParameterRow representing paramData * this method does nothing. *

* Pre-conditions: none
* Post-conditions: The view no longer displays the information representing * paramData * @param paramData the ParameterDataInterface for the ParameterRow that * is going to be removed from the view */ public void removeParameterRow(ParameterDataInterface paramData) { // CALL get of parameterRows with paramData returns removedRow // IF NOT removedRow = null THEN // CALL remove of parameterRows with paramData // CALL getTypeLabel of removedRow returns typeLabel // CALL getNameTextField of removedRow returns nameField // CALL getValueComponent of removedRow returns valComp // CALL remove of parameterTab with typeLabel // CALL remove of parameterTab with nameField // CALL remove of parameterTab with valComp ParameterRow removedRow = (ParameterRow) parameterRows.get(paramData); if (removedRow != null) { parameterRows.remove(paramData); parameterTab.remove(removedRow.getTypeLabel()); parameterTab.remove(removedRow.getNameTextField()); parameterTab.remove(removedRow.getValueComponent()); // CALL getRemoveListener of pr returns remListener // CALL removeActionListener of deleteParam with remListener deleteParam.removeActionListener(removedRow.getRemoveListener()); // CALL validate of CALL getParent of parameterTab // CALL repaint of CALL getParent of parameterTab parameterTab.getParent().validate(); parameterTab.getParent().repaint(); } // ENDIF } /** * Removes the returnedRow in the Returned Objects tab of the Object Pool * panel associated with ReturnedDataInterface retData *

* If the view has no ReturnedRow representing retData * this method does nothing. *

* Pre-conditions: none
* Post-conditions: The view no longer displays the information representing * retData */ public void removeReturnedRow(ReturnedDataInterface retData) { // CALL get of returnedRows with retData returns removedRow // IF NOT removedRow = null THEN // CALL remove of returnedRows with retData // CALL getTypeLabel of removedRow returns typeLabel // CALL getNameTextField of removedRow returns nameField // CALL getValueComponent of removedRow returns valComp // CALL remove of returnedTab with typeLabel // CALL remove of returnedTab with nameField // CALL remove of returnedTab with valComp ReturnedRow removedRow = (ReturnedRow) returnedRows.get(retData); if (removedRow != null) { returnedRows.remove(retData); returnedTab.remove(removedRow.getTypeLabel()); returnedTab.remove(removedRow.getNameTextField()); returnedTab.remove(removedRow.getValueComponent()); // CALL getRemoveListener of removedRow returns remListener // CALL removeActionListener of deleteReturned with remListener deleteReturned.removeActionListener( removedRow.getRemoveListener()); // CALL getMoveListener of removedRow returns moveListener // CALL removeActionListener of moveReturned with moveListener moveReturned.removeActionListener(removedRow.getMoveListener()); // CALL validate of CALL getParent of returnedTab // CALL repaint of CALL getParent of returnedTab returnedTab.getParent().validate(); returnedTab.getParent().repaint(); } // ENDIF } /** * Clears the view of its MethodRows *

* Pre-conditions: none
* Post-conditions: The view is no longer displaying MethodRows. The combo boxes * in the removed MethodRow are unregistered from the ETAMainModel as * ParameterDataListeners */ public void clearMethods() { // CALL iterator of methodRows returns itr // WHILE hasNext of itr // CALL next of itr returns removeRow // CALL getComboBoxes of removeRow returns arrayOfCB // CALL getLength of arrayOfCB returns i // FOR x = 0 to i - 1 // CALL removeParameterDataListener of model with arrayOfCB[x] // ENDFOR // ENDWHILE Iterator itr = methodRows.iterator(); ParameterObjectComboBox[] arrayOfCB = null; while (itr.hasNext()) { arrayOfCB = ((MethodRow) itr.next()).getComboBoxes(); for (int ndx = 0; ndx < arrayOfCB.length; ndx++) { model.removeParameterDataListener(arrayOfCB[ndx]); } } // CALL values of methodVisibility returns tabs // CALL iterator of tabs returns itr // WHILE hasNext of itr // CALL next of itr returns visTab // CALL remove of methodClassLevel with visTab // ENDWHILE itr = methodVisibility.values().iterator(); while (itr.hasNext()) { methodClassLevel.remove((Component) itr.next()); } // CALL clear of methodVisibility // CALL clear of methodRows methodVisibility.clear(); methodRows.clear(); } /** * Clears the view of its Component Preview panel *

* Pre-conditions: none
* Post-conditions: The view is no longer displaying a Component Preview panel */ public void clearPreview() { //CALL setVisible on preview with false //CALL getContentPane on preview returns cont //CALL removeAll on cont //CALL setTitle on preview with "" preview.setVisible(false); preview.getContentPane().removeAll(); preview.setTitle(""); } /** * Tells the view to display a preview of the GUI object * previewObject *

* A 'Component Preview' panel containing the Component * previewObject is added to the main screen * Pre-conditions: previewObject must not be null
* Post-conditions: The view becomes responsible for displaying a preview of * previewObject * @param previewObject The GUI object that a preview will be displayed for */ public void setPreviewComponent(Component previewObject) { //CALL getClass on previewObject RETURNS cls //CALL getName on cls RETURNS name //CALL setTitle on preview with name //CALL preview getContentPane RETURNS content //CALL add on content with previewObject //CALL setVisible on preview with true if(!(java.awt.Window.class.isAssignableFrom(previewObject.getClass()))) { preview.setTitle("Component View " + previewObject.getClass().getName()); preview.getContentPane().add(previewObject); preview.pack(); preview.setVisible(true); } else { ((java.awt.Window) previewObject).setVisible(true); } } /** * Lays out the four main panels of the ETA program *

* This method is meant to be called only once, right after construction * of the view *

* Pre-conditions: The view hasn't had layoutGUI called on it before
* Post-conditions: The view's four main panels become layed out in * an orderly fashion */ public void layoutGUI() { JSplitPane splitMethodField; // split pane with method and field panels (upper right of layout) JSplitPane splitMFObjectPool; // split pane with object pool and method/field panels (upper half of layout) JSplitPane splitMFOStatusPane; // split pane with object pool/method/field and status panels (whole layout) GridBagConstraints gbCons = new GridBagConstraints(); // GridBagConstraints used to layout splitMFOStatusPane in the dialog // CALL setJMenuBar of this with menuBar // CALL setLayout of getContentPane with NEW GridBagLayout setJMenuBar(menuBar); getContentPane().setLayout(new GridBagLayout()); // CALL setBorder of objectPool with CALL createTitledBorder of BorderFactory with "Object Pool" // CALL setBorder of methodClassLevel with CALL createTitledBorder of BorderFactory with "Methods" // CALL setBorder of fieldClassLevel with CALL createTitledBorder of BorderFactory with "Fields" // CALL setBorder of statusTabbedPane with CALL createTitledBorder of BorderFactory with "Status" objectPool.setBorder(BorderFactory.createTitledBorder("Object Pool")); methodClassLevel.setBorder(BorderFactory.createTitledBorder("Methods")); fieldClassLevel.setBorder(BorderFactory.createTitledBorder("Fields")); statusTabbedPane.setBorder(BorderFactory.createTitledBorder("Status")); /* ensure that ETA starts out at a reasonable size */ // CALL setPreferredSize of methodClassLevel with NEW Dimension 400 by 180 // CALL setPreferredSize of fieldClassLevel with NEW Dimension 400 by 180 methodClassLevel.setPreferredSize(new Dimension(400, 180)); fieldClassLevel.setPreferredSize(new Dimension(400, 180)); // CONSTRUCT splitMethodField as NEW JSplitPane with JSplitPane.VERTICAL_SPLIT, fieldClassLevel, methodClassLevel // CONSTRUCT splitMFObjectPool as NEW JSplitPane with JSplitPane.VERTICAL_SPLIT, objectPool, splitMethodField // CONSTRUCT splitMFOStatusPane as NEW JSplitPane with JSplitPane.VERTICAL_SPLIT, splitMFObjectPool, statusTabbedPane splitMethodField = new JSplitPane(JSplitPane.VERTICAL_SPLIT, methodClassLevel, fieldClassLevel); splitMFObjectPool = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, objectPool, splitMethodField); splitMFOStatusPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, splitMFObjectPool, statusTabbedPane); // SET gridx of gbCons to 0 // SET gridy of gbCons to 0 // SET weightx of gbCons to 1 // SET weighty of gbCons to 1 // SET fill of gbCons to GridBagConstraints.BOTH // SET anchor of gbCons to GridBagConstraints.CENTER // CALL add of getContentPane with splitMFOStatusPane and gbCons gbCons.gridx = 0; gbCons.gridy = 0; gbCons.weightx = 1; gbCons.weighty = 1; gbCons.fill = GridBagConstraints.BOTH; gbCons.anchor = GridBagConstraints.CENTER; getContentPane().add(splitMFOStatusPane, gbCons); // CALL pack of this // CALL setDividerLocation of splitMFOStatusPane with 0.6 pack(); splitMFOStatusPane.setDividerLocation(0.6); // CALL pack of this // CALL setDividerLocation of splitMethodField with 0.6 pack(); splitMethodField.setDividerLocation(0.5); // CALL setOneTouchExpandable of splitMFOStatusPane with true // CALL setOneTouchExpandable of splitMethodField with true // CALL setOneTouchExpandable of splitMFObjectPool with true splitMFOStatusPane.setOneTouchExpandable(true); splitMethodField.setOneTouchExpandable(true); splitMFObjectPool.setOneTouchExpandable(true); } /** * Returns the OutputStream used for outputting messages to the Session Log tab * of the Status panel *

* @return the OutputStream used for outputting messages to the Session Log */ public OutputStream getLogOutputStream() { // RETURN logOutputStream return logOutputStream; } /** * Returns the OutputStream used for outputting informational messages * from the ETA to the Messages tab of the Status panel *

* @return the OutputStream used for outputting informational messages * to the Output tab of the Status panel */ public OutputStream getOutOutputStream() { // RETURN outOutputStream return outOutputStream; } /** * Returns the OutputStream used for outputting error messages from the * ETA to the Messages tab of the Status panel * @return the OutputStream used for outputting error messages from the main * test object to the Output tab of the Status panel */ public OutputStream getErrOutputStream() { // RETURN errOutputStream return errOutputStream; } /** * Enables/disables the view's GUI components to allow/disallow the user to * test the main test object *

* Pre-conditions: none
* Post-conditions: The view's GUI components for displaying/invoking methods * and displaying/editing fields become enabled/disabled * @param enable a boolean, where true enables the components and false * disables them */ public void enableMainTest(boolean enable) { // CALL iterator of fieldRows returns itr // WHILE hasNext of itr // CALL next of itr returns disableRow // CALL setEnabled of disable with enable // CALL getComboBoxes of disableRow returns arrayOfCB // CALL setEnabled of arrayOfCB[0] with enable // ENDWHILE Iterator itr = fieldRows.iterator(); RowAbstract disableRow = null; while (itr.hasNext()) { disableRow = (FieldRow) itr.next(); disableRow.setEnabled(enable); } // CALL iterator of methodRows returns itr // WHILE hasNext of itr // CALL next of itr returns disableRow // CALL setEnabled of disableRow with enable // ENDWHILE itr = methodRows.iterator(); while(itr.hasNext()) { disableRow = (MethodRow) itr.next(); disableRow.setEnabled(enable); } } /** * The dialog that will display the Test Object if the test Object is derived from * Component */ protected JDialog preview; /** * Collection of MethodRows that this view is responsible for displaying in its * Method panel */ protected Collection methodRows; /** * Map of ParameterDataInterfaces to ParameterRows that this view is * responsible for displaying in the * Test Data Items tab of its Object Pool panel */ protected Map parameterRows; /** * Map of ReturnedDataInterfaces to ReturnedRows. The view is * responsible for displaying these ReturnedRows in the Returned Objects * tab of its Object Pool panel */ protected Map returnedRows; /** * The Methods panel of the ETA that has tabs for each class in the main test * object's class hierarchy. Each of these tabs displays MethodRows for * each method of a class */ protected JTabbedPane methodClassLevel; /** * The Component Preview panel of the ETA */ protected JPanel compPrevPanel; /** * Map of Strings (representing class names) to VisibitlityTabbedPanes. The * VisibilityTabbedPanes are used in the Method and Field panels of the ETA *@link aggregation * @associates <{VisibilityTabbedPane}> */ protected java.util.Map methodVisibility; /** * The ETA's menu bar */ protected JMenuBar menuBar; /** * The ETA's file menu */ protected JMenu fileMenu; /** * The ETA's test menu */ protected JMenu testMenu; /** * The ETA's help menu */ protected JMenu helpMenu; /** * A reference to a CreatePrimitiveDialog *

* create is made visible when the user chooses to create a * primitive test data item */ protected CreatePrimitiveDialog createPrimitive; /** * The action representing the "Open Class..." menu item */ protected AbstractAction openClassAction; /** * The action representing the "Exit" menu item */ protected AbstractAction exitAction; /** * The action representing the "Instantiate Class..." menu item */ protected AbstractAction instantiateClassAction; /** * The action representing the "Clean All" menu item */ protected AbstractAction cleanAllAction; /** * The action representing the "Help Contents" menu item */ protected AbstractAction helpAction; /** * The Object Pool panel of the ETA that has tabs for Test Data Items and * Returned objects */ protected JTabbedPane objectPool; /** @link dependency */ /*#ChangeBackgroundDocumentListener lnkChangeBackgroundDocumentListener;*/ /** * The Status panel of the ETA that displays output from the main test class, * messages from the ETA program itself, and the session log */ protected JTabbedPane statusTabbedPane; /** * The Returned Objects tab of the Object Pool */ protected JPanel returnedTab; /** * The Test Data Items tab of the Object Pool */ protected JPanel parameterTab; /** * The "New Test Data Item..." button in the Test Data Items tab */ protected JButton createParam; /** * The "Remove" button in the Test Data Items tab */ protected JButton deleteParam; /** * The "Move to 'Test Data Items'" button in the Returned Objects tab */ protected JButton moveReturned; /** * The "Remove" button in the Returned Objects tab */ protected JButton deleteReturned; /** * The OutputAreaStream used for outputting ETA's internal error messages * to the Messages tab of the Status panel */ protected OutputAreaStream errOutputStream; /** * The OutputAreaStream used for outputting messages to the Session Log */ protected OutputAreaStream logOutputStream; /** * The OutputAreaStream used for outputting ETA's informational messages * to the Messages tab of the Status panel */ protected OutputAreaStream outOutputStream; /** * This class is used by the ETAMainView to listen for clicks on the * "New Test Data Item..." button of the Test Data Item tab */ protected class NewParameterObjectAction extends AbstractAction { /** * Brings up the set of dialogs needed to allow the user to create a * new Test Data Item *

* Pre-conditions: none
* Post-conditions: A series of dialogs prompting the user what type of Test * to create has been displayed * @param evt The action event generated by clicks on the "New * Test Data Item..." button */ public void actionPerformed(ActionEvent evt) { // INITIALIZE newParamType as NEW array of Strings with length 2 // SET newParamType[0] = "Primitive Type" // SET newParamType[1] = "Derived from 'Object'" String[] newParamType = new String[] {"Primitive Type", "Derived from 'Object'"}; // CALL showInputDialog of JOptionPane with // this and // "New Test Data Item is" and // "New Test Data Item - Select Type" and // JOptionPane.OK_CANCEL_OPTION and // NULL and // newParamType[0] // returns choice String choice = (String) JOptionPane.showInputDialog(ETAMainView.this, "New Test Data Item is", "New Test Data Item - Select Type", JOptionPane.OK_CANCEL_OPTION, null, newParamType, newParamType[0]); repaint(); // IF NOT choice = null THEN if (choice != null) { // IF choice = newParamType[0] THEN // CALL setVisible of createPrimitive // IF getStatus of createPrimitive THEN // CALL getObject of createPrimitive returns newPrim // CALL getName of createPrimitive returns primName // CALL addParameterData of model with newPrim, primName // ENDIF if (choice == newParamType[0]) { createPrimitive.setVisible(true); repaint(); if (createPrimitive.getStatus()) { Assert.assert(createPrimitive.getObject() != null, "createPrimitive.getObject() can't be null"); Assert.assert((createPrimitive.getName() != null), "createPrimitive.getName() can't be null"); Assert.assert(createPrimitive.getName().length() > 0, "createPrimitive.getName() can't be empty"); model.addParameterData(createPrimitive.getObject(), createPrimitive.getName()); } } // ELSE // INITIALIZE classPathOk as boolean with false // INITIALIZE classError as boolean with false // CONSTRUCT prompt as String with "Class Path" // WHILE NOT classPathOk // CALL showInputDialog of JOptionPane with // this and // prompt // "New Test Data Item - Object Type Class Path" and // JOptionPane.QUESTION_MESSAGE // returns classPath // IF NOT classPath = null THEN // SET classPathOk to true // TRY // CALL forName of Class with classPath returns newClass // ENDTRY // CATCH LinkageError // SET classPathOk to false // SET classError to true // CALL println of err of ETA with "Linkage Error" // CALL printStackTrace of LinkageError with err of ETA // ENDCATCH // CATCH ExceptionInInitializerError // SET classPathOk to false // SET classError to true // CALL println of err of ETA with "Initializer Error" // CALL printStackTrace of ExceptionInInitializer // with err of ETA // ENDCATCH // CATCH ClassNotFoundException // SET classPathOk to false // SET prompt to "Please Enter a valid Class Path" // CALL println of out of ETA with "Class Path not valid" // ENDCATCH // ELSE // RETURN // ENDIF // ENDWHILE else { Assert.assert(choice == newParamType[1], "invalid choice picked in 'select type' dialog"); Class testDataClass = null; String classPath = JOptionPane.showInputDialog(ETAMainView.this, "Class Path", "New Test Data Item - Object Type Class Path", JOptionPane.QUESTION_MESSAGE); repaint(); while(testDataClass == null && classPath != null) { try { testDataClass = Class.forName(classPath); } catch (ExceptionInInitializerError err) { err.printStackTrace(ETA.err); classPath = null; } catch (LinkageError err) { err.printStackTrace(ETA.err); classPath = null; } catch (ClassNotFoundException exc) { //exc.printStackTrace(ETA.err); classPath = JOptionPane.showInputDialog(ETAMainView.this, "Please Enter a valid Class Path", "New Test Data Item - Object Type Class Path", JOptionPane.QUESTION_MESSAGE); repaint(); } } // INITIALIZE constructorsOK as boolean with true // TRY // CALL getConstructors of newClass returns constructors // ENDTRY // CATCH SecurityException // CALL println of err of ETA with "Security Error when trying // to get constructors" // CALL printStackTrace of SecurityException with err of ETA // SET constructorsOK to false // ENDCATCH // IF NOT constructorsOK THEN // RETURN // ENDIF // CONSTRUCT insDialog as InstantiateClassDialog with // false and this and constructors // CALL setVisible of insDialog with true // IF getStatus of setVisible THEN // CALL getName of insDialog returns itemName // CALL getSelectedConstructor of insDialog returns cons // CALL getParameters returns of insDialog params // CALL addParameterData of model with // name and cons and params // ENDIF // ENDIF // ENDIF try { if (testDataClass != null) { InstantiateClassDialog insDialog = new InstantiateClassDialog( false, ETAMainView.this, testDataClass.getDeclaredConstructors(), model); insDialog.setVisible(true); repaint(); if (insDialog.getStatus()) { Assert.assert(insDialog.getName() != null, "insDialog.getName() can't be null"); Assert.assert(insDialog.getName().length() > 0, "insDialog.getName() can't be empty"); Assert.assert(insDialog.getSelectedConstructor() != null, "insDialog.getSelectedConstructor() can't be null"); model.addParameterData( insDialog.getSelectedConstructor(), insDialog.getParameters(), insDialog.getName()); } } } catch (SecurityException exc) { exc.printStackTrace(ETA.err); } } } } } /** * This class is used by the ETAMainView to listen to clicks on the * "Open Class..." menu item */ protected class OpenClassAction extends AbstractAction { /** * Brings up the Open Class dialog *

* @param evt The action event generated by clicks on the "Open Class..." * menu item */ public void actionPerformed(ActionEvent evt) { // INITIALIZE classPathOk as boolean with false // CONSTRUCT prompt as String with "Class Path" boolean classPathOk = false; String prompt = "Class Path"; // WHILE NOT classPathOk // CALL showInputDialog of JOptionPane with // this and // prompt // "Open Class" and // JOptionPane.QUESTION_MESSAGE // returns classPath // SET prompt = // "Class Path not valid. Please enter a valid Class Path" while (!classPathOk) { String classPath = JOptionPane.showInputDialog(ETAMainView.this, prompt, "Open Class", JOptionPane.QUESTION_MESSAGE); repaint(); prompt = "Class Path not valid. Please enter a valid Class Path"; // IF NOT classPath = null THEN // CALL setWorkingClass of model // with classPath returns classPathOk // ELSE // RETURN // ENDIF if (classPath != null) { classPathOk = model.setMainTestClass(classPath); if (classPathOk) { setTitle("Empirical Test Application - " + classPath); instantiateClassAction.setEnabled(true); instantiateClassAction.putValue(Action.NAME, "Instantiate " + classPath); ETA.log.print("["); ETA.log.print((new Time(System.currentTimeMillis())).toString().substring(0, 5)); ETA.log.println("] Open class '" + classPath + "'"); } } else { return; } // ENDWHILE } } } /** * This class is used by the ETAMainView to listen to clicks on the * "Instantiate Class..." menu item */ protected class InstantiateClassAction extends AbstractAction { /** * Brings up the Instantiate Class dialog *

* Pre-conditions: none
* Post-conditions: The "Instantiate Class..." menu item becomes disabled * @param evt The action event generated by clicks on the "Instantiate * Class..." menu item */ public void actionPerformed(ActionEvent evt) { // CALL getMainTestClass of model returns mainClass // TRY // CALL getConstructors of newClass returns constructors // CONSTRUCT insDialog as InstantiateClassDialog with // true and this and constructors // CALL setVisible of insDialog with true // IF getStatus of insDialog THEN // CALL getSelectedConstructor returns cons // CALL getParameters returns params // CALL getName returns name // CALL instantiateClass of model with // cons and params and name // CALL setEnabled with false // ENDIF // ENDTRY // CATCH SecurityException // CALL println of err of ETA with "Security Error when trying // to get constructors" // CALL printStackTrace of SecurityException with err of ETA // SET constructorsOK to false // ENDCATCH Class mainClass = model.getMainTestClass(); try { Constructor [] constructors = mainClass.getDeclaredConstructors(); InstantiateClassDialog insDialog = new InstantiateClassDialog(true, ETAMainView.this, constructors, model); insDialog.setVisible(true); repaint(); if (insDialog.getStatus()) { model.instantiateClass(insDialog.getSelectedConstructor(), insDialog.getParameters(), insDialog.getName()); setEnabled(false); } } catch (SecurityException ex) { ETA.err.println("Security Error when trying to get constructors"); ex.printStackTrace(ETA.err); } } } /** * This class is used by the ETAMainView to listen to clicks on the * "Clean All" menu item */ protected class CleanAllAction extends AbstractAction { /** * Clears the Object Pool of all its Test Data items and Returned Objects *

* Pre-conditions: none
* Post-conditions: none * @param evt The action event generated by clicks on the "Clean All" * menu item */ public void actionPerformed(ActionEvent evt) { // CALL keySet of parameterRows returns paramDatas // CALL iterator of paramDatas returns itr // WHILE hasNext of itr // CALL next of itr returns remRow // CALL remove on remRow // ENDWHILE // CALL keySet of returnedRows returns retDatas // CALL iterator of retDatas returns itr // WHILE hasNext of itr // CALL next of itr returns remRow // CALL remove on remRow // ENDWHILE Iterator itr = null; //an iterator of the rows, will be used in while loops itr = (new ArrayList(parameterRows.keySet())).iterator(); /* remove all Test data items in the object pool*/ while(itr.hasNext()) { ((ParameterDataInterface) itr.next()).remove(); } itr = (new ArrayList(returnedRows.keySet())).iterator(); /* remove all Returned data items in the object pool*/ /*while(itr.hasNext()) { ((ReturnedDataInterface) itr.next()).remove(); }*/ } } /** * This class is used by the ETAMainView to listen to clicks on the "Exit" * menu item */ protected class ExitAction extends AbstractAction { /** * Exits the ETA program *

* Pre-conditions: none
* Post-conditions: The ETA program is closed * @param evt The action event generated by clicks on the "Exit" * menu item */ public void actionPerformed(ActionEvent evt) { // CALL exit of System with 0 System.exit(0); } } /** * This class is used by the ETAMainView to listen to clicks on the * "Help Contents" menu item */ protected class HelpAction extends AbstractAction { /** * Opens a browser window to allow the user to view the user manual / help documents *

* Pre-conditions: none
* Post-conditions: Browser window opens displaying help file * @param evt The action event generated by clicks on the "Help Contents" * menu item */ public void actionPerformed(ActionEvent evt) { try { Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler http://cobra.csc.calpoly.edu/~team_4/usermanual.html"); } catch (IOException exception) { JOptionPane.showMessageDialog(null, "Load Failed"); } } } }