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 grupe 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"));