001/* A tableau representing a dialog window. 002 003 Copyright (c) 2003-2013 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 */ 027package ptolemy.actor.gui; 028 029import java.awt.Frame; 030import java.lang.reflect.Constructor; 031import java.util.Iterator; 032 033import javax.swing.JFrame; 034 035import ptolemy.kernel.Entity; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.KernelException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.NamedObj; 040import ptolemy.util.MessageHandler; 041 042/////////////////////////////////////////////////////////////////// 043//// DialogTableau 044 045/** 046 A tableau representing a Dialog in a toplevel window. 047 <p> 048 DialogTableau is just like all the other XXXTableau classes except that the 049 Frame associated with DialogTableau is not an extension of TableauFrame, and, 050 ultimately, the Top class. The reason being that Top adorns the GUI 051 manifestation with the normal status bar which isn't appropriate for a 052 dialog. 053 In addition, the created dialog is not a JDialog, but a JFrame. And, the 054 created dialog is non-modal. 055 <p> 056 There can be any number of instances of this class in an effigy, however, 057 there 058 can only be one each for the model represented by the effigy, and one each of 059 the actors that are part of the model. 060 061 @author Rowland R Johnson 062 @version $Id$ 063 @since Ptolemy II 4.0 064 @Pt.ProposedRating Red (rowland) 065 @Pt.AcceptedRating Red (cxh) 066 @see Effigy 067 */ 068public class DialogTableau extends Tableau { 069 /** Construct a new tableau for the model represented by the given effigy. 070 * Use setFrame() to specify the Dialog after construction. 071 * @param container The container. 072 * @param name The name. 073 * @exception IllegalActionException If the container does not accept 074 * this entity (this should not occur). 075 * @exception NameDuplicationException If the name coincides with an 076 * attribute already in the container. 077 */ 078 public DialogTableau(Effigy container, String name) 079 throws IllegalActionException, NameDuplicationException { 080 super(container.workspace()); 081 082 setName(name); 083 setContainer(container); 084 } 085 086 /////////////////////////////////////////////////////////////////// 087 //// public methods //// 088 089 /** Create a tableau for the specified dialog. First look to see 090 * if a dialog already exists. If so, then just return that one. 091 * @param parent The Frame parent 092 * @param configuration The configuration 093 * @param effigy The Effigy containing the model that needs a dialog. 094 * @param dialogClass The Dialog class to create. 095 * @param target The entity that needs the Dialog 096 * @return DialogTableau 097 */ 098 public static DialogTableau createDialog(Frame parent, 099 Configuration configuration, Effigy effigy, Class dialogClass, 100 Entity target) { 101 if (PtolemyDialog.class.isAssignableFrom(dialogClass)) { 102 // First see whether the effigy already contains a dialog of 103 // dialogClas on this entity. 104 Iterator dialogs = effigy.entityList(DialogTableau.class) 105 .iterator(); 106 107 while (dialogs.hasNext()) { 108 DialogTableau dialogTableau = (DialogTableau) dialogs.next(); 109 PtolemyDialog existingDialog = (PtolemyDialog) dialogTableau 110 .getFrame(); 111 112 if (existingDialog != null 113 && existingDialog.getClass() == dialogClass 114 && dialogTableau.hasTarget(target)) { 115 return dialogTableau; 116 } 117 } 118 119 // Now, do the same test on the container of the effigy. 120 NamedObj container = effigy.getContainer(); 121 122 if (container != null && container instanceof PtolemyEffigy) { 123 dialogs = ((PtolemyEffigy) container) 124 .entityList(DialogTableau.class).iterator(); 125 126 while (dialogs.hasNext()) { 127 DialogTableau dialogTableau = (DialogTableau) dialogs 128 .next(); 129 PtolemyDialog existingDialog = (PtolemyDialog) dialogTableau 130 .getFrame(); 131 132 if (existingDialog.getClass() == dialogClass 133 && dialogTableau.hasTarget(target)) { 134 return dialogTableau; 135 } 136 } 137 } 138 } 139 140 // A DialogTableau doesn't exist, so create one. 141 DialogTableau newDialogTableau; 142 143 try { 144 newDialogTableau = new DialogTableau(effigy, 145 effigy.uniqueName("dialog")); 146 147 PtolemyDialog dialog = null; 148 Constructor[] constructors = dialogClass.getConstructors(); 149 Constructor constructor = null; 150 151 for (Constructor constructor2 : constructors) { 152 Class[] pType = constructor2.getParameterTypes(); 153 154 if (pType.length == 4 && pType[0] == DialogTableau.class 155 && pType[1] == Frame.class && pType[2] == Entity.class 156 && pType[3] == Configuration.class) { 157 constructor = constructor2; 158 break; 159 } 160 } 161 162 if (constructor != null) { 163 Object[] args = new Object[4]; 164 args[0] = newDialogTableau; 165 args[1] = parent; 166 args[2] = target; 167 args[3] = configuration; 168 dialog = (PtolemyDialog) constructor.newInstance(args); 169 } 170 171 if (dialog == null) { 172 throw new KernelException(target, null, 173 "Can't create a " + dialogClass); 174 } 175 176 newDialogTableau.setFrame(dialog); 177 return newDialogTableau; 178 } catch (Throwable throwable) { 179 MessageHandler.error("Failed to create a DialogTableau for " 180 + target.getFullName(), throwable); 181 } 182 183 return null; 184 } 185 186 /** Get the target associated with this DialogTableau. Actually, the target 187 * is associated with the frame that is associated with this DialogTableau. 188 * @return target The Entity that this DialogTableau is associated with. 189 */ 190 public Entity getTarget() { 191 JFrame dialogJFrame = getFrame(); 192 193 if (dialogJFrame instanceof PtolemyDialog) { 194 PtolemyDialog dialog = (PtolemyDialog) dialogJFrame; 195 return dialog.getTarget(); 196 } 197 198 return null; 199 } 200 201 /** Determines if a particular Entity is associated with this 202 * DialogTableau. 203 * @param entity Entity that test is performed on., 204 * @return true/false True if entity is associated with this DialogTableau. 205 */ 206 public boolean hasTarget(Entity entity) { 207 Entity target = getTarget(); 208 209 if (target != null && target == entity) { 210 return true; 211 } 212 213 return false; 214 } 215}