1 /**********************************************************************
2 * Copyright (c) 2005, 2008, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 * $Id: GraphNode.java,v 1.3 2008/01/24 02:28:49 apnan Exp $
10 * IBM - Initial API and implementation
11 * Bernd Hufmann - Updated for TMF
12 **********************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Arrays
;
17 import java
.util
.Comparator
;
18 import java
.util
.HashMap
;
19 import java
.util
.Iterator
;
20 import java
.util
.List
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.TmfUiTracer
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IGC
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.ISDPreferences
;
27 * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget.
33 public abstract class GraphNode
{
35 protected int startEventOccurrence
= 0;
37 protected int endEventOccurrence
= 0;
40 * Preference ColorId to use to draw font
42 public String prefId
= ISDPreferences
.PREF_SYNC_MESS
;
45 * The selection state of the graph node.
47 protected boolean selected
= false;
50 * The focus state of the graph node.
52 protected boolean focused
= false;
54 protected boolean hasChilden
= false;
57 * The graph node name used to label the graph node in the View.
59 protected String name
= ""; //$NON-NLS-1$
61 protected HashMap
<String
, List
<GraphNode
>> nodes
;
62 protected HashMap
<String
, List
<GraphNode
>> fnodes
;
63 protected HashMap
<String
, List
<GraphNode
>> bnodes
;
65 protected HashMap
<String
, Integer
> indexes
;
66 protected HashMap
<String
, Boolean
> fSort
;
67 protected HashMap
<String
, Boolean
> bSort
;
70 * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists
73 public void resetIndex() {
76 Iterator
<String
> it
= indexes
.keySet().iterator();
77 while (it
.hasNext()) {
78 String nodeType
= it
.next();
79 indexes
.put(nodeType
, Integer
.valueOf(0));
84 * Add a GraphNode into the receiver
86 * @param nodeToAdd the node to add
88 public void addNode(GraphNode nodeToAdd
) {
90 nodes
= new HashMap
<String
, List
<GraphNode
>>(2);
91 fnodes
= new HashMap
<String
, List
<GraphNode
>>(2);
92 bnodes
= new HashMap
<String
, List
<GraphNode
>>(2);
93 indexes
= new HashMap
<String
, Integer
>(2);
94 bSort
= new HashMap
<String
, Boolean
>(2);
95 fSort
= new HashMap
<String
, Boolean
>(2);
100 if (nodeToAdd
== null)
103 if (nodes
.get(nodeToAdd
.getArrayId()) == null) {
104 nodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
105 indexes
.put(nodeToAdd
.getArrayId(), Integer
.valueOf(0));
106 fnodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
107 fSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(false));
108 if (nodeToAdd
.getBackComparator() != null) {
109 bnodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
110 bSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(false));
114 List
<GraphNode
> fNodeList
= (List
<GraphNode
>) fnodes
.get(nodeToAdd
.getArrayId());
115 List
<GraphNode
> bNodeList
= null;
117 bNodeList
= (List
<GraphNode
>) bnodes
.get(nodeToAdd
.getArrayId());
118 if (fNodeList
!= null && fNodeList
.size() > 0) {
119 // check if the nodes are added y ordered
120 // if not, tag the list to sort it later (during draw)
121 GraphNode node
= (GraphNode
) fNodeList
.get(fNodeList
.size() - 1);
122 Comparator
<GraphNode
> fcomp
= nodeToAdd
.getComparator();
123 Comparator
<GraphNode
> bcomp
= nodeToAdd
.getBackComparator();
124 if ((fcomp
!= null) && (fcomp
.compare(node
, nodeToAdd
) > 0)) {
125 fSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(true));
127 if ((bcomp
!= null) && (bcomp
.compare(node
, nodeToAdd
) > 0)) {
128 bSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(true));
132 if (fNodeList
== null) {
133 fNodeList
= new ArrayList
<GraphNode
>();
136 fNodeList
.add(nodeToAdd
);
137 nodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
138 fnodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
139 if (nodeToAdd
.getBackComparator() != null) {
140 bNodeList
.add(nodeToAdd
);
141 bnodes
.put(nodeToAdd
.getArrayId(), bNodeList
);
146 * Set the graph node name.<br>
147 * It is the name display in the view to label the graph node.
149 * @param nodeName the name to set
151 public void setName(String nodeName
) {
156 * Returns the graph node name.<br>
157 * It is the name display in the view to label the graph node.
159 * @return the graph node name
161 public String
getName() {
166 * Tags the the graph node has selected.<br>
167 * WARNING: This method is only used to draw the graph node using the system selection colors. <br>
168 * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class
170 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
171 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
172 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
173 * @param selection - true to set selected, false to set unselected
175 public void setSelected(boolean selection
) {
176 selected
= selection
;
180 * Tags the the graph node as focused.<br>
181 * WARNING: This method is only used to draw the graph node using the system focus style. <br>
182 * To use the complete SDViewer focus mechanism see SDWidget class
184 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
185 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
186 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
187 * @param focus - true to set focued, false otherwise
189 public void setFocused(boolean focus
) {
194 * Returns true if the graph node is selected, false otherwise.<br>
195 * The returned value is used to highlight the graph node in the View.
197 * @return true if selected, false otherwise
200 public boolean isSelected() {
205 * Returns true if the graph node is focused, false otherwise.<br>
206 * The returned value is used to highlight the graph node in the View.
208 * @return true if focued, false otherwise
211 public boolean hasFocus() {
216 * Returns true if the graph node contains the point given in parameter, return false otherwise.
218 * @param x the x coordinate of the point to test containment <br>
219 * y the y coordinate of the point to test containment
220 * @return true if contained, false otherwise
222 abstract public boolean contains(int x
, int y
);
225 * Returns the x coordinate of the graph node
227 * @return the x coordinate
229 abstract public int getX();
232 * Returns the y coordinate of the graph node
234 * @return the y coordinate
236 abstract public int getY();
239 * Returns the graph node height
241 * @return the graph node height
243 abstract public int getHeight();
246 * Returns the graph node width
248 * @return the graph node width
250 abstract public int getWidth();
253 * Draws the graph node in the given context
255 * @param context the graphical context to draw in
257 abstract protected void draw(IGC context
);
260 * Returns the GraphNode visibility for the given visible area. Wrong visibility calculation, may strongly impact
261 * drawing performance
267 * @return true if visible false otherwise
269 public boolean isVisible(int x
, int y
, int width
, int height
) {
274 * Return a comparator to sort the GraphNode of the same type This comparator is used to order the GraphNode array
275 * of the given node type. (see getArrayId).
277 * @return the comparator
279 public Comparator
<GraphNode
> getComparator() {
284 * If needed, return a different comparator to backward scan the GraphNode array
286 * @return the backward comparator or null if not needed
288 public Comparator
<GraphNode
> getBackComparator() {
293 * Compare two graphNodes
295 * @param node the node to compare to
296 * @return true if equal false otherwise
298 public boolean isSameAs(GraphNode node
) {
303 * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered
306 * @return the node type identifier
308 abstract public String
getArrayId();
311 * Return true if the distance from the GraphNode to the given point is positive
313 * @param x the point x coordinate
314 * @param y the point y coordinate
315 * @return true if positive false otherwise
317 public boolean positiveDistanceToPoint(int x
, int y
) {
322 * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current
323 * visible area can be returned
325 * @param x the x coordinate of the point to test
326 * @param y the y coordinate of the point to test
327 * @return the graph node containing the point given in parameter, null otherwise
329 public GraphNode
getNodeAt(int x
, int y
) {
330 GraphNode toReturn
= null;
335 Iterator
<String
> it
= nodes
.keySet().iterator();
336 GraphNode node
= null;
337 while (it
.hasNext()) {
338 Object nodeType
= it
.next();
339 List
<GraphNode
> list
= (List
<GraphNode
>) nodes
.get(nodeType
);
340 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
341 node
= getNodeFromListAt(x
, y
, list
, index
);
342 if (toReturn
== null)
345 GraphNode internalNode
= node
.getNodeAt(x
, y
);
346 if (internalNode
!= null)
349 else if (Math
.abs(node
.getWidth()) < Math
.abs(toReturn
.getWidth()) || Math
.abs(node
.getHeight()) < Math
.abs(toReturn
.getHeight()))
356 public ArrayList
<GraphNode
> getNodeList(GraphNode from
, GraphNode to
) {
357 ArrayList
<GraphNode
> result
= new ArrayList
<GraphNode
>();
361 } else if (to
!= null) {
365 if (from
== null || to
== null)
371 int startX
= Math
.min(from
.getX(), Math
.min(to
.getX(), Math
.min(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
372 int endX
= Math
.max(from
.getX(), Math
.max(to
.getX(), Math
.max(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
373 int startY
= Math
.min(from
.getY(), Math
.min(to
.getY(), Math
.min(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
374 int endY
= Math
.max(from
.getY(), Math
.max(to
.getY(), Math
.max(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
379 Iterator
<String
> it
= nodes
.keySet().iterator();
380 while (it
.hasNext()) {
381 Object nodeType
= it
.next();
382 List
<GraphNode
> nodesList
= (List
<GraphNode
>) nodes
.get(nodeType
);
383 if (nodesList
== null || nodesList
.isEmpty())
385 for (int i
= 0; i
< nodesList
.size(); i
++) {
386 GraphNode node
= (GraphNode
) nodesList
.get(i
);
387 int nw
= node
.getWidth();
388 int nh
= node
.getHeight();
389 int nx
= node
.getX();
390 int ny
= node
.getY();
391 if (contains(startX
, startY
, endX
- startX
, endY
- startY
, nx
+ 1, ny
+ 1) && contains(startX
, startY
, endX
- startX
, endY
- startY
, nx
+ nw
- 2, ny
+ nh
- 2))
393 result
.addAll(node
.getNodeList(from
, to
));
396 if ((to
!= null) && (!result
.contains(to
)))
402 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
403 * iteration at the given index<br>
404 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
406 * @param x the x coordinate of the point to test
407 * @param y the y coordinate of the point to test
408 * @param list the list to search in
409 * @param fromIndex list browsing starting point
410 * @return the graph node containing the point given in parameter, null otherwise
412 protected GraphNode
getNodeFromListAt(int x
, int y
, List
<GraphNode
> list
, int fromIndex
) {
415 for (int i
= fromIndex
; i
< list
.size(); i
++) {
416 GraphNode node
= (GraphNode
) list
.get(i
);
417 if (node
.contains(x
, y
))
424 * Returns the start event occurrence attached to this graphNode.
426 * @return the start event occurrence attached to the graphNode
428 public int getStartOccurrence() {
429 return startEventOccurrence
;
433 * Returns the end event occurrence attached to this graphNode
435 * @return the start event occurrence attached to the graphNode
437 public int getEndOccurrence() {
438 return endEventOccurrence
;
442 * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area
445 * @param x visible area top left corner x coordinate
446 * @param y visible area top left corner y coordinate
447 * @param width visible area width
448 * @param height visible area height
450 public void updateIndex(int x
, int y
, int width
, int height
) {
453 if(TmfUiTracer
.isIndexTraced()) {
454 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
455 TmfUiTracer
.traceIndex("Visible area position in virtual screen (x,y)= " + x
+ " " + y
+ "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
458 Iterator
<String
> it
= nodes
.keySet().iterator();
459 while (it
.hasNext()) {
460 String nodeType
= it
.next();
462 int drawIndex
= ((Integer
) indexes
.get(nodeType
)).intValue();
464 * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); }
466 if ((nodes
.get(nodeType
) != null) && (((List
<GraphNode
>) nodes
.get(nodeType
)).size() > 1)) {
467 if (((GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
)).positiveDistanceToPoint(x
, y
))
473 if ((direction
== -1) && (bnodes
.get(nodeType
) != null)) {
474 GraphNode currentNode
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
);
475 drawIndex
= Arrays
.binarySearch(((List
<GraphNode
>) bnodes
.get(nodeType
)).toArray(new GraphNode
[0]), ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
), currentNode
.getBackComparator());
476 nodes
.put(nodeType
, (List
<GraphNode
>) bnodes
.get(nodeType
));
481 nodes
.put(nodeType
, (List
<GraphNode
>) bnodes
.get(nodeType
));
483 GraphNode prev
= null;
485 for (int i
= drawIndex
; i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() && i
>= 0; i
= i
+ direction
) {
487 indexes
.put(nodeType
, Integer
.valueOf(i
));
489 GraphNode currentNode
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
);
494 Comparator
<GraphNode
> comp
= currentNode
.getComparator();
495 HashMap
<String
, Boolean
> sort
= fSort
;
497 if (direction
== -1) {
498 if (currentNode
.getBackComparator() != null) {
499 comp
= currentNode
.getBackComparator();
504 if (i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() - 1) {
505 GraphNode next
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
+ 1);
507 if ((comp
!= null) && (comp
.compare(currentNode
, next
) > 0))
508 sort
.put(nodeType
, Boolean
.valueOf(true));
510 if (direction
== 1) {
511 if (((GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
)).positiveDistanceToPoint(x
, y
))
514 if (currentNode
.getBackComparator() == null) {
515 if // (currentNode.isVisible(x,y,width,height)
516 (!currentNode
.positiveDistanceToPoint(x
, y
))
519 if (currentNode
.isVisible(x
, y
, width
, height
) && !currentNode
.positiveDistanceToPoint(x
, y
)) {
520 if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0))
522 } else if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0))
528 nodes
.put(nodeType
, fnodes
.get(nodeType
));
529 if ((bnodes
.get(nodeType
) != null) && (direction
== -1)) {
530 // nodes.put(nodeType,fnodes.get(nodeType));
531 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
532 List
<GraphNode
> list
= (List
<GraphNode
>) nodes
.get(nodeType
);
533 List
<GraphNode
> backList
= (List
<GraphNode
>) bnodes
.get(nodeType
);
534 GraphNode currentNode
= (GraphNode
) (backList
.get(index
));
536 index
= Arrays
.binarySearch(list
.toArray(new GraphNode
[0]), backList
.get(index
), currentNode
.getComparator());
539 indexes
.put(nodeType
, Integer
.valueOf(index
));
543 for (int i
= drawIndex
; i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() && i
>= 0; i
++) {
544 GraphNode toDraw
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
);
545 toDraw
.updateIndex(x
, y
, width
, height
);
546 if (!toDraw
.isVisible(x
, y
, width
, height
))
550 if (TmfUiTracer
.isIndexTraced()) {
551 TmfUiTracer
.traceIndex("First drawn " + nodeType
+ " index = " + drawIndex
+ "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
552 TmfUiTracer
.traceIndex(nodeType
+ " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$
556 if (TmfUiTracer
.isIndexTraced()) {
557 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
562 * Draws the children nodes on the given context.<br>
563 * This method start width GraphNodes ordering if needed.<br>
564 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
566 * @param context the context to draw to
567 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
569 protected void drawChildenNodes(IGC context
) {
573 // If the nodes have not been added ordered, the array is ordered
574 Iterator
<String
> it
= fSort
.keySet().iterator();
575 while (it
.hasNext()) {
576 String nodeType
= it
.next();
577 boolean sort
= ((Boolean
) fSort
.get(nodeType
)).booleanValue();
579 GraphNode
[] temp
= ((List
<GraphNode
>) fnodes
.get(nodeType
)).toArray(new GraphNode
[0]);
580 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
581 Arrays
.sort(temp
, node
.getComparator());
582 fSort
.put(nodeType
, Boolean
.valueOf(false));
583 nodes
.put(nodeType
, Arrays
.asList(temp
));
584 fnodes
.put(nodeType
, Arrays
.asList(temp
));
585 if (TmfUiTracer
.isSortingTraced())
586 TmfUiTracer
.traceSorting(nodeType
+ " array sorted\n"); //$NON-NLS-1$
590 Iterator
<String
> it2
= bSort
.keySet().iterator();
591 while (it2
.hasNext()) {
592 String nodeType
= it2
.next();
593 boolean sort
= ((Boolean
) bSort
.get(nodeType
)).booleanValue();
595 GraphNode
[] temp
= ((List
<GraphNode
>) bnodes
.get(nodeType
)).toArray(new GraphNode
[0]);
596 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
597 Arrays
.sort(temp
, node
.getBackComparator());
598 bSort
.put(nodeType
, Boolean
.valueOf(false));
599 bnodes
.put(nodeType
, Arrays
.asList(temp
));
600 if (TmfUiTracer
.isSortingTraced())
601 TmfUiTracer
.traceSorting(nodeType
+ " back array sorted\n"); //$NON-NLS-1$
605 if (TmfUiTracer
.isDisplayTraced()) {
606 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
610 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom() < Metrics
.MESSAGE_SIGNIFICANT_VSPACING
)
611 arrayStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
/ ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom()));
614 Iterator
<String
> it3
= fSort
.keySet().iterator();
615 while (it3
.hasNext()) {
617 Object nodeType
= it3
.next();
618 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
619 context
.setFont(Frame
.getUserPref().getFont(node
.prefId
));
620 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
621 count
= drawNodes(context
, (List
<GraphNode
>) nodes
.get(nodeType
), index
, arrayStep
);
622 if (TmfUiTracer
.isDisplayTraced())
623 TmfUiTracer
.traceDisplay(count
+ " " + nodeType
+ " drawn, starting from index " + index
+ "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
625 if (TmfUiTracer
.isDisplayTraced()) {
626 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
632 * Draw the GraphNode stored in the given list, starting at index startIndex with the given step
634 * @param context the context to draw to
635 * @param list the GraphNodes list
636 * @param startIndex the start index
637 * @param step the step to browse the list
638 * @return the number of GraphNodes drawn
640 protected int drawNodes(IGC context
, List
<GraphNode
> list
, int startIndex
, int step
) {
644 GraphNode last
= null;
649 GraphNode node
= (GraphNode
) list
.get(0);
650 context
.setFont(Frame
.getUserPref().getFont(node
.prefId
));
651 Comparator
<GraphNode
> comparator
= node
.getComparator();
652 for (int i
= startIndex
; i
< list
.size(); i
= i
+ step
) {
653 GraphNode toDraw
= (GraphNode
) list
.get(i
);
654 if (i
< list
.size() - 1) {
655 GraphNode next
= (GraphNode
) list
.get(i
+ 1);
656 if ((comparator
!= null) && (comparator
.compare(toDraw
, next
) > 0)) {
657 fSort
.put(next
.getArrayId(), Boolean
.valueOf(true));
660 int cx
= context
.getContentsX();
661 int cy
= context
.getContentsY();
662 int cw
= context
.getVisibleWidth();
663 int ch
= context
.getVisibleHeight();
664 // The arrays should be ordered, no needs to continue for this one
665 if (!toDraw
.isVisible(cx
, cy
, cw
, ch
) && toDraw
.positiveDistanceToPoint(cx
+ cw
, cy
+ ch
))
667 // ***Common*** nodes visibility
668 if ((!toDraw
.isSameAs(last
) || toDraw
.isSelected()) && (toDraw
.isVisible(context
.getContentsX(), context
.getContentsY(), context
.getVisibleWidth(), context
.getVisibleHeight()))) {
671 toDraw
.draw(context
);
673 toDraw
.drawFocus(context
);
680 public void drawFocus(IGC context
) {
681 context
.drawFocus(getX(), getY(), getWidth(), getHeight());
685 * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height)
687 * @param x the rectangle x coordinate
688 * @param y the rectangle y coordinate
689 * @param width the rectangle width
690 * @param height the rectangle height
691 * @param px the x coordinate of the point to test
692 * @param py the y coordinate of the point to test
693 * @return true if contained false otherwise
695 public static boolean contains(int x
, int y
, int width
, int height
, int px
, int py
) {
698 int locWidth
= width
;
699 int locHeight
= height
;
703 locWidth
= -locWidth
;
707 locY
= locY
+ height
;
708 locHeight
= -locHeight
;
710 return (px
>= locX
) && (py
>= locY
) && ((px
- locX
) <= locWidth
) && ((py
- locY
) <= locHeight
);