How do I move the mouse cursor (windows) with Java?
I have a pair of values constantly being updated. I want to use them to control the cursor.
Robot.mouseMove(x,y)
As mentioned in:
https://stackoverflow.com/a/2941373/1150918 by OscarRyz.
You will need to use the Robot class.
Robot r = null;
try {
r = new Robot();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
r.mouseMove(x, y);//x is the horizontal position on the screen, y is the vertical
Related
Using Selenium Webdriver to take screenshot for specific UI Element as suggested by other post, I am using getSubimage method to capture the screenelement. But, receiving failure exception.
I am unsure about the difference in uielement's getLocation().getX() and getSize().getWidth().getX(). If someone can clarify this, as inside the WritableRaster method's condition it always checks for y+height
File imgSrc=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
Point point = uiElem.getLocation();
Point bottomright = new Point(uiElem.getSize().getWidth(),
uiElem.getSize().getHeight());
int xcord = point.getX();
int ycord = point.getY();
BufferedImage img;
try {
img = ImageIO.read(imgSrc);
BufferedImage dest = img.getSubimage(xcord, ycord, bottomright.getX(), bottomright.getY());
ImageIO.write(dest, "png", imgSrc);
FileUtils.copyFile(imgSrc, new File(".\\Screenshots\\123.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
While debugging, I noticed that the img (width 1366 and height = 613). and getSubImage() has (194,1335,960,15). It will always fail for condition (y+ height) >(this.minY + this.height ) inside createWritableChildMethod. So,can anyone point,where it's going wrong, also it doesn't make sense , as why we adding (y+height)of sub-image is greater?
Found a workaround, just notices it's better to use getScreenshotAs() directly on UIElement without doing alot of manipulation on the element.
public void takeSmallScreenshot(WebDriver driver, WebElement uiElem)
{
File uiElementSrc = uiElem.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(uiElementSrc, new File(".\\Screenshots\\"+uiElem.getText().substring(0,5)+".png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm trying to write a program that would bring the mouse cursor to certain coordinates, according to timings, regardless of the user. I wrote a simple code using Robot, but ran into a problem ... I have two monitors, and the cursor moves incorrectly depending on what monitor it is on at the moment, please tell me how to solve the problem.
The code below is what I was trying to create ...
GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] graphicsDevices = graphicsEnvironment.getScreenDevices();
for(int i=0; i < graphicsDevices.length; i++)
{
System.out.println(graphicsDevices[i]);
}
try {
//Robot robot = new Robot(MouseInfo.getPointerInfo().getDevice());
Robot robot = new Robot();
while(true)
{
robot.mouseMove(-1640, -3);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(10000);
}
} catch (Exception e) {
e.printStackTrace();
}
You should work with the idea of get the resolution and then move from there. You are doing ABSOLUTE moves and they will work different in differents setups.
You should use this code
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int width = gd.getDisplayMode().getWidth();
int height = gd.getDisplayMode().getHeight();
from there you could:
Robot robot = new Robot();
robot.mouseMove (width-10, height+3);
So you would move relatively to the specs of the monitor. I hope I have helped.
I tried looking up this question, but most of the answers are that the file path is wrong, but that's most likely not the case. The file works the 1st time I use it.
I am making a battleships game, and use JLabels to show ships on map. I want to make a button to rotate ship from horizontal to vertical but it's icon disappears when I try to change it.
When I run this constructor code:
public Ship(int size, String direction, boolean active, Client c,
ClientGUI cg) {
this.c = c;
this.cg = cg;
health = size;
this.active = active;
this.direction = direction;
file = "img/" + Integer.toString(health) + direction + ".png"; // String
try {
System.out.println(file);
tx = ImageIO.read(new File(file)); // BufferedImage
} catch (IOException e) {
e.printStackTrace();
}
texture = new JLabel(new ImageIcon(tx));
if (direction.equals("v"))
texture.setBounds(0, 0, 40, 40 * size);
else
texture.setBounds(0, 0, 40 * size, 40);
texture.setVisible(true);
}
everything works and I can see the image.
But then I try to rotate it, using pretty much the same code:
void rotate() {
if (direction.equals("h")) {
direction = "v";
file = "img/" + Integer.toString(health) + direction + ".png";
try {
System.out.println(file);
tx = ImageIO.read(new File(file));
} catch (IOException e) {
e.printStackTrace();
}
texture.setBounds(0,0,40, 40 * size);
texture.setIcon(new ImageIcon(tx));
} else {
direction = "h";
file = "img/" + Integer.toString(health) + direction + ".png";
try {
System.out.println(file);
tx = ImageIO.read(new File(file));
} catch (IOException e) {
e.printStackTrace();
}
texture.setIcon(new ImageIcon(tx));
texture.setBounds(0,0,40 * size, 40);
}
cg.repaint(); // not sure if I need to do this
}
and it disappears...
I tried placing two ships, one is rotated, it's just missing the JLabel or the icon on JLabel.
If you update the JLabel texture by calling a method which changes it's state, it may or may not be updated immediately unless you call texture.repaint() or texture.paintAll(texture.getGraphics()), or some similar method.
Also, I would look into using a LayoutManager for whatever upper level component you are using to hold your grid of JLabels. If you use a GridLayout of your game board and either:
set the JLabel's preferred size with texture.setPreferredSize(Dimension) and call frame.pack() once when setting up your game; or
set the JLabel's size with label.setSize(Dimension) once and don't pack your JFrame
You will only need to set the size of the JLabel once, not every time you set a new ImageIcon to the label. Because, Ideally your game shouldn't be doing any extra work that it doesn't have to so it performs faster.
I would also recommend maintaining every possible ImageIcon as static fields in your class, rather than accessing them from the file every time. That way, you read them once from a static initializing method, which then reach ship can directly access when changing the direction.
I want to make a button to rotate ship from horizontal to vertical
You can use the Rotated Icon class to do the rotation for you.
I am a beginner in java, and I am trying to write a simple screen-capture program. I wrote a simple SWING desktop app with a button and a text-field, and what I am trying to do is, when a user clicks that button the app takes a snapshot of the screen using awt.Robot, and sends that image and the text to a PHP script on my server.
My snapshot function so far is:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = new File("screenshot_full.png");
ImageIO.write(bufferedImage, "png", file);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
As you can see it's fairly simple so far, however I am not sure how to send that image to my PHP script without actually storing the image on user's PC.
Oh and I am using apache httpClient library for communicating to the web server. For the text I guess I can pass it in the URL as a get query, but I am not sure what to do about the image.
ImageIO.write can to an OutputStream of your choice.
So if you don't want to write the image to a File, you can simply write it to a different stream instead...
For example...
OutputStream os = null;
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
os = ...;
ImageIO.write(bufferedImage, "png", os);
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
os.close();
} catch (Exception exp) {
}
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
Of course, I have no idea where you're sending the data, so you'll need to define the OutputStream yourself.
If you have the memory for it, you could write it a ByteArrayOutputStream and then write this to whatever output stream you need in the future...
To slightly modify your existing method, perhaps you could use a temporarily file and then delete it when you are finished with it. Perhaps it might look something like:
private void takeSnapShot(){
try {
Robot robot = new Robot();
Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage bufferedImage = robot.createScreenCapture(area);
//Try to save the captured image
try {
File file = File.createTempFile(Long.toString(System.currentTimeMillis()), ".png");
ImageIO.write(bufferedImage, "png", file);
//send image
file.delete();
} catch (IOException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (AWTException ex) {
Logger.getLogger(ScrCaptFrm.class.getName()).log(Level.SEVERE, null, ex);
}
}
Another alternative would be to construct an int[][] from your BufferedImage which will hold the RGB values for every pixel of the image:
public int[][] getColors(final BufferedImage image){
assert image != null;
final int[][] colors = new int[image.getWidth()][image.getHeight()];
for(int x = 0; x < colors.length; x++)
for(int y = 0; y < colors[x].length; y++)
colors[x][x] = image.getRGB(x, y);
return colors;
}
I am a little unsure about what you hope to achieve; What do you plan on doing with the image?
Why don't you make this a WebsService and let your PHP consume it? You could send the binary data through the WebsService using some sort of Base64 encoder.
You could do this to get the bytes of the BufferedImage:
byte[] binaryData = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();
I use the following lines to simulate a Control_A [ select all ] key action in Java with robot, but the clipboard is not getting the text, why ?
Robot robot=null;
try { robot=new Robot(); }
catch (AWTException ex) { System.err.println("Can't start Robot: " + ex); }
robot.mouseMove(260,500);
robot.mousePress(InputEvent.BUTTON1_MASK);
// robot.mouseMove(660,700);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.keyPress(KeyEvent.VK_CONTROL); // Select all
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_CONTROL); // Copy
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
Transferable t=Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
try
{
if (t!=null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
{
String text=(String)t.getTransferData(DataFlavor.stringFlavor);
System.out.println(text);
}
}
catch (Exception ex) { ex.printStackTrace(); }
I have a browser open so at [260,500] on screen there is text at that area. What have I missed ?
Edit:
I just found something strange, when I opened a browser, the text in the browser is not copies, but if I open a notepad/wordpad, the text in them will be copies, so why the browser didn't do it ?
All of your code should be inside the try block where you instantiate the Robot because you could end up trying to work with a null reference and get a NullPointerException. And if your Robot never got created and never copied contents, there'd be no point in you trying to access the contents from the clipboard either.
I'm not entirely sure why but adding a small delay before trying to read from the clipboard fixes things. I'm guessing it might have to do with a race condition between Java getting hold of the clipboard before the system has had time to update it.
This updated code should work:
Robot robot = null;
try
{
robot = new Robot();
robot.mouseMove(260, 500);
robot.mousePress(InputEvent.BUTTON1_MASK);
// robot.mouseMove(660,700);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.keyPress(KeyEvent.VK_CONTROL); // Select all
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_CONTROL); // Copy
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
try
{
//sleep just a little to let the clipboard contents get updated
Thread.sleep(25);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
try
{
if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
{
String text = (String) t.getTransferData(DataFlavor.stringFlavor);
System.out.println(text);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
catch (AWTException ex)
{
System.err.println("Can't start Robot: " + ex);
}
Not sure of your code context but I had the same problem trying to extract the text from a PDF document on the browser.
It was misleading because the ctrl-a was highlighting the text but ctlr-c copied nothing. My solution was first to simulate a click anywhere on the document first, then ctrl-a and ctrl-c. My code:
robot = new Robot();
//Get window size
Dimension d = driver.manage().window().getSize();
System.out.println("Dimension x and y :"+d.getWidth()+" "+d.getHeight());
int x = (d.getWidth()/4)+20;
int y = (d.getHeight()/10)+50;
robot.mouseMove(x,y);
//Clicks Left mouse button
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(25);
// Select all
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_CONTROL);
Thread.sleep(100);
// Copy to clipboard
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_C);
robot.keyRelease(KeyEvent.VK_CONTROL);
Thread.sleep(100);
Hope this helps.