1 19 package org.netbeans.modules.xml.wsdl.ui.view.grapheditor.widget; 20 21 import java.awt.BasicStroke ; 22 import java.awt.Color ; 23 import java.awt.Dimension ; 24 import java.awt.Graphics2D ; 25 import java.awt.Image ; 26 import java.awt.Insets ; 27 import java.awt.Paint ; 28 import java.awt.Point ; 29 import java.awt.Rectangle ; 30 import java.awt.RenderingHints ; 31 import java.awt.Stroke ; 32 import java.awt.datatransfer.DataFlavor ; 33 import java.awt.datatransfer.Transferable ; 34 import java.awt.event.ActionEvent ; 35 import java.awt.event.ActionListener ; 36 import java.util.ArrayList ; 37 import java.util.Collection ; 38 import java.util.LinkedList ; 39 import java.util.List ; 40 41 import javax.swing.Action ; 42 import javax.swing.JPopupMenu ; 43 import javax.swing.SwingUtilities ; 44 45 import org.netbeans.api.visual.action.ActionFactory; 46 import org.netbeans.api.visual.action.PopupMenuProvider; 47 import org.netbeans.api.visual.action.WidgetAction.WidgetDropTargetDragEvent; 48 import org.netbeans.api.visual.action.WidgetAction.WidgetDropTargetDropEvent; 49 import org.netbeans.api.visual.border.Border; 50 import org.netbeans.api.visual.layout.LayoutFactory; 51 import org.netbeans.api.visual.layout.LayoutFactory.SerialAlignment; 52 import org.netbeans.api.visual.widget.LabelWidget; 53 import org.netbeans.api.visual.widget.Scene; 54 import org.netbeans.api.visual.widget.Widget; 55 import org.netbeans.modules.xml.wsdl.model.Definitions; 56 import org.netbeans.modules.xml.wsdl.model.Message; 57 import org.netbeans.modules.xml.wsdl.model.Part; 58 import org.netbeans.modules.xml.wsdl.model.WSDLModel; 59 import org.netbeans.modules.xml.wsdl.ui.actions.ActionHelper; 60 import org.netbeans.modules.xml.wsdl.ui.netbeans.module.Utility; 61 import org.netbeans.modules.xml.wsdl.ui.view.grapheditor.border.FilledBorder; 62 import org.netbeans.modules.xml.wsdl.ui.view.grapheditor.layout.LeftRightLayout; 63 import org.netbeans.modules.xml.wsdl.ui.view.treeeditor.MessageFolderNode; 64 import org.openide.nodes.Node; 65 import org.openide.util.Lookup; 66 import org.openide.util.NbBundle; 67 import org.openide.util.Utilities; 68 import org.openide.windows.TopComponent; 69 70 73 public class MessagesWidget extends Widget implements 74 ActionListener , ExpandableWidget, DnDHandler, PopupMenuProvider { 75 76 private WSDLModel model; 77 private Widget headerLabel; 78 private Widget headerWidget; 79 private ExpanderWidget expanderWidget; 80 private ButtonWidget addMessageButton; 81 private ButtonWidget removeMessageButton; 82 private Widget buttons; 83 84 private Widget contentWidget; 85 86 private MessageHitPointWidget messageHitPoint; 87 private int messageHitPointIndex = -1; 88 89 private StubWidget stubWidget; 90 91 private Node componentNode; 92 93 public MessagesWidget(Scene scene, WSDLModel model) { 94 super(scene); 95 this.model = model; 96 97 setLayout(LayoutFactory.createVerticalLayout(SerialAlignment.JUSTIFY, 8)); 98 setOpaque(true); 99 setBorder(MAIN_BORDER); 100 101 stubWidget = new StubWidget(scene, NbBundle.getMessage( 102 MessagesWidget.class, 103 "LBL_MessagesWidget_ThereAreNoMessages")); 104 105 addMessageButton = new ButtonWidget(scene, NbBundle.getMessage( 106 MessagesWidget.class, 107 "LBL_MessagesWidget_AddMessage")); addMessageButton.setActionListener(this); 109 110 removeMessageButton = new ButtonWidget(scene, NbBundle.getMessage( 111 MessagesWidget.class, 112 "LBL_MessagesWidget_RemoveMessage")); removeMessageButton.setActionListener(this); 114 115 boolean expanded = ExpanderWidget.isExpanded(this, true); 116 expanderWidget = new ExpanderWidget(scene, this, expanded); 117 118 buttons = new Widget(scene); 119 buttons.setLayout(LayoutFactory.createHorizontalLayout( 120 LayoutFactory.SerialAlignment.JUSTIFY, 8)); 121 buttons.addChild(addMessageButton); 122 buttons.addChild(removeMessageButton); 123 buttons.addChild(expanderWidget); 124 125 headerWidget = new HeaderWidget(scene, expanderWidget); 126 headerWidget.setMinimumSize(new Dimension ( 127 WidgetConstants.MINIMUM_WIDTH, 0)); 128 headerWidget.setLayout(new LeftRightLayout(32)); 129 addChild(headerWidget); 130 headerWidget.addChild(buttons); 131 132 messageHitPoint = new MessageHitPointWidget(scene); 133 134 contentWidget = new Widget(scene); 135 contentWidget.setLayout(LayoutFactory.createVerticalLayout( 136 SerialAlignment.JUSTIFY, 8)); 137 if (expanded) { 138 addChild(contentWidget); 139 } 140 141 getActions().addAction(((PartnerScene) scene).getDnDAction()); 142 getActions().addAction(ActionFactory.createPopupMenuAction(this)); 143 createContent(); 144 } 145 146 private void createContent() { 147 Collection <Message> messages = model.getDefinitions().getMessages(); 148 149 if (stubWidget.getParentWidget() != null) { 150 stubWidget.getParentWidget().removeChild(stubWidget); 151 } 152 153 if (messages == null) { 154 messages = new LinkedList <Message>(); 155 } 156 157 Scene scene = getScene(); 158 headerLabel = new ImageLabelWidget(scene, IMAGE, NbBundle.getMessage( 159 MessagesWidget.class, "LBL_MessagesWidget_Messages"), 160 "(" + messages.size() + ")"); 161 headerWidget.addChild(0, headerLabel); 162 163 WidgetFactory factory = WidgetFactory.getInstance(); 164 165 if (messages.isEmpty()) { 166 contentWidget.addChild(stubWidget); 167 } else { 168 for (Message message : messages) { 169 Widget widget = factory.createWidget(scene, message, true); 170 contentWidget.addChild(widget); 171 } 172 } 173 174 updateButtonsState(); 175 } 176 177 178 public void updateContent() { 179 headerWidget.removeChild(headerLabel); 180 contentWidget.removeChildren(); 181 createContent(); 182 } 183 184 185 public void actionPerformed(ActionEvent event) { 186 if (event.getSource() == addMessageButton) { 187 Message message = null; 188 try { 189 if (model.startTransaction()) { 190 message = model.getFactory().createMessage(); 191 message.setName(MessagesUtils.createNewMessageName(model)); 192 193 Part newPart = model.getFactory().createPart(); 194 newPart.setName(MessagesUtils.createNewPartName(message)); 195 198 message.addPart(newPart); 199 200 copyView(null, message); 201 202 model.getDefinitions().addMessage(message); 203 } 204 } finally { 205 model.endTransaction(); 206 } 207 if (message != null) { 208 ActionHelper.selectNode(message); 209 } 210 } else if (event.getSource() == removeMessageButton) { 211 for (MessageWidget messageWidget : getMessageWidgets()) { 212 if (messageWidget.getState().isSelected()) { 213 Message message = messageWidget.getWSDLComponent(); 214 try { 215 if (model.startTransaction()) { 216 model.getDefinitions().removeMessage(message); 217 } 218 } finally { 219 model.endTransaction(); 220 } 221 break; 222 } 223 } 224 } 225 } 226 227 228 public void updateButtonsState() { 229 boolean enabled = false; 230 231 if (contentWidget != null && contentWidget.getChildren() != null) { 232 for (Widget w : contentWidget.getChildren()) { 233 if (w instanceof MessageWidget) { 234 enabled |= w.getState().isSelected(); 235 } 236 } 237 } 238 239 if (enabled != removeMessageButton.isButtonEnabled()) { 240 removeMessageButton.setButtonEnabled(enabled); 241 } 242 } 243 244 245 public void collapseWidget(ExpanderWidget expander) { 246 if (contentWidget.getParentWidget() != null) 247 removeChild(contentWidget); 248 } 249 250 public void expandWidget(ExpanderWidget expander) { 251 if (contentWidget.getParentWidget() == null) 252 addChild(contentWidget); 253 } 254 255 256 public void dragExit() { 257 hideHitPoint(); 258 } 259 260 261 public boolean dragOver(Point scenePoint, WidgetDropTargetDragEvent event) { 262 if (isCollapsed()) return false; 263 264 try { 265 Transferable t = event.getTransferable(); 266 if (t != null) { 267 for (DataFlavor flavor : t.getTransferDataFlavors()) { 268 Class repClass = flavor.getRepresentationClass(); 269 if (Node.class.isAssignableFrom(repClass)) { 270 Node node = (Node) t.getTransferData(flavor); 271 if ("Message".equals(node.getName())) { showHitPoint(scenePoint); 273 return true; 274 } 275 } 276 } 277 } 278 } catch (Exception ex) { 279 } 281 282 return false; 283 } 284 285 286 private boolean hasMessages() { 287 Collection <Message> messages = model.getDefinitions().getMessages(); 288 if (messages == null) return false; 289 return !messages.isEmpty(); 290 } 291 292 293 public boolean drop(Point scenePoint, WidgetDropTargetDropEvent event) { 294 if (isCollapsed()) return false; 295 296 int index = messageHitPointIndex; 297 298 hideHitPoint(); 299 300 if (index >= 0) { 301 try { 302 if (model.startTransaction()) { 303 Message[] messages = model.getDefinitions().getMessages() 304 .toArray(new Message[0]); 305 306 Message newMessage = model.getFactory().createMessage(); 307 newMessage.setName(MessagesUtils.createNewMessageName(model)); 308 Part newPart = model.getFactory().createPart(); 309 newPart.setName(MessagesUtils.createNewPartName(newMessage)); 310 newMessage.addPart(newPart); 313 314 copyView(null, newMessage); 315 if (index == messages.length) { 316 model.getDefinitions().addMessage(newMessage); 317 } else { 318 Utility.insertIntoDefinitionsAtIndex(index, model, newMessage, Definitions.MESSAGE_PROPERTY); 319 } 320 } 321 } finally { 322 model.endTransaction(); 323 } 324 325 return true; 326 } 327 328 return false; 329 } 330 331 332 private void copyView(Message oldMessage, Message newMessage) { 333 MessageWidget newWidget = (MessageWidget) WidgetFactory.getInstance() 334 .createWidget(getScene(), newMessage); 335 336 MessageWidget oldWidget = null; 337 338 if (oldMessage != null) { 339 oldWidget = (MessageWidget) ((PartnerScene) getScene()) 340 .findWidget(oldMessage); 341 } 342 343 if (oldWidget == null || !oldWidget.isCollapsed()) { 344 newWidget.expandForDragAndDrop(); 345 } 346 347 } 351 352 353 public boolean isCollapsed() { 354 return contentWidget.getParentWidget() == null; 355 } 356 357 public void expandForDragAndDrop() { 358 expanderWidget.setExpanded(true); 359 } 360 361 362 private void hideHitPoint() { 363 if (messageHitPoint.getParentWidget() != null) { 364 messageHitPoint.getParentWidget() 365 .removeChild(messageHitPoint); 366 } 367 368 if (!hasMessages() && stubWidget.getParentWidget() == null) { 369 contentWidget.addChild(stubWidget); 370 } 371 372 messageHitPointIndex = -1; 373 } 374 375 376 private void showHitPoint(Point scenePoint) { 377 if (contentWidget.getParentWidget() == null) return; 378 379 int index = placeHolderIndex(scenePoint); 380 381 if (index < 0) return; 382 383 messageHitPointIndex = index; 384 385 if (messageHitPoint.getParentWidget() != null) { 386 messageHitPoint.getParentWidget().removeChild(messageHitPoint); 387 } 388 389 if (stubWidget.getParentWidget() != null) { 390 stubWidget.getParentWidget().removeChild(stubWidget); 391 } 392 393 contentWidget.addChild(messageHitPointIndex, messageHitPoint); 394 } 395 396 397 private MessageWidget[] getMessageWidgets() { 398 List <MessageWidget> result = new ArrayList <MessageWidget>(); 399 400 for (Widget widget : contentWidget.getChildren()) { 401 if (widget instanceof MessageWidget) { 402 result.add((MessageWidget) widget); 403 } 404 } 405 406 return result.toArray(new MessageWidget[result.size()]); 407 } 408 409 410 private int placeHolderIndex(Point scenePoint) { 411 MessageWidget[] messageWidgets = getMessageWidgets(); 412 413 if (messageWidgets == null) return -1; 414 415 int index = 0; 416 417 if (messageHitPoint.getParentWidget() != null) { 418 if (messageHitPoint.isHitAt(messageHitPoint.convertSceneToLocal(scenePoint))) { 419 return -1; 420 } 421 } 422 423 for (int i = 0; i < messageWidgets.length; i++) { 424 MessageWidget messageWidget = messageWidgets[i]; 425 Point partPoint = messageWidget.convertSceneToLocal(scenePoint); 426 Rectangle partBounds = messageWidget.getBounds(); 427 428 if (partPoint.y < partBounds.getCenterY()) { 429 return i; 430 } 431 } 432 433 return messageWidgets.length; 434 } 435 436 public Object hashKey() { 437 return model.getDefinitions().getName(); 438 } 439 440 446 protected TopComponent findTopComponent() { 447 return (TopComponent) SwingUtilities.getAncestorOfClass( 448 TopComponent.class, getScene().getView()); 449 } 450 451 456 private synchronized Node getNode() { 457 if (componentNode == null) { 458 componentNode = new MessageFolderNode(model.getDefinitions()); 459 componentNode = new WidgetFilterNode(componentNode); 460 } 461 return componentNode; 462 } 463 464 public JPopupMenu getPopupMenu(Widget widget, Point point) { 465 Node node = getNode(); 466 if (node != null) { 467 TopComponent tc = findTopComponent(); 470 Lookup lookup; 471 if (tc != null) { 472 tc.setActivatedNodes(new Node[] { node }); 474 lookup = tc.getLookup(); 477 } else { 478 lookup = Lookup.EMPTY; 479 } 480 Action [] actions = node.getActions(true); 482 return Utilities.actionsToPopup(actions, lookup); 483 } 484 return null; 485 } 486 487 public static final Border MAIN_BORDER = new FilledBorder(1, 1, 8, 8, 488 new Color (0x888888), Color.WHITE); 489 490 491 private static final Image IMAGE = Utilities.loadImage 492 ("org/netbeans/modules/xml/wsdl/ui/view/resources/message.png"); 494 495 private static class MessageHitPointWidget extends LabelWidget { 496 public MessageHitPointWidget(Scene scene) { 497 super(scene, " "); 498 setFont(scene.getDefaultFont()); 499 setBorder(new MessageHitPointBorder()); 500 } 501 } 502 503 504 private static class MessageHitPointBorder implements Border { 505 public Insets getInsets() { 506 return new Insets (8, 8, 8, 8); 507 } 508 509 510 public void paint(Graphics2D g2, Rectangle rectangle) { 511 Paint oldPaint = g2.getPaint(); 512 Stroke oldStroke = g2.getStroke(); 513 514 Object oldStrokeControl = g2.getRenderingHint( 515 RenderingHints.KEY_STROKE_CONTROL); 516 517 g2.setPaint(Color.WHITE); 518 g2.fill(rectangle); 519 520 g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, 521 RenderingHints.VALUE_STROKE_PURE); 522 g2.setPaint(WidgetConstants.HIT_POINT_BORDER); 523 g2.setStroke(new BasicStroke (2)); 524 g2.drawRoundRect(rectangle.x + 1, rectangle.y + 1, 525 rectangle.width - 2, rectangle.height - 2, 6, 6); 526 527 g2.setPaint(oldPaint); 528 g2.setStroke(oldStroke); 529 g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, 530 oldStrokeControl); 531 } 532 533 534 public boolean isOpaque() { 535 return true; 536 } 537 } 538 } 539 | Popular Tags |