Klasa Robot


Z pewnością nie raz byliście w sytuacji, że chcielibyście napisać program, który sam wykonuje jakieś czynności na waszym komputerze - porusza kursorem, wypisuje jakiś tekst. Mogłoby się wydawać, że jest to skomplikowane i wymaga sięgnięcia po jakieś skomplikowane biblioteki, a tymczasem służy do tego jedna klasa - Robot. Możemy dzięki niej w bardzo prosty sposób obsługiwać klawiaturę oraz mysz, a także robić screenshoty i odczytywać informacje o pikselach.

Nie trudno sobie wyobrazić jak wielkie możliwości nam to daje - bez problemu można napisać prosty tasker, bota do gry, a nawet prostą wersję team viewera, lub program do zdalnego sterowania pulpitem.

Kurs Java

Najciekawsze metody, które znajdziemy w klasie Robot to:

  • keyPress(int keycode), keyRelease(int keycode) - wciśnięcie/zwolnienie klawisza na klawiaturze. Niestety minus jest taki, że keycode nie odpowiada wartości ASCII danego znaku trzeba się posługiwać wartościami stałych zdefiniowanych w klasie KeyEvent
  • mousePress(int buttons), mouseRelease(int buttons) - wciśnięcie/zwolnienie przycisków myszy - jako argumenty podajemy stałe zdefiniowane w klasie InputEvent (BUTTON1_MASK, BUTTON2_MASK, BUTTON3_MASK)
  • mouseMove(int x, int y) - przesunięcie kursora we wskazany punkt ekranu
  • createScreenCapture(Rectangle screenRect) - zrobienie screenshota ekranu w wybranym obszarze
  • delay(int time) - wstrzymanie wykonywanego wątku na czas podany jako argument (w milisekundach)

Oprócz tego klasa Robot zawiera kilka innych metod - ale nie będziemy się nimi zajmować, zainteresowani mogą je zobaczyć w dokumentacji.

Zobaczmy prosty przykład tego jak można ją wykorzystać w jakimś przykładzie. Napiszmy program, który napisze używając klawiatury "Hello World", następnie wykona screena ekranu i zapisze go na dysku. - jest na tyle prosty, że wszystko zmieści nam się w jednej klasie.

import java.awt.AWTException;
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.awt.Robot;
 import java.awt.Toolkit;
 import java.awt.event.KeyEvent;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 
 import javax.imageio.ImageIO;
 
 public class RobotTest {
 	Robot robot;
 
 	public RobotTest() {
 		try {
 			robot = new Robot();
 		} catch (AWTException e) {
 			System.err.println("Co ten robot wyprawia?!");
 			e.printStackTrace();
 		}
 	}
 
 	/**
 	 * Metoda drukuje tekst "Hello World"
 	 */
 	public void printText() {
 		int[] text = {KeyEvent.VK_H, KeyEvent.VK_E, KeyEvent.VK_L, KeyEvent.VK_L, KeyEvent.VK_O, KeyEvent.VK_SPACE,
 				KeyEvent.VK_W, KeyEvent.VK_O, KeyEvent.VK_R, KeyEvent.VK_L, KeyEvent.VK_D};
 		//pętla - wciśnięcie przycisku i przerwa na 200ms
 		for(int i=0; i<text.length; i++) {
 			robot.keyPress(text[i]);
 			robot.delay(200);
 		}
 	}
 
 	/**
 	 * Metoda robi screenshot ekranu i zapisuje go na dysku
 	 */
 	public void screenCapture() {
 		//pobieramy rozmiar ekranu i tworzymy Rectangle
 		Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
 		Rectangle rectangle = new Rectangle(dimension);
 		//robimy screenshot z utworzonego obszaru
 		BufferedImage screen = robot.createScreenCapture(rectangle);
 		try {
 			ImageIO.write(screen, "jpg", new File("screenshot.jpg"));
 		} catch (IOException e) {
 			System.err.println("Błąd zapisu obrazu");
 			e.printStackTrace();
 		}
 	}
 
 	/**
 	 * Testujemy czy działa
 	 */
 	public static void main(String[] args) {
 		RobotTest test = new RobotTest();
 		test.robot.delay(3000);
 		test.printText();
 		test.screenCapture();
 	}
 
 }

Przykład w zasadzie ma odpowiednie komentarze więc nie ma wiele do omówienia. Stworzyliśmy dwie metody odpowiedzialne za funkcje programu: printText() , które wydrukuje nam "Hello World", screenCapture() , która zrobi zrzut ekranu. Dodatkowo wykorzystano metodę delay() z klasy Robot, aby wstrzymać działanie programu - najpierw na 3 sekundy przed wydrukowaniem tekstu (abyśmy mogli sobie np kliknąć w notatniku i zobaczyli, że faktycznie napis się tam będzie pojawiał), a później na 200 milisekund pomiędzy kolejnymi "wciśnięciami" klawiszy.

W przypadku przechwytywania obrazu z pulpitu najpierw pobieramy rozmiar ekranu przy pomocy getScreenSize() klasy Toolkit (zawiera ona także dużo innych ciekawych informacji systemowych). Obraz możemy też zapisać w formacie .png zmieniając rozszerzenie w metodzie write z klasy ImageIO - powinniśmy wtedy uzyskać lepszą jakość.

Klasa robot w javie

Poniżej znajdziesz dodatkowo kod z filmu u góry tej strony.

import java.awt.*;
import java.awt.event.InputEvent;

public class Main {

    public static void main(String[] args) throws AWTException, InterruptedException {

        Robot robot = new Robot();

        Color green = new Color(75, 219, 106);

        int x = 500;
        int y = 400;

        while (true) {
            Color pixelColor = robot.getPixelColor(x, y);
            if(pixelColor.equals(green)) {
                robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
            }
        }

    }
}

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.

Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.

del

Genialne! Dzięki wielkie, jak możesz to rozbudować to czekam z niecierpliwością, Ewentualnie możesz podać inne tego typu ciekawostki dotyczące Javy? Chętnie poczytam. Pozdrawiam.

darQ

Myślę, że po wciśnięciu przycisku należałoby jeszcze go puścić ;) Zaraz pod kodem ze wciśnięciem można śmiało dodać puszczenie takiego przycisku. Czyli... ... for(int i=0; i&lt;text.length; i++) { robot.keyPress(text[i]); robot.keyRelease(text[i]); // DODANY RELASE ! robot.delay(200); } ... Dlaczego? Jedna JVM drugiej nie równa i mogą się różne rzeczy dziać ;)

fsdfsdf

Nie działa na przeglądarkach(np. wciśnięcie buttona). Wie ktoś jak zrobić, aby działało?

darQ

Użyłem dwóch (DWÓCH) metod: wciśnięcie i zwolnienie przycisku i... działa. W przeglądarce. Na buttonach, w obiektach flashowych itp. Sprecyzuj problem. P.S. Najprostszy przykład - gdy element znajduje się w pozycji 500,400 od lewego górnego rogu ekranu: ... Thread.sleep(4000); // Daj sobie czas na alt+taba do przeglądarki (oczywiście 'sen' w try-catch'u) robot.mouseMove(500, 400); //Przesuwamy myszkę robot.mousePress(MouseEvent.BUTTON1_MASK); // Wciskami button 1 robot.mouseRelease(MouseEvent.BUTTON1_MASK); // Puszczamy button 1 ...

Sławek Ludwiczak

Bez Release też powinno działać, bo napisałem w ten sposób bota, który wygrał w konkursie nagrodę ;) Chociaż jak najbardziej warto ją dodać i dzięki za zwrócenie uwagi (warto też dodać krótki delay pomiędzy tymi operacjami).

walden

Mi bez Release w konsoli cmd wyświetlało tylko 'helo world' - zjadało jedną literkę 'l', w notatniku normalnie.

barwnikk

keyPress naciska i spuszcza klawisz. A jak zrobić, aby przytrzymało mi spacje przez 5 sek? to mi nie działa: Robot r = new Robot(); r.keyPress(KeyEvent.VK_SPACE); r.delay(5000); r.keyRelease(KeyEvent.VK_SPACE); W programie (notatniku) tylko widać jedną spację, ale shift trzyma...

bartesk

Tez to miale. pomoglo jak przy zapisywaniu obrazu wpisalem konkretny adres np. "D://screenshot.jpg" ImageIO.write(screen, "jpg", new File("D://screenshot.jpg"));