annotate java/src/uk/ac/qmul/eecs/ccmi/gui/CCmIPopupMenu.java @ 8:ea7885bd9bff tip

fixed bug : render solid line as dotted/dashed when moving the stylus from dotted/dashed to solid
author ccmi-guest
date Thu, 03 Jul 2014 16:12:20 +0100
parents d66dd5880081
children
rev   line source
fiore@3 1 /*
fiore@3 2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
fiore@3 3
fiore@3 4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
fiore@3 5
fiore@3 6 This program is free software: you can redistribute it and/or modify
fiore@3 7 it under the terms of the GNU General Public License as published by
fiore@3 8 the Free Software Foundation, either version 3 of the License, or
fiore@3 9 (at your option) any later version.
fiore@3 10
fiore@3 11 This program is distributed in the hope that it will be useful,
fiore@3 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
fiore@3 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fiore@3 14 GNU General Public License for more details.
fiore@3 15
fiore@3 16 You should have received a copy of the GNU General Public License
fiore@3 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
fiore@3 18 */
fiore@3 19 package uk.ac.qmul.eecs.ccmi.gui;
fiore@3 20
fiore@3 21 import java.awt.Component;
fiore@3 22 import java.awt.event.ActionEvent;
fiore@3 23 import java.awt.event.ActionListener;
fiore@3 24 import java.text.MessageFormat;
fiore@3 25 import java.util.ArrayList;
fiore@3 26 import java.util.Collections;
fiore@3 27 import java.util.Comparator;
fiore@3 28 import java.util.Iterator;
fiore@3 29 import java.util.List;
fiore@3 30 import java.util.ResourceBundle;
fiore@3 31 import java.util.Set;
fiore@3 32
fiore@3 33 import javax.swing.JMenuItem;
fiore@3 34 import javax.swing.JOptionPane;
fiore@3 35 import javax.swing.JPopupMenu;
fiore@3 36
fiore@3 37 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramElement;
fiore@3 38 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties;
fiore@3 39 import uk.ac.qmul.eecs.ccmi.network.AwarenessMessage;
fiore@3 40 import uk.ac.qmul.eecs.ccmi.network.Command;
fiore@3 41 import uk.ac.qmul.eecs.ccmi.network.DiagramEventActionSource;
fiore@3 42 import uk.ac.qmul.eecs.ccmi.utils.InteractionLog;
fiore@3 43
fiore@3 44 /**
fiore@3 45 * This class provides the two menus to handle nodes and edges on the visual graph. This class
fiore@3 46 * provides an abstract implementation common to both the node and edge menus. The specific
fiore@3 47 * implementations are internal static classes, inheriting from this class.
fiore@3 48 *
fiore@3 49 */
fiore@3 50 @SuppressWarnings("serial")
fiore@3 51 public abstract class CCmIPopupMenu extends JPopupMenu {
fiore@3 52 /**
fiore@3 53 * This constructor is called by subclasses constructor.
fiore@3 54 *
fiore@3 55 * @param reference the element this menu refers to (it popped up by right-clicking on it)
fiore@3 56 * @param parentComponent the component where the menu is going to be displayed
fiore@3 57 * @param modelUpdater the model updater to make changed to {@code reference}
fiore@3 58 * @param selectedElements other elements eventually selected on the graph, which are going
fiore@3 59 * to undergo the same changes as {@code reference}, being selected together with it.
fiore@3 60 */
fiore@3 61 protected CCmIPopupMenu(DiagramElement reference,
fiore@3 62 Component parentComponent, DiagramModelUpdater modelUpdater,
fiore@3 63 Set<DiagramElement> selectedElements) {
fiore@3 64 super();
fiore@3 65 this.modelUpdater = modelUpdater;
fiore@3 66 this.parentComponent = parentComponent;
fiore@3 67 this.reference = reference;
fiore@3 68 this.selectedElements = selectedElements;
fiore@3 69 }
fiore@3 70
fiore@3 71 /**
fiore@3 72 * Returns the the element this menu refers to.
fiore@3 73 * @return the element this menu refers to.
fiore@3 74 */
fiore@3 75 public DiagramElement getElement(){
fiore@3 76 return reference;
fiore@3 77 }
fiore@3 78
fiore@3 79 /**
fiore@3 80 * Add the a menu item to this menu. A menu item, once clicked on, will prompt the user for a new name
fiore@3 81 * for the referee element and will execute the update through the modelUpdater passed as argument
fiore@3 82 * to the constructor.
fiore@3 83 */
fiore@3 84 protected void addNameMenuItem() {
fiore@3 85 /* add set name menu item */
fiore@3 86 JMenuItem setNameMenuItem = new JMenuItem(
fiore@3 87 resources.getString("menu.set_name"));
fiore@3 88 setNameMenuItem.addActionListener(new ActionListener() {
fiore@3 89 @Override
fiore@3 90 public void actionPerformed(ActionEvent e) {
fiore@3 91 String type = (reference instanceof Node) ? "node" : "edge";
fiore@3 92 if (!modelUpdater.getLock(reference, Lock.NAME,
fiore@3 93 new DiagramEventActionSource(DiagramEventSource.GRPH,
fiore@3 94 Command.Name.SET_NODE_NAME, reference.getId(),reference.getName()))) {
fiore@3 95 iLog("Could not get the lock on " + type + " for renaming",
fiore@3 96 DiagramElement.toLogString(reference));
fiore@3 97 JOptionPane.showMessageDialog(parentComponent,
fiore@3 98 MessageFormat.format(resources
fiore@3 99 .getString("dialog.lock_failure.name"),
fiore@3 100 type));
fiore@3 101 return;
fiore@3 102 }
fiore@3 103 iLog("open rename " + type + " dialog",
fiore@3 104 DiagramElement.toLogString(reference));
fiore@3 105 String name = JOptionPane.showInputDialog(parentComponent,
fiore@3 106 MessageFormat.format(
fiore@3 107 resources.getString("dialog.input.name"),
fiore@3 108 reference.getName()), reference.getName());
fiore@3 109 if (name == null)
fiore@3 110 iLog("cancel rename " + type + " dialog",
fiore@3 111 DiagramElement.toLogString(reference));
fiore@3 112 else
fiore@3 113 /* node has been locked at selection time */
fiore@3 114 modelUpdater.setName(reference, name.trim(),
fiore@3 115 DiagramEventSource.GRPH);
fiore@3 116 modelUpdater.yieldLock(reference, Lock.NAME,
fiore@3 117 new DiagramEventActionSource(DiagramEventSource.GRPH,
fiore@3 118 Command.Name.SET_NODE_NAME, reference.getId(),reference.getName()));
fiore@3 119 }
fiore@3 120
fiore@3 121 });
fiore@3 122 add(setNameMenuItem);
fiore@3 123 }
fiore@3 124
fiore@3 125 /**
fiore@3 126 * Add the a delete item to this menu. A menu item, once clicked on, will prompt the user for a confirmation
fiore@3 127 * for the deletion of referee element and will execute the update through the modelUpdater passed as argument
fiore@3 128 * to the constructor.
fiore@3 129 */
fiore@3 130 protected void addDeleteMenuItem() {
fiore@3 131 JMenuItem deleteMenuItem = new JMenuItem(resources.getString("menu.delete"));
fiore@3 132 deleteMenuItem.addActionListener(new ActionListener() {
fiore@3 133 @Override
fiore@3 134 public void actionPerformed(ActionEvent evt) {
fiore@3 135 /* create a new Set to maintain iterator consistency as elementTakenOut will change selectedItems */
fiore@3 136 List<DiagramElement> workList = new ArrayList<DiagramElement>(selectedElements);
fiore@3 137 /* right click on an element with no selection involved */
fiore@3 138 if(workList.isEmpty()){
fiore@3 139 workList.add(reference);
fiore@3 140 /* right click on an element with other elements selected, thus we ignore the *
fiore@3 141 * currently selected elements and try to delete only the right clicked one. */
fiore@3 142 }else if(!workList.contains(reference)){
fiore@3 143 workList.clear();
fiore@3 144 workList.add(reference);
fiore@3 145 }else{
fiore@3 146 /* If the right clicked element selected together with other elements, try to *
fiore@3 147 * delete them all. First delete all edges and then all nodes to keep consistency. *
fiore@3 148 * We are deleting a bunch of objects and if a node is deleted before an edge *
fiore@3 149 * attached to it, then an exception will be triggered at the moment of edge *
fiore@3 150 * deletion because the edge will be already deleted as a result of the node deletion */
fiore@3 151 Collections.sort(workList, new Comparator<DiagramElement>(){
fiore@3 152 @Override
fiore@3 153 public int compare(DiagramElement e1,DiagramElement e2) {
fiore@3 154 boolean e1isEdge = e1 instanceof Edge;
fiore@3 155 boolean e2isEdge = e2 instanceof Edge;
fiore@3 156 if(e1isEdge && !e2isEdge){
fiore@3 157 return -1;
fiore@3 158 }
fiore@3 159 if(!e1isEdge && e2isEdge){
fiore@3 160 return 1;
fiore@3 161 }
fiore@3 162 return 0;
fiore@3 163 }
fiore@3 164 });
fiore@3 165 }
fiore@3 166
fiore@3 167 List<DiagramElement>alreadyLockedElements = new ArrayList<DiagramElement>(workList.size());
fiore@3 168 /* check which, of the selected elements, can be deleted and which ones are currently held by *
fiore@3 169 * other clients. If an element is locked it's removed from the list and put into a separated set */
fiore@3 170 for(Iterator<DiagramElement> itr=workList.iterator(); itr.hasNext();){
fiore@3 171 DiagramElement selected = itr.next();
fiore@3 172 boolean isNode = selected instanceof Node;
fiore@3 173 if(!modelUpdater.getLock(selected,
fiore@3 174 Lock.DELETE,
fiore@3 175 new DiagramEventActionSource(
fiore@3 176 DiagramEventSource.GRPH,
fiore@3 177 isNode ? Command.Name.REMOVE_NODE : Command.Name.REMOVE_EDGE,
fiore@3 178 selected.getId(),selected.getName()))){
fiore@3 179 itr.remove();
fiore@3 180 alreadyLockedElements.add(selected);
fiore@3 181 }
fiore@3 182 }
fiore@3 183
fiore@3 184 /* all the elements are locked by other clients */
fiore@3 185 if(workList.isEmpty()){
fiore@3 186 iLog("Could not get lock on any selected element for deletion","");
fiore@3 187 JOptionPane.showMessageDialog(
fiore@3 188 JOptionPane.getFrameForComponent(parentComponent),
fiore@3 189 alreadyLockedElements.size() == 1 ? // singular vs plural
fiore@3 190 resources.getString("dialog.lock_failure.delete") :
fiore@3 191 resources.getString("dialog.lock_failure.deletes"));
fiore@3 192 return;
fiore@3 193 }
fiore@3 194
fiore@3 195 String warning = "";
fiore@3 196 if(!alreadyLockedElements.isEmpty()){
fiore@3 197 StringBuilder builder = new StringBuilder(resources.getString("dialog.lock_failure.deletes_warning"));
fiore@3 198 for(DiagramElement alreadyLocked : alreadyLockedElements)
fiore@3 199 builder.append(alreadyLocked.getName()).append(' ');
fiore@3 200 warning = builder.append('\n').toString();
fiore@3 201 iLog("Could not get lock on some selected element for deletion",warning);
fiore@3 202 }
fiore@3 203
fiore@3 204 iLog("open delete dialog",warning);
fiore@3 205 int answer = JOptionPane.showConfirmDialog(
fiore@3 206 JOptionPane.getFrameForComponent(parentComponent),
fiore@3 207 warning+resources.getString("dialog.confirm.deletions"),
fiore@3 208 resources.getString("dialog.confirm.title"),
fiore@3 209 SpeechOptionPane.YES_NO_OPTION);
fiore@3 210 if(answer == JOptionPane.YES_OPTION){
fiore@3 211 /* the user chose to delete the elements, proceed (locks *
fiore@3 212 * will be automatically removed upon deletion by the server ) */
fiore@3 213 for(DiagramElement selected : workList){
fiore@3 214 modelUpdater.takeOutFromCollection(selected,DiagramEventSource.GRPH);
fiore@3 215 modelUpdater.sendAwarenessMessage(
fiore@3 216 AwarenessMessage.Name.STOP_A,
fiore@3 217 new DiagramEventActionSource(DiagramEventSource.TREE,
fiore@3 218 (selected instanceof Node) ? Command.Name.REMOVE_NODE : Command.Name.REMOVE_EDGE,
fiore@3 219 selected.getId(),selected.getName())
fiore@3 220 );
fiore@3 221 }
fiore@3 222 }else{
fiore@3 223 /* the user chose not to delete the elements, release the acquired locks */
fiore@3 224 for(DiagramElement selected : workList){
fiore@3 225 /* if it's a node all its attached edges were locked as well */
fiore@3 226 /*if(selected instanceof Node){ DONE IN THE SERVER
fiore@3 227 Node n = (Node)selected;
fiore@3 228 for(int i=0; i<n.getEdgesNum();i++){
fiore@3 229 modelUpdater.yieldLock(n.getEdgeAt(i), Lock.DELETE);
fiore@3 230 }}*/
fiore@3 231 boolean isNode = selected instanceof Node;
fiore@3 232 modelUpdater.yieldLock(selected,
fiore@3 233 Lock.DELETE,
fiore@3 234 new DiagramEventActionSource(
fiore@3 235 DiagramEventSource.GRPH,
fiore@3 236 isNode ? Command.Name.REMOVE_NODE : Command.Name.REMOVE_EDGE,
fiore@3 237 selected.getId(),selected.getName()));
fiore@3 238 }
fiore@3 239 iLog("cancel delete node dialog","");
fiore@3 240 }
fiore@3 241 }
fiore@3 242 });
fiore@3 243 add(deleteMenuItem);
fiore@3 244 }
fiore@3 245
fiore@3 246 /**
fiore@3 247 * Performs the log in the InteractionLog.
fiore@3 248 * @param action the action to log.
fiore@3 249 * @param args additional arguments to add to the log.
fiore@3 250 *
fiore@5 251 * @see uk.ac.qmul.eecs.ccmi.utils.InteractionLog
fiore@3 252 */
fiore@3 253 protected void iLog(String action, String args) {
fiore@3 254 InteractionLog.log("GRAPH", action, args);
fiore@3 255 }
fiore@3 256
fiore@3 257 /**
fiore@3 258 *
fiore@3 259 * A popup menu to perform changes (e.g. delete, rename etc.) to a node from the visual graph.
fiore@3 260 *
fiore@3 261 */
fiore@3 262 public static class NodePopupMenu extends CCmIPopupMenu {
fiore@3 263 /**
fiore@3 264 *
fiore@3 265 * @param node the node this menu refers to.
fiore@3 266 * @param parentComponent the component where the menu is going to be displayed.
fiore@3 267 * @param modelUpdater the model updater used to make changed to {@code node}.
fiore@3 268 * @param selectedElements other elements eventually selected on the graph, which are going
fiore@3 269 * to undergo the same changes as {@code node}, being selected together with it.
fiore@3 270 */
fiore@3 271 NodePopupMenu(Node node, Component parentComponent,
fiore@3 272 DiagramModelUpdater modelUpdater,
fiore@3 273 Set<DiagramElement> selectedElements) {
fiore@3 274 super(node, parentComponent, modelUpdater, selectedElements);
fiore@3 275 addNameMenuItem();
fiore@3 276 addPropertyMenuItem();
fiore@3 277 addDeleteMenuItem();
fiore@3 278 }
fiore@3 279
fiore@3 280 private void addPropertyMenuItem() {
fiore@3 281 final Node nodeRef = (Node) reference;
fiore@3 282 /* if the node has no properties defined, then don't add the menu item */
fiore@3 283 if(nodeRef.getProperties().isNull())
fiore@3 284 return;
fiore@3 285 /* add set property menu item*/
fiore@3 286 JMenuItem setPropertiesMenuItem = new JMenuItem(resources.getString("menu.set_properties"));
fiore@3 287 setPropertiesMenuItem.addActionListener(new ActionListener(){
fiore@3 288 @Override
fiore@3 289 public void actionPerformed(ActionEvent e) {
fiore@3 290 if(!modelUpdater.getLock(nodeRef, Lock.PROPERTIES, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_PROPERTIES,nodeRef.getId(),reference.getName()))){
fiore@3 291 iLog("Could not get the lock on node for properties",DiagramElement.toLogString(nodeRef));
fiore@3 292 JOptionPane.showMessageDialog(parentComponent, resources.getString("dialog.lock_failure.properties"));
fiore@3 293 return;
fiore@3 294 }
fiore@3 295 iLog("open edit properties dialog",DiagramElement.toLogString(nodeRef));
fiore@3 296 NodeProperties properties = PropertyEditorDialog.showDialog(JOptionPane.getFrameForComponent(parentComponent),nodeRef.getPropertiesCopy());
fiore@3 297 if(properties == null){ // user clicked on cancel
fiore@3 298 iLog("cancel edit properties dialog",DiagramElement.toLogString(nodeRef));
fiore@3 299 modelUpdater.yieldLock(nodeRef, Lock.PROPERTIES, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_PROPERTIES,nodeRef.getId(),reference.getName()));
fiore@3 300 return;
fiore@3 301 }
fiore@3 302 if(!properties.isNull())
fiore@3 303 modelUpdater.setProperties(nodeRef,properties,DiagramEventSource.GRPH);
fiore@3 304 modelUpdater.yieldLock(nodeRef, Lock.PROPERTIES,new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_PROPERTIES,nodeRef.getId(),reference.getName()));
fiore@3 305 }
fiore@3 306 });
fiore@3 307 add(setPropertiesMenuItem);
fiore@3 308 }
fiore@3 309 }
fiore@3 310
fiore@3 311 /**
fiore@3 312 * A popup menu to perform changes (e.g. delete, rename etc.) to a edge from the visual graph.
fiore@3 313 */
fiore@3 314 public static class EdgePopupMenu extends CCmIPopupMenu {
fiore@3 315 /**
fiore@3 316 * Constructs an {@code EdgePopupMenu} to perform changes to an edge from the visual diagram.
fiore@3 317 * This constructor is normally called when the user clicks in the neighbourhood of a node
fiore@3 318 * connected to this edge. the menu will then include items to change an end label or
fiore@3 319 * an arrow head.
fiore@3 320 * @param edge the edge this menu refers to.
fiore@3 321 * @param node one attached node some menu item will refer to.
fiore@3 322 * @param parentComponent the component where the menu is going to be displayed.
fiore@3 323 * @param modelUpdater the model updater used to make changed to {@code edge}.
fiore@3 324 * @param selectedElements other elements eventually selected on the graph, which are going
fiore@3 325 * to undergo the same changes as {@code edge}, being selected together with it.
fiore@3 326 */
fiore@3 327 public EdgePopupMenu( Edge edge, Node node, Component parentComponent, DiagramModelUpdater modelUpdater,
fiore@3 328 Set<DiagramElement> selectedElements){
fiore@3 329 super(edge,parentComponent,modelUpdater,selectedElements);
fiore@3 330 addNameMenuItem();
fiore@3 331 if(node != null){
fiore@3 332 nodeRef = node;
fiore@3 333 Object[] arrowHeads = new Object[edge.getAvailableEndDescriptions().length + 1];
fiore@3 334 for(int i=0;i<edge.getAvailableEndDescriptions().length;i++){
fiore@3 335 arrowHeads[i] = edge.getAvailableEndDescriptions()[i].toString();
fiore@3 336 }
fiore@3 337 arrowHeads[arrowHeads.length-1] = Edge.NO_ENDDESCRIPTION_STRING;
fiore@3 338 addEndMenuItems(arrowHeads);
fiore@3 339 }
fiore@3 340 addDeleteMenuItem();
fiore@3 341 }
fiore@3 342
fiore@3 343 /**
fiore@3 344 * Constructs an {@code EdgePopupMenu} to perform changes to an edge from the visual diagram.
fiore@3 345 * This constructor is normally called when the user clicks around the midpoint of the edge
fiore@3 346 * @param edge the edge this menu refers to.
fiore@3 347 * @param parentComponent the component where the menu is going to be displayed.
fiore@3 348 * @param modelUpdater the model updater used to make changed to {@code edge}.
fiore@3 349 * @param selectedElements other elements eventually selected on the graph, which are going
fiore@3 350 * to undergo the same changes as {@code edge}, being selected together with it.
fiore@3 351 */
fiore@3 352 public EdgePopupMenu( Edge edge, Component parentComponent, DiagramModelUpdater modelUpdater,
fiore@3 353 Set<DiagramElement> selectedElements){
fiore@3 354 this(edge,null,parentComponent,modelUpdater,selectedElements);
fiore@3 355 }
fiore@3 356
fiore@3 357 private void addEndMenuItems(final Object[] arrowHeads){
fiore@3 358 final Edge edgeRef = (Edge)reference;
fiore@3 359 /* Label menu item */
fiore@3 360 JMenuItem setLabelMenuItem = new JMenuItem(resources.getString("menu.set_label"));
fiore@3 361 setLabelMenuItem.addActionListener(new ActionListener(){
fiore@3 362 @Override
fiore@3 363 public void actionPerformed(ActionEvent evt) {
fiore@3 364 if(!modelUpdater.getLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDLABEL,edgeRef.getId(),reference.getName()))){
fiore@3 365 iLog("Could not get lock on edge for end label",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 366 JOptionPane.showMessageDialog(parentComponent, resources.getString("dialog.lock_failure.end"));
fiore@3 367 return;
fiore@3 368 }
fiore@3 369 iLog("open edge label dialog",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 370 String text = JOptionPane.showInputDialog(parentComponent,resources.getString("dialog.input.label"));
fiore@3 371 if(text != null)
fiore@3 372 modelUpdater.setEndLabel(edgeRef,nodeRef,text,DiagramEventSource.GRPH);
fiore@3 373 else
fiore@3 374 iLog("cancel edge label dialog",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 375 modelUpdater.yieldLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDLABEL,edgeRef.getId(),reference.getName()));
fiore@3 376 }
fiore@3 377 });
fiore@3 378 add(setLabelMenuItem);
fiore@3 379
fiore@3 380 if(arrowHeads.length > 1){
fiore@3 381 /* arrow head menu item */
fiore@3 382 JMenuItem selectArrowHeadMenuItem = new JMenuItem(resources.getString("menu.choose_arrow_head"));
fiore@3 383 selectArrowHeadMenuItem.addActionListener(new ActionListener(){
fiore@3 384 @Override
fiore@3 385 public void actionPerformed(ActionEvent e) {
fiore@3 386 if(!modelUpdater.getLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDDESCRIPTION,edgeRef.getId(),reference.getName()))){
fiore@3 387 iLog("Could not get lock on edge for arrow head",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 388 JOptionPane.showMessageDialog(parentComponent, resources.getString("dialog.lock_failure.end"));
fiore@3 389 return;
fiore@3 390 }
fiore@3 391 iLog("open select arrow head dialog",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 392 String arrowHead = (String)JOptionPane.showInputDialog(
fiore@3 393 parentComponent,
fiore@3 394 resources.getString("dialog.input.arrow"),
fiore@3 395 resources.getString("dialog.input.arrow.title"),
fiore@3 396 JOptionPane.PLAIN_MESSAGE,
fiore@3 397 null,
fiore@3 398 arrowHeads,
fiore@3 399 arrowHeads);
fiore@3 400 if(arrowHead == null){
fiore@3 401 iLog("cancel select arrow head dialog",DiagramElement.toLogString(edgeRef)+" end node:"+DiagramElement.toLogString(nodeRef));
fiore@3 402 modelUpdater.yieldLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDDESCRIPTION,edgeRef.getId(),reference.getName()));
fiore@3 403 return;
fiore@3 404 }
fiore@3 405 for(int i=0; i<edgeRef.getAvailableEndDescriptions().length;i++){
fiore@3 406 if(edgeRef.getAvailableEndDescriptions()[i].toString().equals(arrowHead)){
fiore@3 407 modelUpdater.setEndDescription(edgeRef, nodeRef, i,DiagramEventSource.GRPH);
fiore@3 408 modelUpdater.yieldLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDDESCRIPTION,edgeRef.getId(),reference.getName()));
fiore@3 409 return;
fiore@3 410 }
fiore@3 411 }
fiore@3 412 /* the user selected the none menu item */
fiore@3 413 modelUpdater.setEndDescription(edgeRef,nodeRef, Edge.NO_END_DESCRIPTION_INDEX,DiagramEventSource.GRPH);
fiore@3 414 modelUpdater.yieldLock(edgeRef, Lock.EDGE_END, new DiagramEventActionSource(DiagramEventSource.GRPH,Command.Name.SET_ENDDESCRIPTION,edgeRef.getId(),reference.getName()));
fiore@3 415 }
fiore@3 416 });
fiore@3 417 add(selectArrowHeadMenuItem);
fiore@3 418 }
fiore@3 419 }
fiore@3 420
fiore@3 421 private Node nodeRef;
fiore@3 422 }
fiore@3 423
fiore@3 424 /**
fiore@3 425 * the model updater used to make changed to {@code reference}.
fiore@3 426 */
fiore@3 427 protected DiagramModelUpdater modelUpdater;
fiore@3 428 /**
fiore@3 429 * the component where the menu is going to be displayed.
fiore@3 430 */
fiore@3 431 protected Component parentComponent;
fiore@3 432 /**
fiore@3 433 * the element this menu refers to.
fiore@3 434 */
fiore@3 435 protected DiagramElement reference;
fiore@3 436 /**
fiore@3 437 * other elements eventually selected on the graph, which are going
fiore@3 438 * to undergo the same changes as {@code reference}, being selected together with it.
fiore@3 439 */
fiore@3 440 protected Set<DiagramElement> selectedElements;
fiore@3 441 private static ResourceBundle resources = ResourceBundle.getBundle(CCmIPopupMenu.class.getName());
fiore@3 442 }