I'm writing a simple game in Java and are trying to get the coordinates of the mouse. What I want is 0,0 at the upper left corner of the content, however, I get coordinates relative to the Window.
The code is as follows:
public void mouseMoved(MouseEvent event)
{
x = event.getY();
y = event.getX();
}
and this is hooked up via JFrame.addWindowListener()
Any suggestions?
I would make sure you bind your event to the content pane inside the window frame. Then your events should trigger relatively from 0,0 coordinates. Assuming, you don't need events outside on the main, which for all purposes you could bind a different event handler there.
Another method is to determine the title bar height and window frame width and just subtract them from the given coordinates (since you are positioned adjacent to them inside the game window - if you move adjust appropriately) for the position relative inside the content frame.
That is relative to the window. The window includes the border around the edge of the contentPane, which is why you're getting 3, 25 instead of 0,0. You can either add your MouseListener to the contentPane directly, or use the frame's Insets to account for the border.
double screenW = Toolkit.getDefaultToolkit().getScreenSize().width;
double screenH = Toolkit.getDefaultToolkit().getScreenSize().height;
double posX = screenW/2 - WIDTH/2;
double posY = screenH/2 - HEIGHT/2;
x = event.getX() - posX;
y = event.getY() - posY;
Related
In my program, I have a ScrollPane which its content is a VBox with a lot of child nodes. Some of the nodes are links which you can click and it should jump to the link's destination (imagine clicking the links in the Contents in a Wikipedia article, it will jump to the corresponding section). I know that in order to vertically scroll the ScrollPane by code, I would use .setVvalue().
My thinking is that I will get the y-coordinate of the link's destination node and divide it by the content's total height, and use that value as the Vvalue. The problem is that how would I accurately get the y-coordinate of a node if it's nested in multiple containers (e.g. in 2 VBoxes) using .getBoundsInParent()? Also, am I even approaching this the correct way?
An example of what I mean:
Before clicking the link
After clicking the link
You can use localToParent multiple times to transform coordinates from the coordinate system of the ScollPane's content node:
public static Point2D transform(Node coordinatesNode, Node ancestor, double x, double y) {
Point2D coordinates = new Point2D(x, y);
while (coordinatesNode != ancestor) {
coordinates = coordinatesNode.localToParent(coordinates);
coordinatesNode = coordinatesNode.getParent();
}
return coordinates;
}
You could e.g. use
Point2D pt = transform(someNode, scrollPane.getContent(), 0, 0);
To get the coordinates of the top-left of someNode in the content of scrllPane.
My thinking is that I will get the y-coordinate of the link's destination node and divide it by the content's total height, and use that value as the Vvalue
This is not 100% correct. You need to include the fact that for vvalue = 1 the bottom of the content is shown at the bottom of the viewport not at the top. Therefore the equation for the y coordinate of the content part shown at the top of the viewport is
y = vvalue * (contentHeight - viewportHeight)
so
vvalue = y / (contentHeight - viewportHeight)
You need to treat cases where contentHeight <= viewportHeight or y > contentHeight - viewportHeight seperatly of course.
The height of the viewport can be retrieved via the viewport bounds
double viewportHeight = scrollPane.getViewportBounds().getHeight();
I know Window.sizeToScene() will resize the window to the size that its scene needs, but the position of the window does not adjust accordingly (i.e. the stationary point is top-left corner of the window). Is there any way to make the window resize itself, and keep the window's center at the same place (i.e. make the stationary point at the center of the window)?
Do something like:
public void resize(Window win) {
double x = win.getX();
double y = win.getY();
double width = win.getWidth();
double height = win.getHeight();
win.sizeToScene();
win.setX(x + ((width - win.getWidth()) / 2));
win.setY(y + ((height - win.getHeight()) / 2));
}
The code above caches the position before the window is resized to the scene, then it moves the window the appropriate amount to keep the window centered in the same area. This code does not take into account where the window will be once it is moved/resized. You might want to add checks to make sure the window doesn't end up going off the screen.
#Override
public Shape getShape() {
final Rectangle2D.Double result = new Rectangle2D.Double();
result.setFrameFromDiagonal(getStart(), getEnd());
//FIX this is causing square to move when going opposite direction
result.setRect(result.getX(), result.getY(),
result.getHeight(), result.getHeight());
return result;
}
So here is my code that is drawing a square using Rectangle2D.Double. The getStart() and getEnd() are points that are being returned from mouseDrag events. When I drag to the right or up, it works as intended and creates a square. When I drag left or down the square moves with the drag as it draws. I am fairly new to Java swing and paint components. Wondering if anyone know what is causing this and why?
You need to consider a few specialities:
Save the first coordinate on mouse click: x,y
Save the last coordinate on mouse drag x2,y2
Set min x and y coordinates as the startpoint for setRect: Math.min(x,x2);
Use the absolute value of the coordinate difference to calculate the height and width of rectangle: Math.abs(x-x2);
px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
result.setRect(px, py, pw, ph);
I'm going the coordinates of my cursor from Java.AWT.MouseInfo and I need to convert it to the coordinate relative to a ScrollPane's viewport. I'm trying to have the scrollpane's scrollbar positions center on where the mouse was when zooming in/out.
viewScroll is a ScrollPane. zoomGroup is a Group containing an imageView that is scaled (zooming). When scaled the method repositions the scrollbars where it was before the scale. I want to reposition the scrollbars where the mouse was at the time of zooming.
protected void zoom(double scaleValue) {
p = MouseInfo.getPointerInfo().getLocation();
double Y = p.getX();
double X = p.getY();
double scrollH = viewScroll.getHvalue();
double scrollV = viewScroll.getVvalue();
zoomGroup.setScaleX(scaleValue);
zoomGroup.setScaleY(scaleValue);
viewScroll.setHvalue(Y);
viewScroll.setVvalue(X);
}
I have a JLayeredPane, and inside the JLayeredPane is a JInternalFrame. What I need are the bounds (x position, y position, width, height) of the content pane in the JInternalFrame. The bounds need to be in relation to the JLayeredPane. My problem is the borders, title bar, and I'm not sure what else of the JInternalFrame are messing with my calculation. It's a few pixels off.
Here is how I try to calculate it. This code is in the JInternalFrame:
Rectangle area = new Rectangle(
getX() + 2, //The x coordinate of the JInternalFrame + 2 for the border
getY() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight(), //The Y position of the JinternalFrame + theheight of the title bar of the JInternalFrame
getContentPane().getWidth() - 2, //The width of the Jinternals content pane - the border of the frame
getContentPane().getHeight() //the height of the JinternalFrames content pane
);
I need to get the location of the content pane of the internal frame.
Coordinates with respect to what? The screen? The window?
Calling getLocation() will give you the coordinates relative to the component's parent in the window hierarchy.
SwingUtilities has several methods for transforming coordinates from one frame of reference to another. So, to compensate for the title bar and frame, you can do this:
JInternalFrame iframe = ...
Container c = iframe.getContentPane();
Rectangle r = c.getBounds();
r = SwingUtilities.convertRectangle(c.getParent(), r, iframe.getParent());
The getBounds() method of JInternalFrame returns a Rectangle with the coordinates you need. Why not just do the following:
{
...
JInternalFrame iframe = ...;
Rectangle r = new Rectangle(iframe.getBounds());
}
This way you don't need to manually calculate the bounds.