Java Drawing DrawTop

Language

JP  US  UK

 

Mouse Position Monitor

 H. Jyounishi, Tokyo Japan
 

Frame (Index), No frame                 version:0.3(latest)  

Summary:
The mouse position monitor (MousePositionLS ) calculates in real time whether or not the mouse hits any of shape objects, whenever the mouse was moved. Here "the mouse hits" means that the mouse is located on a shape or very close to a shape boundary. More precisely, the mouse position monitor calculates the hits with a shape element, a text area or an associated shape objects (i.e. a selection box, resize handles, start and end points of a curve, segment junction points of polyline, tangent line of a cubic curve etc.). The mouse position monitor is used in the various functions such as selecting shape, moving/resizing shape, modifyng shape and so on.
Class on this page:MousePositionInfo, MousePositionLS
=> DrawTest: Mouse hit test for a closed shape, Mouse hit test for an unclosed shape

1. Overview
1.1 Mouse position code
The mouse position is classified as Table1.

Table 1. Mouse position code

Code int Mouse position
NO_HIT 0 Empty space, i.e. the mouse hits no shape.
INSIDE_DRAWAREA 1 Inside the drawing area of a shape
(Figure 1.2)
SELECTION_BOX 2 Selection box
NW_RESIZE 3 North West Resize Handle
NE_RESIZE 4 North East Resize Handle
SE_RESIZE 5 South East Resize Handle
SW_RESIZE 6 South West Resize Handle
N_RESIZE 7 North Resize Handle
E_RESIZE 8 East Resize Handle
S_RESIZE 9 South Resize Handle
W_RESIZE 10 West Resize Handle
BOUNDINGBOX_BOUNDARY 11 Bounding box boundary of a shape
INSIDE_BOUNDINGBOX 12 Inside the bounding box boundary of a shape
SHAPE_BOUNDARY 13 Boundary of a shape
END_POINT 14 Endpoints of a line/polyline/cubic curve (Figure 1.3)
CONTROL_POINT 15 Control point (Figure 1.3)
INSIDE_SHAPE 16 Inside a shape
TEXTBOX_BOUNDARY 17 Boundary of a text box
INSIDE_TEXTBOX 18 inside a text box
INSIDE_TEXT 19 Inside the rectangle area in which texts are really displayed.


Figure 1.1 Selection box, resize handles


Figure 1.2 DRAWAREA (Light green area)
The DRAWAREA is a maximum area which covers a shape itself and its relativefigures
such as its selection box, resize handles and tangent lines.




Figure 1.3Control points, endpoints (start/end point)
The segment junction points (segment junction points) of a polyline or a piecewise cubic curve and the endpoints of tangent lines are classified as "control points".


1.2 Mouse hit testing return=>page top
The rough test whether or not the mouse position is inside the DRAWAREA is executed at the beginning of the test. More precise tests are as follows:
Shape to be tested Description
closed shape Judgement of the SHAPE_BOUNDARY, INSIDE_SHAPE
The hit testing for a closed shape can be performed easily by using the contains method defined in java.awt.Shape interface. For example, we define four test points around the mouse pointer and tests as follows:
∙ If all the four test points are contained in the shape, then the mouse pointer is located inside the shape.
∙ If all the four test points aren't contained in the shape, then the mouse pointer is located outside the shape.
∙ Otherwise, the mouse pointer is on the boundary of the shape.


Mouse position and test points

Inside the shape On the shape boundary Outside the shape

• Relative methods=>MousePositionLS.createMousePositionOfShape, MousePositionLS.ptOnShape
• Unit test=>Mouse hit test for a closed shape
Line, open polyline, open cubic curve Judgement of the SHAPE_BOUNDARY
The "open" means that a shape boundary is not closed. In this case, the contains method doesn't work.
To test whether or not the mouse pointer is on a line or a curve, the getShortestLine method of the Curve2DUtil is used. The getShortestLine method calculates the nearest point on a line or a curve from the mouse pointer. This method is performed based on the bisection and Newton-Raphson method, so it achieves unnecessary accuracy for the hit testing. However it is very fast and there is no problem for the real time operation.
See
User's guide test
• Relative methods=>MousePositionLS.createMousePositionOfShape, MousePositionLS.ptOnShape
• Unit test=>Mouse hit test for an unclosed shape
Text area Judgement of the INSIDE_TEXT
The rectangles covering all the text lines in a text box can be got by the LineBreaker.getBounds method.
Returns the maximum rectangle which covers all the rectangles by the TextBox.getTextLayoutArea method.
See
• Relative method=> MousePositionLS.ptOnBox
Rectangle(box) Judgement of the SELECTION_BOX, BOUNDINGBOX_BOUNDARY,INSIDE_BOUNDINGBOX etc
This judgement method is easy.
See
• Relative method=> MousePositionLS.ptOnBox
Point, small rectangle Judgement of the NW_RESIZE - W_RESIZE, END_POINT, CONTROL_POINT etc.
The hit testing for a point or a small rectangle is used for checking whether the mouse pointer is located on a resize handle or control point. The method is easy.

• Relative method=> MousePositionLS.onResizeMark, MousePositionLS.onPoint


2. Class MousePositionInfo return=>page top
public class MousePositionInfo implements Serializable
A MousePositionInfo object is an output from the mouse position monitor (MousePositionLS). It contains the information about the hit shape, text box, mouse position code , hit position and so on.
Field Description
container ShapeContainer container
If the mouse hits a shape, then the ShapeContainer of the shape is set to this field. The ShapeContainer can be a container of grouped shapes.
shapeContainerInGroup ShapeContainer shapeContainerInGroup
If the mouse hits a shape in a group, then the ShapeContainer of the hit shape is set to this field.
textBox TextBox textBox
If the mouse hits a text box, then the text box is set to this field.
mouseStatus String mouseStatus
A string of "mousePressed", "mouseClicked" or "mouseCDragged" is set to this field.
rightButtonPressed
boolean rightButtonPressed
This field is set by the MousePositionLS.mousePressed method, and referred in the mousePressed method.
True if the mouse button 2 or 3 is pressed.
position int position
The mouse position code.
point Point2D point
The mouse position is set to this field.
information String information
Supplemental information.
NO_HIT (static) public static final int NO_HIT=0;
=> mouse position code
INSIDE_DRAWAREA
(static)
public static final int INSIDE_DRAWAREA=1;
SELECTION_BOX
(static)
public static final int SELECTION_BOX=2;
NW_RESIZE (static) public static final int NW_RESIZE=3;
NE_RESIZE (static) public static final int NE_RESIZE=4;
SE_RESIZE (static) public static final int SE_RESIZE=5;
SW_RESIZE (static) public static final int SW_RESIZE=6;
N_RESIZE (static) public static final int N_RESIZE=7;
E_RESIZE (static) public static final int E_RESIZE=8;
S_RESIZE (static) public static final int S_RESIZE=9;
W_RESIZE (static) public static final int W_RESIZE=10;
BOUNDINGBOX_BOUNDARY (static) public static final int BOUNDINGBOX_BOUNDARY=11;
INSIDE_BOUNDINGBOX
(static)
public static final int INSIDE_BOUNDINGBOX=12;
SHAPE_BOUNDARY
(static)
public static final int SHAPE_BOUNDARY=13;
END_POINT (static) public static final int END_POINT=14;
CONTROL_POINT
(static)
public static final int CONTROL_POINT=15;
INSIDE_SHAPE
(static)
public static final int INSIDE_SHAPE=16;
TEXTBOX_BOUNDARY (static) public static final int TEXTBOX_BOUNDARY=17;
INSIDE_TEXTBOX
(static)
public static final int INSIDE_TEXTBOX=18;
INSIDE_TEXT
(static)
public static final int INSIDE_TEXT=19;
=> mouse position code
positionString
(static)
public final static String[] positionString=new String[20];
Stores the strings representing the mouse position codes.

Method Description
Constructor public MousePositionInfo()
Calls the setPositionString method.
setContainer public void setContainer(ShapeContainer container)
Sets the parameter to the corresponding field.
setShapeContainerInGroup public void setShapeContainerInGroup(ShapeContainer shapeContainerInGroup)
Sets the parameter to the corresponding field.
setTextBox public void setTextBox(TextBox textBox)
Sets the parameter to the corresponding field.
setMouseStatus public void setMouseStatus(String mouseStatus)
Sets the parameter to the corresponding field.
setRightButtonPressed public void setRightButtonPressed(boolean pressed)
Sets the parameter to the corresponding field.
setPosition public void setPosition(int position)
Sets the parameter to the corresponding field.
setPoint public void setPoint(Point2D point)
Sets the parameter to the corresponding field.
setInformation public void setInformation(String inf)
Sets the parameter to the corresponding field.
getContainer public ShapeContainer getContainer()
Returns the container field.
getShapeContainer
InGroup
public ShapeContainer getShapeContainerInGroup()
Returns the shapeContainerInGroup field.
getTextBox public TextBox getTextBox()
Returns the textBox field.
getMouseStatus public String getMouseStatus()
Returns the mouseStatus field.
isRightButtonPressed public boolean isRightButtonPressed()
Returns the rightButtonPressed field.
getPosition public int getPosition()
Returns the position field.
getPoint public Point2D getPoint()
Returns the point field.
getInformation public String getInformation()
Returns the information field.
onResizeMark public boolean onResizeMark()
Returns true if the mouse position code equals NW_RESIZE,...... or W_RESIZE.
onEndPoint public boolean onEndPoint()
Returns true if the mouse position code equals END_POINT.
onControlPoint public boolean onControlPoint()
Returns true if the mouse position code equals CONTROL_POINT
clone public Object clone()
Returns a clone object.
toString public String toString()
Returns the string representing this object.
setPositionString private void setPositionString()
Sets the strings representing the mouse position codes to the positionString field.
getPositionString
(static)
public static String getPositionString(int position)
Returns the string of the mouse position code.
getPositionString
InDetail

(static)
public static String getPositionStringInDetail(int position)
Returns the detailed string of the mouse position code.


3. Class MousePositionLS return=>page top
public class MousePositionLS implements MouseListener, MouseMotionListener
3.1 Getting the mouse position

The MousePositionLS calculates in real time whether or not the mouse hits any of shape objects whenever the mouse is moved. If the mouse hits the shape, the MousePositionLS creates a new MousePositionInfo object and stores it the infos array field.
The mouseMoved and mouseDragged methods receive the mouse movement, so the both methods call the createMousePositionInfo method to output the results of the mouse hit testing.
=>Mouse position code


3.2 The related functions
The MousePositionLS class also performs the following functions.
(1) Triggers popup menu

The mouseClicked method of this class or the mouseClicked method of the SelectionLS triggers the popup menu and calls the ExecPopupMenu.show method.


(2) Displaying a MousePositionInfo

The mouseDragged and mouseMoved methods of this class calls the displayMousePosition method. It displays MousePositionInfo objects on the message panel at the bottom of the window. If the mouse hits multiple shapes, then it displays multiple MousePositionInfo objects.


Figure 3.1 Message panel


(3) Changing the mouse cursor mark
The mouseMoved method performs the operation.

3.3 Special issues

It seems uneconomical that this class creates new MousePositionInfo objects whenever the mouse hits a shape.
To avoid this, the MousePositionLS constructor reserves an array of MousePositionInfo objects. If the mouse hits a hape, then the setMousePosition method sets the hit information to a reserved MousePositionInfo object. For this reason, the processing of outputting MousePositionInfo objects is a little bit complex. The fields and the methods related to this are as follows:


Field and method Description
The number of reserved MousePositionInfo objects The maxInfos field. Currently the maxInfos is 50.
The counter of output MousePositionInfo objects The infoCount field.
The method of setting the MousePositionInfo to the array The setMousePosition method of this class
The methods of getting the MousePositionInfo from the array Some methods are available according to the purpose.
getMousePositionInfoForSelection - Returns the MousePositionInfo objects for selecting a shape.
getMousePositionInfoForMoveResize - Returns the single MousePositionInfo object for moving/resizing a shape.
getAllMousePositionInfo - Returns all MousePositionInfo objects.


3.4 MousePositionLS API return=>page top
public class MousePositionLS implements MouseListener, MouseMotionListener
Field
Description
popupTrigger
(static)
public static boolean popupTrigger
Same as the SelectionLS.popupTrigger field.
See=> Popup Menu Triggers popup menu
clicked boolean clicked
The mouseClicked method of this class sets true to this field. This field is referred in the mouseEventCompleted method.
clickedPoint public Point2D clickedPoint
The clicked point is stored to this field.
infoCount private int infoCount
The number of output MousePositionInfo objects. This field is counted up by the setMousePosition method.
maxInfos private int maxInfos
The number of reserved MousePositionInfo objects.
infos MousePositionInfo[] infos=new MousePositionInfo[maxInfos]
The reserved array storing MousePositionInfo objects.
See=> Special issues

Method Description
Constructor public MousePositionLS()
Calls the activateListener method to register this object to the ListenerPanel as a MouseListener and MouseMotionListener.
activateListener private void activateListener(boolean activate)
If the activate is true, then this method registers this object to ListenerPanel as a MouseListener and MouseMotionListener.
If the activate is false, then this method removes this object from ListenerPanel.
isMouseListener private boolean isMouseListener()
Inquires whether this object is registered to ListenerPanel or not.
isMouseMotionListener private boolean isMouseMotionListener()
Inquires whether this object is registered to ListenerPanel or not.
mousePressed public void mousePressed(MouseEvent e)
∙ Stores the return value of the isPopupTrigger method of the e (MouseEvent) to the popupTrigger field.
See =>SelectionLS Getting PopupTrigger, Popup Menu Triggers popup menu
∙ If the mouse right button was pressed, then this method calls the setRightButtonPressed methods for all the current MousePositionInfo objects which were created in the mouseMoved method.
∙ Calls the displayMousePosition method to display the current MousePositionInfo objects to the message panel.
See=> The related functions (2)
mouseDragged public void mouseDragged(MouseEvent e)
∙ Creates the MousePositionInfo objects by calling the createMousePositionInfo method of this class.
∙ Calls the displayMousePosition method to display the current MousePositionInfo objects to the message panel.
mouseReleased public void mouseReleased(MouseEvent e)
∙ Stores the return value of the isPopupTrigger method of the e (MouseEvent ) to the static field popupTrigger.
See=>SelectionLS Getting PopupTrigger, Popup Menu Triggers popup menu
∙ Calls the displayMousePosition method to display the current mouse position on the message panel.
mouseClicked public void mouseClicked(MouseEvent e)
∙ Calls the displayMousePosition method to display the current mouse position on the message panel.
∙ If the return value of the allMouseEventsCompleted method is true and the value of the statement - (SelectionLS.popupTrigger||popupTrigger) - is true, then this method calls the ExecPopupMenu.show method to show the popup menu. The same logic is implemented in the mouseClicked method of the SelectionLS.
See=> Popup Menu Triggers popup menu
mouseMoved public void mouseMoved(MouseEvent e)
∙ Creates the MousePositionInfo objects by calling the createMousePositionInfo method of this class and calls the displayMousePosition method to display them on the message panel.
∙ Changes the cursor mark according to the mouse position code of the MousePositionInfo given by the getMousePositionInfoForSelection method.
mouseEntered public void mouseEntered(MouseEvent e)
Sets the default cursor mark.
mouseExited public void mouseExited(MouseEvent e)
Sets the default cursor mark.
displayMousePosition private void displayMousePosition(String mouseAction, double X, double Y)
Displays the MousePositionInfo objects on the message panel.
See=> The related functions (2)
getMousePositionInfo
ForSelection
public MousePositionInfo[] getMousePositionInfoForSelection()BR> Returns the MousePositionInfo objects used for selecting shapes. If multiple MousePositionInfo objects exists in the infos, this method sorts them according to their ranks and returns them in descendant order.
The ranks are as follow in descending order(mouse position code):
∙ MousePositionInfo.NW_RESIZE - W_RESIZE, END_POINT, CONTROL_POINT
∙ MousePositionInfo.SELECTION_BOX.
∙ MousePositionInfo.INSIDE_TEXT.
∙ MousePositionInfo.SHAPE_BOUNDARY
∙ MousePositionInfo.TEXTBOX_BOUNDARY.
∙ MousePositionInfo.SELECTION_BOX
∙ MousePositionInfo.INSIDE_TEXTBOX
∙ MousePositionInfo.INSIDE_SHAPE
∙ MousePositionInfo.BOUNDINGBOX_BOUNDARY, INSIDE_BOUNDINGBOX
: If the same rank is set to mulyiple mouse position informations, for example, MousePositionInfo.INSIDE_SHAPE, then the higher rank is set to the mouse position information with the forward shape in z- order(User's guide).
getMousePositionInfo
ForMoveResize
public MousePositionInfo getMousePositionInfoForMoveResize()
Returns the MousePositionInfo objects used for moving or resizing shapes. If multiple MousePositionInfo objects exists in the infos, this method returns the single MousePositionInfo object of the highest rank.
The ranks are as follow in descending order(mouse position code):
∙ MousePositionInfo.NW_RESIZE - W_RESIZE, END_POINT
∙ MousePositionInfo.TEXTBOX_BOUNDARY.
∙ MousePositionInfo.SHAPE_BOUNDARY
∙ MousePositionInfo.SELECTION_BOX
∙ MousePositionInfo.INSIDE_SHAPE
: If the same rank is set to mulyiple mouse position informations, for example, MousePositionInfo.INSIDE_SHAPE, then the higher rank is set to the mouse position information with the forward shape in z- order(User's guide).
getAllMousePositionInfo public MousePositionInfo[] getAllMousePositionInfo()
Returns all the MousePositionInfo objects which hits shapes.
mouseEventCompleted public boolean mouseEventCompleted()
Inquires whether or not the methods of this class - mousePressed, mouseDragged, mouseReleased and mouseClicked - have finished. This method is called from this class and the SelectionLS class.
allMouseEventCompleted public boolean allEventsCompleted()
Returns true if the mouseEventCompleted method of this class and the same method of the SelectionLS both returns true.
See=>Popup Menu Triggers popup menu
createMousePositionInfo private void createMousePositionInfo(double X, double Y)
Parameters:
(X, Y) - The current mouse position.
Processing:
This method is the main method for the mouse hit testing.
If the shape to be tested is a group of shapes, then this method calls the createMousePositionOfGroup method, else this method calls the createMousePositionOfShape method. These two methods output MousePositionInfo objects if the mouse hits any of the existing shapes.
createMousePosition
OfShape
private void createMousePositionOfShape(double X, double Y, ShapeContainer shapeContainer)
Parameters:
(X, Y) - The current mouse position.
shapeContainer - Represents a shape, not a group of shapes.
Processing:
The mouse hit testing for a single shape. The shapeContainer can't be a group of shapes.
createMousePosition
OfGroup
private void createMousePositionOfGroup(double X, double Y, ShapeContainer shapeContainer)
Parameters:
(X, Y) - The current mouse position.
shapeContainer - Represents a shape, not a group of shapes.
Processing:
The mouse hit testing for a group of shapes.
The hit testing is performed for each shape and the hit types such as MousePositionInfo.BOUNDINGBOX_BOUNDARY, MousePositionInfo.SELECTION_BOX and "on resize marks" are tested. Other detailed types will be tested by createMousePositionOfShapeInGroup.
createMousePosition
OfShapeInGroup
private void createMousePositionOfShapeInGroup(double X, double Y, ShapeContainer groupContainer, ShapeContainer shapeContainer)
Parameters:
(X, Y) - The current mouse position.
groupContainer - Represents a group of shapes.
shapeContainer - Represents a shape contained in groupContainer.
Processing:
This method tests MousePositionInfo.TEXTBOX_BOUNDARY and MousePositionInfo.INSIDE_TEXT for each shapeContainer in a group.
ptOnShape private int ptOnShape(double X, double Y, ShapeContainer shapeContainer)
Parameters:
(X, Y) - The current mouse position.
shapeContainer - Represents a shape, not a group of shapes.
Returns:
0 - Outside the shape.
SHAPE_BOUNDARY - On the shape boundary.
INSIDE_SHAPE - Inside the shape.
Processing:
This method tests whether the point (X,Y) is on a shape boundary or inside a shape. The shapeContainer can't be a group of shapes.
∙ For an open shape
Calculates the nearest point on the shape's boundary from (X,Y) by the getShortestLine of the Curve2DUtil. If the distance between (X,Y) and the nearest point is less than a given tolerance, this method returns SHAPE_BOUNDARY.
Here the tolerance is given by 0.5*(DrawParameters.Mark_NormalSize/scale) and the scale means zoom factor.
∙ For a closed shape
This method creates four points around (X,Y) and tests whether the mouse is outside the shape, on the shape boundary or inside the shape as follows.
∙ If all the four points are contained in the shape, then the mouse pointer is located inside the shape.
∙ If all the four points aren't contained in the shape, then the mouse pointer is located outside the shape.
∙ Otherwise, the mouse pointer is on the boundary of the shape.
See=> Mouse hit testing
ptOnBox private int ptOnBox(double X, double Y, Rectangle2D box)
Parameters:
(X, Y) - The current mouse position.
box - The Rectangle2D object.
Returns:
0 - Outside the shape.
BOUNDINGBOX_BOUNDARY
- On the box boundary.
INSIDE_BOUNDINGBOX - Inside the box.
Processing:
The processing is similar to the ptOnShape method.
ptInfOnBox private String ptInfOnBox(double X, double Y, Rectangle2D box)
This method is called from the createMousePositionOfShape and createMousePositionOfShapeInGroup methods. Currently this method is used to add the supplemental information to the TEXTBOX_BOUNDARY and referred in the TextBox.mouseDragged method.
Parameters:
(X, Y) - The current mouse position.
box - The Rectangle2D object.
Returns:
Returs "outside"/"inside"/"top"/"bottom"/"left"/"right".
Processing:
The processing is similar to the ptOnBox method.
onPoint private int onPoint(double X, double Y, Point2D[] points)
Parameters:
(X, Y) - The current mouse position.
points - The Point2D objects.
Returns:
If (X,Y) equals any of the points, then returns its array index. Otherwise returns -1.
Processing:
Tests whether the point (X,Y) equals any of the points within a given tolerance. The tolerance is given by 0.5*DrawParameters.Mark_NormalSize/scale.
onResizeMark private int onResizeMark(double X, double Y, Rectangle2D rectangle)
Parameters:
(X, Y) - The current mouse position.
rectangle - The rectangle representing a resize handle.
Returns:
If the mouse is on a resize handle, then returns NW_RESIZE, NE_RESIZE, SE_RESIZE, SW_RESIZE, N_RESIZE, E_RESIZE, S_RESIZE or W_RESIZE, otherwise returns 0.
Processing:
Tests whether the point (X,Y) is on a resize handle of a shape or not.
boxContains private boolean boxContains(double X, double Y, double delta, double boxX, double boxY)
Parameters:
(X, Y) - The current mouse position.
delta - Half of the edge length.
(boxX, boxY): The center point of the rectangle.
Returns:
Returns true if (X,Y) is inside the box.
Processing:
Tests whether (X,Y) is inside the box whose center point (boxX, boxY) and whose edge length is 2*delta.
setMousePosition private void setMousePosition(ShapeContainer container, ShapeContainer shapeContainerInGroup,TextBox textBox, int position, Point2D point, String inf)
Sets the information of mouse hit testing to a MousePositionInfo object reserved in the infos array.
See=> Special issues




Copyright (c) 2009-2013
All other trademarks are property of their respective owners.