annotate java/src/uk/ac/qmul/eecs/ccmi/gui/CCmIPopupMenu.java @ 1:e3935c01cde2 tip

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