A) Robot – JDK 1.3

Anders, als es vielleicht viele denken, sind in Java – trotz der Plattformunabhängigkeit – auch Operationen wie das Simulieren eines Tastendrucks oder eines Mausklicks möglich. Hierzu dient die Klasse java.awt.Robot. Es ist also möglich Tastatureingaben und Maussteuerung zu simulieren und so z. B. eine Demo-Programmsteuerung zu implementieren. In diesem Kapitel werden wir uns diese Klasse etwas näher ansehen.

Als erstes müssen Sie sich ein Objekt der Klasse Robot über das new-Schlüsselwort erzeugen. Sie haben zwei Konstruktoren zur Auswahl:

  • Robot()
  • Robot(GraphicsDevice screen)

Wir verwenden die erste Methode. Bei der Zweiten könnten Sie noch eine GraphicsDevice übergeben und somit auf ein anderes Koordinatensystem verweisen. Beim Erzeugen einer neuen Robot-Instanz kann eine AWTException geworfen werden, falls die Plattform keine Kontrolle von low-level-Eingaben (also Tastatur-, Mauseingaben, …) erlaubt, oder die Anwendung im Headless-Modus läuft. Eine SecurityException wird geworfen, falls es nicht gestattet ist einen neuen Robot zu erzeugen. Letztere Exception muss nicht abgefangen werden, so dass sich für die Initialisierung folgender Code ergibt:

java.awt.Robot r = null;
try {
  r = new java.awt.Robot();
} 
catch (AWTException e) {
  e.printStackTrace();
}

Sehen wir uns nun die Möglichkeiten mit Robot an.

Einen Screenshot erstellen

Sie haben die Möglichkeit ein Abbild des aktuellen Bildschirms bzw. eines bestimmten Bereichs davon zu machen. Hierzu rufen Sie die Methode robot.createScreenCapture(java.awt.Rectangle rect); auf. Das java.awt.Rectangle repräsentiert den Bereich, der aufgenommen werden soll – bspw: robot.createScreenCapture(new java.awt.Rectangle(50, 100, 400, 400)); um einen Screenshot an Position x=50, y=100 und mit Breite=400, Höhe=200 zu erzeugen. Der so generierte Screenshot wird in Form eines BufferedImage zurückgegeben, welches weiter verarbeitet werden kann. Sehen wir uns ein kleines Beispiel an, in welchem ein Screenshot geschossen, und im gleichen Verzeichnis gespeichert wird.

Auf die Verwendung von BufferedImage und die Speicherung des Bildes soll an dieser Stelle nicht eingegangen werden.

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class RobotTest {

  public static void main(String[] args) {
		
    Robot robot = null;
    try {
      robot = new Robot();
    } 
    catch (AWTException e) {
      e.printStackTrace();
    }
    BufferedImage img = robot.createScreenCapture(new Rectangle(50, 100, 400, 200));
    try {
      ImageIO.write(img, "png", new File("./screenshot.png"));
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }
	
}

Die Methode createScreenCapture wirft eine IllegalArgumentException, wenn die Höhe oder die Breite des Screenshotbereichs kleiner-gleich 0 ist, und eine SecurityException, falls die readDisplayPixels Erlaubnis nicht erteilt wurde.

Die Maus fernsteuern

Eines der wichtigsten Features der Robot-Klasse ist die Fernsteuerung der Maus. Mit Ihr kann der Mauszeiger zu einer bestimmten Position am Bildschirm bewegt (mouseMove(int x, int y)), eine Maustaste gedrückt (mousePress(int button)) und wieder losgelassen (mouseRelease(int button)), oder das Mausrad betätigt (mouseWheel(int wheelAmt)) werden.

Um den Mauszeiger zu bewegen, genügt es die gewünschten Koordinaten anzugeben (z. B. robot.mouseMove(0, 0);). Die Methoden mousePress und mouseRelease gehören unmittelbar zusammen, da eine Maustaste, die gedrückt wurde, auch wieder losgelassen werden muss. Als Parameter wird der zu drückende Mausbutton übergeben – entweder java.awt.event.MouseEvent.BUTTON1_MASK, java.awt.event.MouseEvent.BUTTON2_MASK oder java.awt.event.MouseEvent.BUTTON3_MASK (z. B. robot.mousePress(MouseEvent.BUTTON1_MASK);). Um das Scrollrad zu betätigen, rufen Sie mouseWheel mit der gewünschten Anzahl an „Anschlägen“, die gescrollt werden sollen, auf. Positive Werte bedeuten „nach unten“ bzw. „zum User hin“, negative Werte „nach oben“ bzw. „vom User weg“ (z. B. robot.mouseWheel(5);).

Sehen wir uns ein kleines Beispiel an. Der Mauszeiger soll in die obere, linke Ecke bewegt, und ein einfacher Klick mit der linken Maustaste ausgeführt werden. Unter Windows-Systemen würde das bei einem maximierten Fenster bedeuten, dass ein kleines Fenster-Kontext-Menü geöffnet wird.

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.MouseEvent;

public class RobotTest {

  public static void main(String[] args) {
		
    Robot robot = null;
    try {
      robot = new Robot();
    } 
    catch (AWTException e) {
      e.printStackTrace();
    }
    robot.mouseMove(0, 0);
    robot.mousePress(MouseEvent.BUTTON1_MASK);
    robot.mouseRelease(MouseEvent.BUTTON1_MASK);
  }
}

Sollte ein „illegaler“ int-Wert übergeben werden, wird eine IllegalArgumentException ausgelöst.

Tasten drücken

Auch das simulierte Betätigen einer Taste wird häufig benötigt. Robot bietet die Möglichkeit eine Taste zu drücken (keyPress(int keycode)) und wieder loszulassen (keyRelease(int keycode)). Genauso wie bei der Fernsteuerung der Maus, muss auch hier eine gedrückte Taste später wieder losgelassen werden. Die zu übergebenden KeyCodes beziehen Sie sich aus der Klasse java.awt.KeyEvent.

Zur Veranschaulichung sehen Sie sich den Code an, der den Tastendruck von STRG+V simuliert, welcher standardmäßig etwas aus der Zwischenablage einfügt (natürlich sollten Sie zum Testen auch einen Text in die Zwischenablage kopieren, und beim Starten des Programms einen entsprechenden Texteditor im Vordergrund haben, in welchem der Text eingefügt werden kann).

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

public class RobotTest {

  public static void main(String[] args) {
		
    Robot robot = null;
    try {
      robot = new Robot();
    } 
    catch (AWTException e) {
      e.printStackTrace();
    }
    robot.keyPress(KeyEvent.VK_CONTROL);
    robot.keyPress(KeyEvent.VK_V);
    robot.keyRelease(KeyEvent.VK_V);
    robot.keyRelease(KeyEvent.VK_CONTROL);
  }
}

Sollte ein „illegaler“ int-Wert übergeben werden, wird eine IllegalArgumentException ausgelöst.

Wartezeit

Sie haben mehrere Möglichkeiten das Programm bzw. den aktuellen Thread zu pausieren. Diese Methoden werden Ihnen nachfolgend Stichpunktartig aufgelistet.

  • delay(int ms) => pausiert das Programm für die angegebene Zeit an Millisekunden (Minimal 0, Maximal 60.000).
  • setAutoDelay(int ms) bzw. zur Abfrage getAutoDelay() => pausiert das Programm nach jedem ausgelösten Event durch den Robot (z. B. durch die Betätigung einer Maustaste) für die angegebene Zeit an Millisekunden (Minimal 0, Maximal 60.000).
  • waitForIdle() => wartet, bis alle Ereignisse, die sich momentan in der event queue befinden, abgearbeitet wurden.
  • setAutoWaitForIdle(boolean isOn) bzw. zur Abfrage isAutoWaitForIdle() => führt nach jedem, durch Robot erzeugtem, Event automatisch die Methode waitForIdle() aus.

Lassen Sie Ihren Robot nun Testweise eine Maustaste drücken, 500 Millisekunden warten, die Maustaste wieder loslassen, und ein weiteres Mal 500 Millisekunden warten. Die aktuelle Zeit wird dabei über ein System.out.println mit dem Wert System.currentTimeMillis() zwischenzeitlich immer ausgegeben.

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.MouseEvent;

public class RobotTest {

  public static void main(String[] args) {
		
    Robot robot = null;
    try {
      robot = new Robot();
    } 
    catch (AWTException e) {
      e.printStackTrace();
    }
    robot.setAutoDelay(500);
    System.out.println(System.currentTimeMillis());
    robot.mousePress(MouseEvent.BUTTON1_MASK);
    System.out.println(System.currentTimeMillis());
    robot.mouseRelease(MouseEvent.BUTTON1_MASK);
    System.out.println(System.currentTimeMillis());
  }
}

Die Farbe eines Pixels auslesen

Durch Robot mit der Methode getPixelColor(int x, int y) wird es ebenfalls möglich die Farbe eines bestimmten Pixels auf dem Bildschirm auszulesen. Es werden einfach die gewünschten Koordinaten übergeben, und schon erhält man die Farbe in Form eines java.awt.Color Objekts. In Kombination mit den Klassen java.awt.MouseInfo und java.awt.PointerInfo (welche an dieser Stelle nicht weiter besprochen werden) ist es seit Java 1.5 z. B. möglich, alle 500 Millisekunden die Farbe des Pixels, auf welchem momentan die Maus zeigt, auszugeben.

import java.awt.AWTException;
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;

public class RobotTest {

  public static void main(String[] args) {
		
    Robot robot = null;
    try {
      robot = new Robot();
    } 
    catch (AWTException e) {
      e.printStackTrace();
    }
    while (true) {
      Point p = MouseInfo.getPointerInfo().getLocation();
      Color c = robot.getPixelColor(p.x, p.y);
      System.out.println("Red: " + c.getRed() + 
        ", Green: " + c.getGreen() + 
        ", Blue: " + c.getBlue());
      robot.delay(500);
    }
  }
}
Previous Article
Next Article

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.