I am using the jxmapkit to show a map in a java frame.
Now i am trying to translate a click x,y position into Lat, Long.
This is what I have so far:
public void mouseClicked(MouseEvent e)
{
Point point = e.getPoint();
JXMapViewer map = mainMap.getMainMap();
Rectangle bounds = map.getViewportBounds();
int x = (int)(point.getX() - bounds.getX());
int y = (int)(point.getY() - bounds.getY());
GeoPosition mappos = map.getTileFactory().pixelToGeo(new Point(x,y), map.getZoom());
But the bounds x and y are too big 282723 and 205680 so the translation is obviously failing.
Does
Rectangle bounds = map.getViewportBounds();
work or am I doing something wrong?
are you tried to put that into JScrollPane and then just move with Rectangle to Visible ViewPort, I think that's job for that ...
Related
I'm working on something that involves clicking specific points on a buffered image in a JPanel. I had issues with this earlier in the project (affine transform translation not working properly), but nothing I found fixed it so I decided I would come back to it later.
I'm not entirely sure how to trouble shoot it since I'm a novice, but I think it's reading my y coordinates too low. I made a mouse input listener that tracks the number of times the user has clicked and gets the mouse pointer's location for functions I haven't made yet. For testing I have it output the coordinates and number of clicks then make a circle centered where the mouse clicks.
#Override
public void mouseClicked(MouseEvent e) {
Point mouseCursor = MouseInfo.getPointerInfo().getLocation();
panel.drawCenteredCircle(mouseCursor.getX(), mouseCursor.getY(), 100);
System.out.println(String.valueOf(mouseCursor));
System.out.println(String.valueOf(clickCount));
clickCount++;
}
Here is drawCenteredCircle in my custom panel class:
public void drawCenteredCircle(double x, double y, int r) {
imgG2 = image.createGraphics();
imgG2.setPaint(Color.RED);
x = (x-r/2.0);
y = (y-r/2.0);
imgG2.fillOval((int)Math.round(x), (int)Math.round(y), r, r);
this.repaint();
imgG2.dispose();
}
I tried taking a screenshot to show what happens, but the circle properly centers on the x coordinate, but not the y coordinate. Instead it draws the circle with the pointer at the top center edge.
I overrided the paintComponent of my JPanel to implement a zoom feature:
#Override
protected void paintComponent(Graphics g) {
//Implimenting zoom
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g.create();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
/*Supposed to counter the movement from the scale, not working properly
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double x = (w - scale * imageWidth)/2;
double y = (h - scale * imageHeight)/2;*/
AffineTransform at = new AffineTransform()/*.getTranslateInstance(x, y) */;
at.scale(scale, scale);
g2.drawRenderedImage(image, at);
//g2.dispose(); I was told to put this, but I'm not sure if it's necessary or what it does entirely
}
My confused notes are because I got this code from an example someone made and, as I said earlier, the affine translation wasn't working (I took the actual translation out). They're irrelevant to the question.
The reason I put this is because I initially had code that was meant to fit the image to the screen/frame depending if it was fullscreen or not:
int x = image.getWidth();
int y = image.getHeight();
double frameW = frame.getBounds().getWidth();
double frameH = frame.getBounds().getHeight();
//Rectangle winSize = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
double screenW = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
double screenH = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
if (!isFullScreen) {
if (x/y > frameW/frameH) {
scale = frameW/x;
} else {
scale = frameH/y;
}
} else {
if (x/y > screenW/screenH) {
scale = screenW/x;
} else {
scale = screenH/y;
}
}
It uses my zoom function which scales the image with the double "scale." I noticed that when I zoomed in or out, it would change where the dots would appear relative to the pointer. It wasn't until I removed the code for the image to start fitted to the window and had it start at 100% that I received the result of the pointer being at the top center of the circle.
I also tried removing the part that's supposed to center the circle and the result was the pointer being on the left side and having a gap between it and the top of the circle.
Sorry if this is too much stuff. I'm pretty novice and learned just as much about java (the only coding language I know) working on this project as I knew when I first started it. I'm not sure what information I have that could be helpful in this, so I just threw in everything I thought could help. I appreciate any help, even irrelevant to my question.
#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 trying to create a remote desktop access tool in Java (more of an experiment than anything really), but i'm having trouble converting the point in which is clicked to a location on the main screen. Let me explain.
Here's an example of how the tool looks (for now).
The screen capture window is 1280x720, and the actual screens vary in size, how can I get the location of where the mouse is and change it to the same location on the main screen?
e.g. if I click on the apple logo on the screen capture window, it should move my mouse and click on the apple logo on the main screen. I just can't figure out how to get the point in the window, and translate it to the same point on the main screen!
EDIT: Here is what i'm trying to do atm:
MouseAdapter adapter = new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
PacketMoveMouse packetMoveMouse = new PacketMoveMouse(address, e.getXOnScreen(), e.getYOnScreen());
sendPacket(address, packetMoveMouse);
}
#Override
public void mousePressed(MouseEvent e) {
Point point = this.getPoint(e.getPoint());
PacketClickMouse packetClickMouse = new PacketClickMouse(address, point.getX(), point.getY(), e.getButton());
sendPacket(address, packetClickMouse);
}
private Point getPoint(Point point) {
SwingUtilities.convertPointFromScreen(point, panel);
return point;
}
};
I also tried without converting the point, i was just trying various things. It moves the mouse correctly, but to the wrong point.
I also tried to convert it to a point on the main screen using some basic math, but i think my logic flawed, here is what i tried:
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
int x = ((PacketMoveMouse) packet).getX();
int y = ((PacketMoveMouse) packet).getY();
double xRatio = (screenRect.getWidth() / 1280);
double yRatio = (screenRect.getHeight() / 720);
Robot robot = new Robot();
robot.mouseMove((int) ((x * xRatio)), (int) ((y * yRatio)));
This is when i just send the regular point to the client then change to to a relative point once it's received. The display screen of the client is 1280x720 currently.
To get your mouse CURRENT coordinates
int mouseX;
int mouseY;
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
I am using the following method to try to find a point (coordinate) that hasn't been previously used, and isn't within the bounds of items that have previously used and coordinates.
The way it works is I am rendering "bases" (RTS top-down game), and I am creating two random variable locations for x and y. I pass these, along with the bases texture, into the following method. The method loops through a list of rectangles that are the rectangles of each previously rendered base. If the point is within any of the rectangles, the method is called again using a different set of coordinates. It does this until it finds a set that isn't within a rectangle. It then adds a new rectangle to the list at these coordinates, and returns them so the game can render a new base.
However, the bases still overlap.
Here is the method:
private Point getCoords(int x, int y, Texture t){
for (int i=bases.size()-1; i> -1; i--) {
if (bases.get(i).contains(new Point(x,y))){
x = new Random().nextInt(map.getWidth() * map.getTileWidth());
y = new Random().nextInt(map.getHeight() * map.getTileHeight());
getCoords(x, y, t);
}
}
bases.add(new Rectangle(x,y,t.getImage().getWidth(), t.getImage().getHeight()));
return new Point(x, y);
}
And here is where it is being called:
switch(ran){
default:
int x = new Random().nextInt(map.getWidth() * map.getTileWidth());
int y = new Random().nextInt(map.getHeight() * map.getTileHeight());
Point p = getCoords(x, y, temp);
map.generateBase("air", p.x, p.y);
break;
}
Any ideas what is wrong here?
Thanks
There are several problems:
Your algorithm might be overwritting good coordinates (free ones) with wrong coordinates, you dont have any condition to exit the loop/recursion if you find a good place
You are checking for if rectangle contains the point, but later you are adding a rectanble, so it may not contain the point, but the rectangle created later may collide
try this
private Point getCoords(int x, int y, Texture t){
boolean found = false;
final int width = map.getTileWidth();
final int height = map.getTileHeight();
while(!found) {
x = new Random().nextInt(map.getWidth() * width);
y = new Random().nextInt(map.getHeight() * height);
for (int i=bases.size()-1; i> -1; i--) {
if (!bases.get(i).intersects(new Rectanble(x,y, width, height))){
found = true;
} else found = false;
}
}
bases.add(new Rectangle(x,y,t.getImage().getWidth(), t.getImage().getHeight()));
return new Point(x, y);
}
*** EDIT: Im not sure if I had to use TileWidth and TileHeight or image width and image height for width and height :D
int x = new Random().nextInt(map.getWidth() * map.getTileHeight());
Maybe a bad copy paste. It may be :
int x = new Random().nextInt(map.getWidth() * map.getTileWidth());
In both codes :-D
Okay so after some playing around, I found the issue is the rectangles that are saved are saved with a fixed location which means as the map moves, the rectangles don't. The fix is to loop through each bases and get the base's map position, rather than screen position, and check against this. Also, I found i was checking for a point in a rectangle, which may be outside the rectangle but leaves my bases overlapping still. So i now check for rectangle-rectangle collision instead
My goal is getting the ball to be centered at the paddle even if the value of the ball radius were to change in future versions of the game.
My only problem is implementing the correct math formula
for the x coordinate of the gameball. I got the y coordinate formula working perfectly.
I do not need the correct answer. I just need guidance and suggestions to get the answer.
Here is a picture of the java program:
http://i33.photobucket.com/albums/d86/warnexus/ball.png
You can find the code below the comment "// Trouble figuring the math here".
/** Radius of the ball in pixels */
private static final int BALL_RADIUS = 500;
private void setup_Paddle()
{
// TODO Auto-generated method stub
// x coordinate of the upper left corner
// y coordinate of the upper left corner
paddle = new GRect(20,20,PADDLE_WIDTH,PADDLE_HEIGHT);
paddle.setFilled(true);
paddle.setColor(Color.PINK);
add(paddle,paddleInitialLocationX,paddleInitialLocationY);
}
private void setup_Ball()
{
// Trouble figuring the math here
int ballSetUpCoordX = (int) (paddle.getX());
// Good Code!
int ballSetUpCoordY = (int) (paddle.getY()-BALL_RADIUS);
gameBall = new GOval(BALL_RADIUS,BALL_RADIUS);
gameBall.setFilled(true);
gameBall.setColor(Color.BLUE);
add(gameBall,ballSetUpCoordX,ballSetUpCoordY);
}
private GOval gameBall;
private GRect paddle;
private int paddleInitialLocationX = 200;
private int paddleInitialLocationY = 500;
Coordinates are generally for the top left corner of an object. So to get any two objects o1 and o2 to be centered the same place, you have to offset based on size.
Here we'll move o1's center to o2's center.
int o2CenterX = o2.x - (o2.width/2);
//If we just used o2CenterX, it would put the corner of o1 into the center of o2
o1.x = o2CenterX - (o1.width/2);
Repeat for y, which you appear to have already done(radius serves as width/2). You will likely have to adjust this formula slightly unless you want the paddle and ball intersecting on the screen.