001/* The graph controller for interface automata models. 002 003 Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.vergil.modal.ia; 029 030import java.awt.Color; 031import java.awt.event.ActionEvent; 032import java.awt.event.KeyEvent; 033import java.io.File; 034import java.net.URL; 035 036import javax.swing.AbstractAction; 037import javax.swing.JFileChooser; 038import javax.swing.JMenu; 039import javax.swing.JToolBar; 040 041import ptolemy.actor.gui.Configuration; 042import ptolemy.actor.gui.Tableau; 043import ptolemy.domains.modal.kernel.ia.InterfaceAutomaton; 044import ptolemy.gui.JFileChooserBugFix; 045import ptolemy.util.StringUtilities; 046import ptolemy.vergil.modal.FSMGraphController; 047 048/////////////////////////////////////////////////////////////////// 049//// InterfaceAutomatonGraphController 050 051/** 052 A Graph Controller for interface automata models. This controller adds 053 the "Compose With" menu item to the Graph menu. 054 055 @author Steve Neuendorffer, Yuhong Xiong, Contributor: Edward A. Lee 056 @version $Id$ 057 @since Ptolemy II 8.0 058 @Pt.ProposedRating Red (yuhong) 059 @Pt.AcceptedRating Red (johnr) 060 */ 061public class InterfaceAutomatonGraphController extends FSMGraphController { 062 /** Create a new controller with the specified directory of the current 063 * model. The directory is for setting the current directory of 064 * the file chooser invoked by the "Compose With" menu item. 065 * @param directory An instance of File that specifies the directory 066 * of the current model. 067 */ 068 public InterfaceAutomatonGraphController(File directory) { 069 super(); 070 _directory = directory; 071 } 072 073 /////////////////////////////////////////////////////////////////// 074 //// public methods //// 075 076 /** Add commands to the specified menu and toolbar, as appropriate 077 * for this controller. In this class, commands are added to create 078 * ports and relations. 079 * @param menu The menu to add to, or null if none. 080 * @param toolbar The toolbar to add to, or null if none. 081 */ 082 @Override 083 public void addToMenuAndToolbar(JMenu menu, JToolBar toolbar) { 084 super.addToMenuAndToolbar(menu, toolbar); 085 086 // Add an item that does composition. 087 // menu.addSeparator(); 088 diva.gui.GUIUtilities.addMenuItem(menu, _composeWithAction); 089 090 // diva.gui.GUIUtilities.addToolBarButton(toolbar, _newStateAction); 091 } 092 093 /////////////////////////////////////////////////////////////////// 094 //// private variables //// 095 // The action for composing with another interface automaton. 096 private ComposeWithAction _composeWithAction = new ComposeWithAction(); 097 098 // The directory of the current model. 099 private File _directory; 100 101 /////////////////////////////////////////////////////////////////// 102 //// inner classes //// 103 /////////////////////////////////////////////////////////////////// 104 //// ComposeWithAction 105 106 /** An action to perform composition. */ 107 @SuppressWarnings("serial") 108 public class ComposeWithAction extends AbstractAction { 109 /** Create a new action to perform composition. */ 110 public ComposeWithAction() { 111 super("Compose With"); 112 putValue("tooltip", "Compose with another interface automaton"); 113 putValue(diva.gui.GUIUtilities.MNEMONIC_KEY, 114 Integer.valueOf(KeyEvent.VK_C)); 115 } 116 117 /** Compose with another interface automaton by first opening a file 118 * chooser dialog and then composing with the specified model. 119 * The specified model and the composition result are shown in 120 * two new interface automaton graph frames. 121 */ 122 @Override 123 public void actionPerformed(ActionEvent e) { 124 // NOTE: This code is mostly copied from Top. 125 126 // Avoid white boxes in file chooser, see 127 // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801 128 JFileChooserBugFix jFileChooserBugFix = new JFileChooserBugFix(); 129 Color background = null; 130 try { 131 background = jFileChooserBugFix.saveBackground(); 132 JFileChooser fileDialog = new JFileChooser(); 133 fileDialog.setDialogTitle( 134 "Select an interface automaton to compose with."); 135 136 if (_directory != null) { 137 fileDialog.setCurrentDirectory(_directory); 138 } else { 139 // The default on Windows is to open at user.home, which is 140 // typically an absurd directory inside the O/S installation. 141 // So we use the current directory instead. 142 // FIXME: Could this throw a security exception in an applet? 143 String cwd = StringUtilities.getProperty("user.dir"); 144 145 if (cwd != null) { 146 fileDialog.setCurrentDirectory(new File(cwd)); 147 } 148 } 149 150 int returnValue = fileDialog.showOpenDialog(getFrame()); 151 152 if (returnValue == JFileChooser.APPROVE_OPTION) { 153 _directory = fileDialog.getCurrentDirectory(); 154 155 try { 156 // NOTE: It would be nice if it were possible to enter 157 // a URL in the file chooser, but Java's file chooser does 158 // not permit this, regrettably. So we have a separate 159 // menu item for this. 160 File file = fileDialog.getSelectedFile() 161 .getCanonicalFile(); 162 URL url = file.toURI().toURL(); 163 164 // NOTE: Used to use for the first argument the following, 165 // but it seems to not work for relative file references: 166 // new URL("file", null, _directory.getAbsolutePath() 167 Configuration configuration = getConfiguration(); 168 Tableau newAutomatonTableau = configuration 169 .openModel(url, url, url.toExternalForm()); 170 171 // compose the two interface automata and show result 172 InterfaceAutomaton model1 = (InterfaceAutomaton) getFrame() 173 .getModel(); 174 InterfaceAutomatonGraphFrame graphFrame2 = (InterfaceAutomatonGraphFrame) newAutomatonTableau 175 .getFrame(); 176 InterfaceAutomaton model2 = (InterfaceAutomaton) graphFrame2 177 .getModel(); 178 179 InterfaceAutomaton composition = model1.compose(model2); 180 configuration.openModel(composition); 181 } catch (Exception ex) { 182 getFrame().report("Error reading input", ex); 183 } 184 } 185 } finally { 186 jFileChooserBugFix.restoreBackground(background); 187 } 188 } 189 } 190}