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();
}
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.
I'm trying to have an image follow my cursor, smoothly moving where it is located and turning to face it.
When i'm near the origin, it works flawlessy: the image will flip completely without issues, however the further i go from the origin of the window, the less the image turns. When i'm at the other side of the screen, instead of flipping over it'll rotate 5°-15° instead.
I'd love if somebody could point out what the issue is =)
Here's my current code for the image:
lblRover = new JLabel(sees) { // sees is an ImageIcon
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform aT = g2.getTransform();
Shape oldshape = g2.getClip();
double x = getWidth()/2.0;
double y = getHeight()/2.0;
aT.rotate(Math.toRadians(degrees), x, y);
g2.setTransform(aT);
g2.setClip(oldshape);
super.paintComponent(g);
}
};
lblRover.setSize(179, 180);
lblRover.setLocation(500, 300);
JFrame.getFrames()[0].add(lblRover);
And this is the code that handles the rotation, plus its movement:
NewJFrame.PInf = MouseInfo.getPointerInfo();
/* The frame is contained in NewJFrame, PInf is a PointerInfo */
p = (NewJFrame.PInf.getLocation()); // p is a point
p.x-=NewJFrame.getWindows()[0].getLocationOnScreen().x;
p.y-=NewJFrame.getWindows()[0].getLocationOnScreen().y;
//i subtract the location of the window relative to the screen
img = NewJFrame.lblRover.getLocation();
img.x+=NewJFrame.lblRover.getWidth()/2;
img.y+=NewJFrame.lblRover.getHeight()/2;
// img will be the point with the center of my image
sas=getAngle(p,img); // sas is a float variable
NewJFrame.degrees=sas;
//
// From now on i move the image
//
diffx = p.x-img.x;
diffy = p.y-img.y;
diffx/=80; // 80 is an arbitrary number to smooth the effect
diffy/=80; // high numbers will make the image not move at all
Point var = new Point(NewJFrame.lblRover.getLocation());
// I may have to use img here or subtract width and height /2
var.x+=diffx;
var.y+=diffy;
NewJFrame.lblRover.setLocation(var);
// A 5ms sleep to smooth the movement
// I also refresh a debug label
// Also i do refresh the frame, otherwise nothing happens
NewJFrame.jLabel1.setText(""+NewJFrame.lblRover.getLocation().y
+"/"+ p.y+" "+NewJFrame.lblRover.getLocation().x +"/"+ p.x );
NewJFrame.getFrames()[0].repaint();
try {
sleep(5);
} catch (InterruptedException ex) {
Logger.getLogger(thread.class.getName()).log(Level.SEVERE, null, ex);
}
Well, after multiple tries i've narrowed it down.
Now, the rotation code is put last, before the repaint, and it looks like this:
sas=this.getAngle((float)diffy,(float)diffx);
NewJFrame.degrees=sas;
I've also created this new method that uses two float instead of two points:
public float getAngle(Float x, Float y) {
float angle = (float) Math.toDegrees(Math.atan2(x, y));
//System.out.println(angle);
return angle;
I have no clue why it works now but it didn't before as the procedure is basically identical...but hey it works! =D
Using mouseevents, I am able to get the x and y coordinates of the frame, yet I am unable to get the x and y coordinates of the panel. The below codes are me getting the x and y coordinates of the frame.
public void mouseMoved(MouseEvent e) {
x = e.getX();
y = e.getY();
text = Integer.toString(x) +","+Integer.toString(y);
Frame.frame.repaint();
}
The below codes are me trying to get the x and y coordinates of the panel, but it's painting out 0's instead. Paint.paint is the name of my jpanel. I don't know what I'm doing wrong. Please help if you can.
public void mouseMoved(MouseEvent e) {
x = Paint.paint.getX();
y = Paint.paint.getY();
text = Integer.toString(x) +","+Integer.toString(y);
Frame.frame.repaint();
}
If I understand right, your MouseListener is registered with the JFrame, and you wish to get the x/y relative to a JPanel contained within the JFrame. The x and y within the MouseEvent refer to the Component in which the MouseListener was registered. If you have a MouseListener registered on a Parent container, and which to get the coordinates of the MouseEvent relative to a child Component, you can using SwingUtilities to convert the coordinates
public void mousePressed(MouseEvent e){
Point childCoordinate = SwingUtilities.convertPoint(parent, e.getPoint(), child);
}
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 ...
I'm doing these iTunes Stanford classes, and I've been learning beginning Java. Things are going great, but they recently introduced events-and specifically MouseEvents. I've been reading the chapters in the book, and pouring through the example code, and something is just not clicking right for me...it's always that asynchronous stuff that gives me trouble :-D
Earlier, some people mentioned it was important that I mention that the "addMouseListener" is a class in the Graphics import. As far as I can tell, that just adds a blanket mouse listener to the canvas.
I'm still real new to this, so I may not be describing things as well as I should.
This is a piece of code that I have been trying to simplify in order to better understand it. Currently, it will build a red rectangle, and I can click on it and drag it along the x axis. Great!!!
import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;
/** This class displays a mouse-draggable rectangle and oval */
public class DragObject extends GraphicsProgram {
/* Build a rectangle */
public void run() {
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
addMouseListeners();
}
/** Called on mouse press to record the coordinates of the click */
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
/** Called on mouse drag to reposition the object */
public void mouseDragged(MouseEvent e) {
if((lastX) > 100){
gobj.move(e.getX() - lastX, 0);
lastX = e.getX();
lastY = e.getY();
}
}
/** Called on mouse click to move this object to the front */
public void mouseClicked(MouseEvent e) {
if (gobj != null) gobj.sendToFront();
}
/* Instance variables */
private GObject gobj; /* The object being dragged */
private double lastX; /* The last mouse X position */
private double lastY; /* The last mouse Y position */
}
If I drag the mouse off the canvas, I want the rectangle to stay within the canvas, and not move off it (the same behavior that a horizontal scroll bar would do if you moved beyond the scroll area with the mouse button still clicked). How can I do that?
I've been trying something along these lines, but it's not working right:
if ( ( lastX > (getWidth() - PADDLE_WIDTH) ) || ( lastX < PADDLE_WIDTH ) ) {
gobj.move(0, 0);
} else {
gobj.move(e.getX() - lastX, 0);
}
Your code is moving the rectangle relative to the last position of the mouse. This works fine when you are simply moving things, but for your needs when you want it to stop at the borders, you need to use absolute positioning.
// When the mouse is pressed, calculate the offset between the mouse and the rectangle
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
public void mouseDragged(MouseEvent e) {
double newX;
// Assuming you can get the absolute X position of the object.
newX = gobj.getX() + e.getX() - lastX;
// Limit the range to fall within your canvas. Adjust for your paddle width as necessary.
newX = Math.max( 0, Math.min( newX, getWidth() ) );
// Set the new position of the paddle, assuming you can set the absolute position.
gobj.setX( newX );
lastX = e.getX();
lastY = e.getY();
}
}
This may not be quite what you want because as soon as you go off the edge, the object will stop moving, but then once you move back toward the canvas, your paddle will move immediately instead of waiting for the mouse to reach the same relative position to the paddle at which it started.
You can probably experiment to get it to do what you want.
In order to do this you will need to know the width of the Canvas object, i'm sure there will be a method that will provide this value. You can then check the current x location of the MouseEvent against the width of the canvas, and not increment the x coordinates of the shape object once you are past the width of the canvas. Depending on how much of the shape you want to remain in the canvas, you may need to take into account the width of the shape object as well.
One thing that helps me when dealing w/ animation and moving objects in a gui is drawing out a few scenarios on paper, and noting how the coordinates change.