/* * testApp.java * * Created on July 15, 2003, 8:04 PM */ package hart2; import javax.swing.*; import java.awt.*; import java.beans.*; import java.awt.event.*; import javax.swing.event.*; import javax.swing.tree.*; import java.util.*; /** * * @author James Hart */ public class testApp extends javax.swing.JFrame { /** Creates new form testApp */ public testApp() { jEquationPane1 = new JEquationPane ( new EquationFrameAdapter( ) ); envelopenum++; //keep track of how high the envelopes have been opened numOpenEnvelopes++;//keep track of number of open envelopes openWindows.add( this ); envelopeName = "Untitled " + envelopenum; Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); sizeScale = screenSize.width/100; initComponents(); setSize( new Dimension( screenSize.width-2, screenSize.height-2 ) ); setLocation(1, 1); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents equationToolBar = new javax.swing.JToolBar(); newEquationButton = new javax.swing.JButton(); jSplitPane1 = new javax.swing.JSplitPane(); jDesktopPane1 = jEquationPane1; InputMap myInputMap = jDesktopPane1.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); ActionMap myActionMap = jDesktopPane1.getActionMap( ); String keyName = "DELETE"; Action deleteAction = new AbstractAction( ) { public void actionPerformed( ActionEvent e ) { JInternalFrame selectedFrame = jDesktopPane1.getSelectedFrame( ); if (selectedFrame != null) deleteRelation( selectedFrame.getTitle() ); } }; myInputMap.put(KeyStroke.getKeyStroke("released DELETE"), keyName ); myActionMap.put(keyName, deleteAction); jScrollPane1 = new javax.swing.JScrollPane(); jTree1 = new javax.swing.JTree(); equationMenuBar = new javax.swing.JMenuBar(); jFile1 = new javax.swing.JMenu(); jNew1 = new javax.swing.JMenuItem(); jNewEnvelope1 = new javax.swing.JMenuItem(); jOpen1 = new javax.swing.JMenuItem(); jClose1 = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); jSave1 = new javax.swing.JMenuItem(); jSaveAs1 = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JSeparator(); jExit1 = new javax.swing.JMenuItem(); jEdit1 = new javax.swing.JMenu(); jCopy = new javax.swing.JMenuItem(); jCombine = new javax.swing.JMenuItem(); jWindows1 = new javax.swing.JMenu(); jNewEnvelope2 = new javax.swing.JMenuItem(); jSeparator4 = new javax.swing.JSeparator(); jHelp1 = new javax.swing.JMenu(); jContents = new javax.swing.JMenuItem(); jIndex = new javax.swing.JMenuItem(); jSeparator3 = new javax.swing.JSeparator(); jAbout = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Equation Editor - " + envelopeName); setFont(new java.awt.Font("Monospaced", 0, 10)); setMaximizedBounds(new java.awt.Rectangle(0, 0, 0, 0)); setResizable(false); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); equationToolBar.setMaximumSize(new java.awt.Dimension(42, 30)); equationToolBar.setMinimumSize(new java.awt.Dimension(42, 30)); newEquationButton.setIcon(new javax.swing.ImageIcon("C:\\Documents and Settings\\James Hart\\My Documents\\My Pictures\\newfile.GIF")); newEquationButton.setToolTipText("New Equation"); newEquationButton.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.RAISED)); newEquationButton.setMargin(new java.awt.Insets(2, 2, 2, 2)); newEquationButton.setMaximumSize(new java.awt.Dimension(24, 25)); newEquationButton.setMinimumSize(new java.awt.Dimension(24, 25)); newEquationButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { onNewRelation(evt); } }); equationToolBar.add(newEquationButton); getContentPane().add(equationToolBar, java.awt.BorderLayout.NORTH); jSplitPane1.setRightComponent(jDesktopPane1); jScrollPane1.setPreferredSize(new Dimension( sizeScale*12, 363 /* 363 is the default*/ )); jTree1.setBorder(new javax.swing.border.TitledBorder(envelopeName)); jTree1.setCellEditor(new EquationTreeCellEditor( )); jTree1.setCellRenderer(new EquationTreeCellRenderer()); jTree1.setEditable(true); jTree1.setInvokesStopCellEditing(true); jTree1.setLargeModel(true); Object myLeadSelectionPath[] = { new String( "This string will not be duplicated" )}; jTree1.setMaximumSize(new java.awt.Dimension(200, 72)); jTree1.setModel(theEnvelope); jTree1.setRootVisible(false); CellEditorListener newTreeCellListener = new CellEditorListener() { public void editingCanceled( ChangeEvent e) { } public void editingStopped( ChangeEvent e ) { Object newVal = ((DefaultCellEditor)e.getSource()).getCellEditorValue(); Object oldVal = ((EquationTreeCellEditor)e.getSource()).getEditedRelation(); //Make sure it changes the name only if the name has actually been changed, not //just edited if ( oldVal instanceof Relation ) { if ( !((Relation)oldVal).getName().equals( newVal.toString() ) ) renameRelation( oldVal, newVal ); } } } ; jTree1.getCellEditor().addCellEditorListener( newTreeCellListener ); jTree1.setSize( 100, 78 ); jTree1.addMouseListener ( new EquationTreeMouseListener( ) ); jTree1.getSelectionModel().addTreeSelectionListener( jEquationPane1 ); //Key event handling //Why is it always so darn complex? InputMap myInputMap2 = jTree1.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); ActionMap myActionMap2 = jTree1.getActionMap( ); String keyName2 = "DELETE"; Action deleteAction2 = new AbstractAction( ) { public void actionPerformed( ActionEvent e ) { if (jTree1.isEditing() ) return; JInternalFrame selectedFrame = jDesktopPane1.getSelectedFrame( ); if (selectedFrame != null) deleteRelation( selectedFrame.getTitle() ); } }; myInputMap2.put(KeyStroke.getKeyStroke("released DELETE"), keyName2 ); myActionMap2.put(keyName, deleteAction2); jTree1.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { onTreeKeyTyped(evt); } }); jScrollPane1.setViewportView(jTree1); jSplitPane1.setLeftComponent(jScrollPane1); getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER); equationMenuBar.setAutoscrolls(true); jFile1.setMnemonic('F'); jFile1.setText("File"); jFile1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jFile1ActionPerformed(evt); } }); jNew1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK)); jNew1.setMnemonic('n'); jNew1.setText("New Equation"); jNew1.setToolTipText("Create new equation"); jNew1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { onNewRelation(evt); } }); jFile1.add(jNew1); jNewEnvelope1.setText("New Envelope"); jNewEnvelope1.setToolTipText("Create new envelope"); jNewEnvelope1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jNewEnvelope1ActionPerformed(evt); } }); jFile1.add(jNewEnvelope1); jOpen1.setMnemonic('o'); jOpen1.setText("Open"); jOpen1.setToolTipText("Open old envelope"); jFile1.add(jOpen1); jClose1.setMnemonic('c'); jClose1.setText("Close"); jClose1.setToolTipText("Close current envelope"); jClose1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jClose1ActionPerformed(evt); } }); jFile1.add(jClose1); jFile1.add(jSeparator1); jSave1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK)); jSave1.setMnemonic('s'); jSave1.setText("Save"); jSave1.setToolTipText("Save current envelope"); jFile1.add(jSave1); jSaveAs1.setMnemonic('a'); jSaveAs1.setText("Save As . . ."); jSaveAs1.setToolTipText("Save current envelope to a different file"); jFile1.add(jSaveAs1); jFile1.add(jSeparator2); jExit1.setMnemonic('x'); jExit1.setText("Exit"); jExit1.setToolTipText("Exit Equation Editor"); jExit1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jExit1ActionPerformed(evt); } }); jFile1.add(jExit1); equationMenuBar.add(jFile1); jEdit1.setMnemonic('E'); jEdit1.setText("Edit"); jCopy.setText("Copy"); jEdit1.add(jCopy); jCombine.setText("Combine"); jEdit1.add(jCombine); equationMenuBar.add(jEdit1); jWindows1.setMnemonic('W'); jWindows1.setText("Windows"); jWindows1.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { jWindows1MenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); jNewEnvelope2.setMnemonic('N'); jNewEnvelope2.setText("New Envelope"); jNewEnvelope2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jNewEnvelope1ActionPerformed(evt); } }); jWindows1.add(jNewEnvelope2); jWindows1.add(jSeparator4); equationMenuBar.add(jWindows1); jHelp1.setMnemonic('H'); jHelp1.setText("Help"); jContents.setText("Contents"); jHelp1.add(jContents); jIndex.setText("Index"); jHelp1.add(jIndex); jHelp1.add(jSeparator3); jAbout.setText("About"); jHelp1.add(jAbout); equationMenuBar.add(jHelp1); setJMenuBar(equationMenuBar); setLocation(new java.awt.Point(0, 0)); }//GEN-END:initComponents private void jWindows1MenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_jWindows1MenuSelected //Clear the menu jWindows1.removeAll(); //Insert the static elements jWindows1.add( jNewEnvelope2 ); jWindows1.add( jSeparator4 ); //Add a menu item for each open window for ( int i = 0; i < openWindows.size(); i++) { //Get the ith window testApp itApp = (testApp)openWindows.get( i ); //get its name String appName = "" + (i+1) + ". " + itApp.envelopeName; //See whether it is the open window boolean toCheck = (this == itApp); //Create the menu item JCheckBoxMenuItem windowItem = new JCheckBoxMenuItem( appName, toCheck ); windowItem.addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { JCheckBoxMenuItem pushedItem = (JCheckBoxMenuItem)e.getSource(); if (!pushedItem.getState()) return; //ignore commands to go to the current window String pushedName = pushedItem.getText(); int endOfNumber = pushedName.indexOf( '.' ); //find the first '.' in the name int appNum = Integer.parseInt( pushedName.substring(0, endOfNumber ) )-1;//get the number of the selected testApp testApp selectedApp = (testApp)openWindows.get( appNum ); selectedApp.toFront(); } } ); jWindows1.add( windowItem ); } }//GEN-LAST:event_jWindows1MenuSelected private void jClose1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jClose1ActionPerformed numOpenEnvelopes--; openWindows.remove( this ); if (numOpenEnvelopes == 0) { System.exit(0); } dispose( ); }//GEN-LAST:event_jClose1ActionPerformed private void jNewEnvelope1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jNewEnvelope1ActionPerformed new testApp().show(); }//GEN-LAST:event_jNewEnvelope1ActionPerformed private void onTreeKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_onTreeKeyTyped //base your action on the entered key code switch ( evt.getKeyCode() ) { case (KeyEvent.VK_DELETE): System.out.println( "This is truly amazing" ); Object deletedObject = jTree1.getSelectionPath().getLastPathComponent(); if (deletedObject != null ) deleteRelation( deletedObject ); } }//GEN-LAST:event_onTreeKeyTyped private void onNewRelation(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onNewRelation Relation newRelation; positionNum++; positionNum%=10; //Make sure it isn't duplicating a previous name in the system //by looping until the name is unique relationNum++; String newName = "Equation " + relationNum; boolean nameUnique = theEnvelope.isUniqueName( newName ); while (!nameUnique) { relationNum++; //keeps track of current Relation name # newName = "Equation " + relationNum; nameUnique = theEnvelope.isUniqueName( newName ); } try { newRelation = theEnvelope.newRelation( "0=0", newName ); } catch (InvalidEquationException e) { e.printStackTrace(); return; } //Set up the new frame JInternalFrame myFrame = jEquationPane1.createInternalFrame( newRelation, 20*positionNum, 20*positionNum ); }//GEN-LAST:event_onNewRelation /** Exit the application */ private void jExit1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jExit1ActionPerformed System.exit( 0 ); }//GEN-LAST:event_jExit1ActionPerformed private void jFile1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jFile1ActionPerformed // Add your handling code here: }//GEN-LAST:event_jFile1ActionPerformed /** Exit the current JFrame - if none left, exit the application */ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm numOpenEnvelopes--; openWindows.remove( evt.getWindow() ); if (numOpenEnvelopes == 0) { System.exit(0); } }//GEN-LAST:event_exitForm /** * @param args the command line arguments */ public static void main(String args[]) { new testApp().show(); } /** Remove a relation from the current envelope * @param identifier a representation of the name of the object to be deleted */ private void deleteRelation(Object identifier) { if (identifier instanceof Relation) identifier = ((Relation)identifier).getName( ); int shouldDelete = JOptionPane.showConfirmDialog( null, "Delete " + identifier + "\nAre you sure?", "Delete " + identifier, JOptionPane.OK_CANCEL_OPTION ); if ( shouldDelete == JOptionPane.OK_OPTION ) { jEquationPane1.removeInternalPane( identifier ); theEnvelope.removeRelation( identifier ); selectActiveFrame( ); } } /** This member routes a rename command to the JInternalPane and * the Envelope * @param oldVal the name of the relation or the relation to be renamed * @param newVal the new name of the relation */ private void renameRelation( Object oldVal, Object newVal ) { if ( theEnvelope.isUniqueName( newVal.toString() ) ) { jEquationPane1.renameInternalPane( oldVal, newVal ); theEnvelope.renameRelation( oldVal, newVal ); } else { JOptionPane.showMessageDialog( this, newVal.toString() + " already exists.", "Equation already exists", JOptionPane.WARNING_MESSAGE ); } } private void selectActiveFrame() { //Activate the next frame, if any is active try { String nextFrameName = jEquationPane1.getSelectedFrame().getTitle(); if (nextFrameName != null) { jTree1.getSelectionModel().setSelectionPath( theEnvelope.getTreePathTo( nextFrameName ) ); jTree1.scrollPathToVisible( theEnvelope.getTreePathTo( nextFrameName ) ); } } catch (NullPointerException e ) { //Only happens if there is no active frame jTree1.getSelectionModel().clearSelection(); } } /** Called when the user does the proper pop-up action on either the * JTree or the JInternalFrame *@param e the MouseEvent that triggered the popup *@param selectedObject the name (or reference to the Relation) of the object being managed *@param onTree boolean which was true if the click was on the JTree */ private void relationPopupHandler(MouseEvent e, final Object selectedObject, boolean onTree) { JPopupMenu contextMenu = new JPopupMenu( ); JMenuItem renameItem = new JMenuItem( "Rename" ); renameItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { TreePath toEditPath = theEnvelope.getTreePathTo( selectedObject ); jTree1.startEditingAtPath( toEditPath ); } } ); JMenuItem deleteItem = new JMenuItem( "Delete" ); deleteItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { deleteRelation( selectedObject ); } } ); JMenu substituteMenu = createSubstituteMenu( "Apply Substitution", selectedObject ); contextMenu.add( deleteItem ); contextMenu.add( renameItem ); contextMenu.addSeparator(); contextMenu.add( substituteMenu ); contextMenu.show( e.getComponent(), e.getX(), e.getY() ); } /** Creates the applied substitution sub-menu *@param menuName the name of the menu which is being created *@param excludeObject the object which was defined as the source of the menu * */ private JMenu createSubstituteMenu( String menuName, final Object excludeObject ) { JMenu returnMenu = new JMenu( menuName ); Relation currentRelations[] = theEnvelope.getRelations( ); for ( int i = 0; i < currentRelations.length; i++ ) { String compName = excludeObject.toString(); if (excludeObject instanceof Relation) compName = ((Relation)excludeObject).getName(); if ( !currentRelations[ i ].getName().equals( compName ) ) { returnMenu.add( currentRelations[ i ].toString() ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e) { if (e.getSource() instanceof JMenuItem) { JMenuItem source = (JMenuItem)e.getSource(); applySubstitution( excludeObject, source.getName() ); } } } ); } } returnMenu.add( "Other . . ." ).addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { otherSubstituteDialogBox( e ); } } ); return returnMenu; } /** Brings up the dialog box for applying a substitution not already *expressed in the current Relations *@param e the ActionEvent which triggered this box * */ private void otherSubstituteDialogBox( ActionEvent e ) { JOptionPane.showMessageDialog( null, "otherSubstituteDialogBox called" ); } /** Applies a substitution to one of the Relations in theEnvelope *@param subInto the name of (or Relation equal to) the Relation to be *substituted into *@param substitution the text or Relation to be substituted into subInto */ private void applySubstitution( Object subInto, Object substitution ) { JOptionPane.showMessageDialog( null, "applySubstitution called" ); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenu jWindows1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator4; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JMenuItem jCombine; private javax.swing.JMenuItem jCopy; private javax.swing.JMenuItem jExit1; private javax.swing.JMenuBar equationMenuBar; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JMenuItem jNewEnvelope2; private javax.swing.JMenuItem jSaveAs1; private javax.swing.JMenuItem jSave1; private javax.swing.JMenuItem jIndex; private javax.swing.JMenuItem jContents; private javax.swing.JMenu jHelp1; private javax.swing.JMenuItem jOpen1; private javax.swing.JMenuItem jNewEnvelope1; private javax.swing.JSeparator jSeparator1; private javax.swing.JMenuItem jClose1; private javax.swing.JDesktopPane jDesktopPane1; private javax.swing.JMenuItem jNew1; private javax.swing.JMenu jEdit1; private javax.swing.JButton newEquationButton; private javax.swing.JToolBar equationToolBar; private javax.swing.JSeparator jSeparator3; private javax.swing.JTree jTree1; private javax.swing.JMenu jFile1; private javax.swing.JMenuItem jAbout; // End of variables declaration//GEN-END:variables private Envelope theEnvelope = new Envelope( ); private int relationNum = 0; private int positionNum = -1; private JEquationPane jEquationPane1; //this is a counter used to determine the new evelopes name static private int envelopenum=0; //this is a counter which records how many windows are currently //open static private int numOpenEnvelopes=0; private String envelopeName; private int sizeScale; static private Vector openWindows = new Vector( ); //keep track of the open JFrames /** Create an InternalPaneListener for the JEquationPane*/ class EquationFrameAdapter extends InternalFrameAdapter { /** Constructor used so the adapter knows the appropriate information*/ EquationFrameAdapter( ) { } /** When the user selects the internal frame, it affects the Jtree as well*/ public void internalFrameActivated( InternalFrameEvent e ) { activateFrame( e.getInternalFrame() ); } /** When the user clicks on the JTree, it reestablishes a minimized frame*/ public void internalFrameDeiconified( InternalFrameEvent e ) { activateFrame( e.getInternalFrame() ); } /** When the Relation window gets iconified, also make it disappear*/ public void internalFrameIconified( InternalFrameEvent e ) { //hide the deiconified image //e.getInternalFrame().setVisible( false ); //Turn the deactivated image gray String closedFrameTitle = e.getInternalFrame().getTitle(); theEnvelope.setActiveState( closedFrameTitle, false ); //if the closed frame was the selected frame, deselect it selectActiveFrame( ); } /** Internal function used to encapsulate behavior common to * deiconification and activation * @param frame internal frame which was deiconified or activated*/ private void activateFrame( JInternalFrame frame ) { //Get the string to open String activeFrameTitle = frame.getTitle(); //Select the given Relation jTree1.getSelectionModel().setSelectionPath( theEnvelope.getTreePathTo( activeFrameTitle ) ); //Activate the selected Relations theEnvelope.setActiveState( activeFrameTitle, true ); //Scroll to the selection, if necessary jTree1.scrollPathToVisible( theEnvelope.getTreePathTo( activeFrameTitle ) ); } } /** Internal class to extend jTree1's mouse listening capabilities*/ class EquationTreeMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { if ( e.isPopupTrigger() ) { popupTriggered( e ); return; } //Test if the click was outside the tree int selRow = jTree1.getRowForLocation( e.getX(), e.getY() ); Object clickedObject = theEnvelope.getChild( theEnvelope.getRoot(), selRow ); if ( clickedObject == null ) {//then it was outside the tree jTree1.stopEditing(); } } public void mouseReleased(MouseEvent e) { if ( e.isPopupTrigger() ) { popupTriggered( e ); return; } } private void popupTriggered(MouseEvent e) { int selRow = jTree1.getRowForLocation( e.getX(), e.getY() ); Object clickedObject = theEnvelope.getChild( theEnvelope.getRoot(), selRow ); //jTree1.setSelectionPath( jTree1.getPathForLocation( e.getX(), e.getY() ) ); if (clickedObject != null ) { relationPopupHandler( e, clickedObject, true ); } } } }