Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Neues in Java 8 und Java 7
2 Fortgeschrittene String-Verarbeitung
3 Threads und nebenläufige Programmierung
4 Datenstrukturen und Algorithmen
5 Raum und Zeit
6 Dateien, Verzeichnisse und Dateizugriffe
7 Datenströme
8 Die eXtensible Markup Language (XML)
9 Dateiformate
10 Grafische Oberflächen mit Swing
11 Grafikprogrammierung
12 JavaFX
13 Netzwerkprogrammierung
14 Verteilte Programmierung mit RMI
15 RESTful und SOAP-Web-Services
16 Technologien für die Infrastruktur
17 Typen, Reflection und Annotationen
18 Dynamische Übersetzung und Skriptsprachen
19 Logging und Monitoring
20 Sicherheitskonzepte
21 Datenbankmanagement mit JDBC
22 Java Native Interface (JNI)
23 Dienstprogramme für die Java-Umgebung
Stichwortverzeichnis

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java SE 8 Standard-Bibliothek von Christian Ullenboom
Das Handbuch für Java-Entwickler
Buch: Java SE 8 Standard-Bibliothek

Java SE 8 Standard-Bibliothek
Pfeil 11 Grafikprogrammierung
Pfeil 11.1 Grundlegendes zum Zeichnen
Pfeil 11.1.1 Die paint(Graphics)-Methode für das AWT-Frame
Pfeil 11.1.2 Die ereignisorientierte Programmierung ändert Fensterinhalte
Pfeil 11.1.3 Zeichnen von Inhalten auf ein JFrame
Pfeil 11.1.4 Auffordern zum Neuzeichnen mit repaint(…)
Pfeil 11.1.5 Java 2D-API
Pfeil 11.2 Einfache Zeichenmethoden
Pfeil 11.2.1 Linien
Pfeil 11.2.2 Rechtecke
Pfeil 11.2.3 Ovale und Kreisbögen
Pfeil 11.2.4 Polygone und Polylines
Pfeil 11.3 Zeichenketten schreiben und Fonts
Pfeil 11.3.1 Zeichenfolgen schreiben
Pfeil 11.3.2 Die Font-Klasse
Pfeil 11.3.3 Font-Metadaten durch FontMetrics *
Pfeil 11.4 Geometrische Objekte
Pfeil 11.4.1 Die Schnittstelle Shape
Pfeil 11.4.2 Pfade *
Pfeil 11.5 Das Innere und Äußere einer Form
Pfeil 11.5.1 Farben und die Paint-Schnittstelle
Pfeil 11.5.2 Farben mit der Klasse Color
Pfeil 11.5.3 Composite und XOR *
Pfeil 11.5.4 Dicke und Art der Linien von Formen bestimmen über Stroke *
Pfeil 11.6 Bilder
Pfeil 11.6.1 Eine Übersicht über die Bilder-Bibliotheken
Pfeil 11.6.2 Bilder mit ImageIO lesen
Pfeil 11.6.3 Ein Bild zeichnen
Pfeil 11.6.4 Splash-Screen *
Pfeil 11.6.5 Bilder skalieren *
Pfeil 11.6.6 Schreiben mit ImageIO
Pfeil 11.6.7 Asynchrones Laden mit getImage(…) und dem MediaTracker *
Pfeil 11.7 Weitere Eigenschaften von Graphics *
Pfeil 11.7.1 Eine Kopie von Graphics erstellen
Pfeil 11.7.2 Koordinatensystem verschieben
Pfeil 11.7.3 Beschnitt (Clipping)
Pfeil 11.7.4 Zeichenhinweise durch RenderingHints
Pfeil 11.7.5 Transformationen mit einem AffineTransform-Objekt
Pfeil 11.8 Drucken *
Pfeil 11.8.1 Drucken der Inhalte
Pfeil 11.8.2 Bekannte Drucker
Pfeil 11.9 Benutzerinteraktionen automatisieren, Robot und Screenshots *
Pfeil 11.9.1 Der Roboter
Pfeil 11.9.2 Automatisch in die Tasten hauen
Pfeil 11.9.3 Automatisierte Maus-Operationen
Pfeil 11.9.4 Methoden zur Zeitsteuerung
Pfeil 11.9.5 Bildschirmabzüge (Screenshots)
Pfeil 11.9.6 Funktionsweise und Beschränkungen
Pfeil 11.9.7 MouseInfo und PointerInfo
Pfeil 11.10 Zum Weiterlesen
 
Zum Seitenanfang

11.9Benutzerinteraktionen automatisieren, Robot und Screenshots * Zur vorigen ÜberschriftZur nächsten Überschrift

Eine besondere Eigenschaft von Präsentationsprogrammen ist die Tatsache, dass Benutzerinteraktionen wie von Zauberhand automatisch vom System vorgenommen werden. Ein Programm kann beispielsweise die Interaktion mit der Maus oder der Tastatur aufnehmen und zu einem späteren Zeitpunkt abspielen. Weitere Nutzer sind GUI-Testwerkzeuge wie FEST-Swing (https://code.google.com/p/fest/), die Benutzerinteraktionen automatisieren.

 
Zum Seitenanfang

11.9.1Der Roboter Zur vorigen ÜberschriftZur nächsten Überschrift

Genau für diese Art der Oberflächensteuerung gibt es die Klasse Robot im Paket AWT. Sie verwaltet eine mit Aktionen gefüllte Ereigniswarteschlange. Die Aktionen werden nacheinander abgearbeitet.

class java.awt.Robot
  • void keyPress(int keycode)
    Drückt eine Taste.

  • void keyRelease(int keycode)
    Lässt die Tasten wieder los.

  • void mouseMove(int x, int y)
    Bewegt die Maus auf die Koordinate relativ zum aktuellen Fenster.

  • void mousePress(int buttons)
    Aktiviert eine oder mehrere Maustasten.

  • void mouseRelease(int buttons)
    Lässt die Maustaste wieder los.

  • void delay(int ms)
    Wartet Millisekunden. Mehr als 60 Sekunden sind nicht möglich; die Strafe wäre eine IllegalArgumentException.

 
Zum Seitenanfang

11.9.2Automatisch in die Tasten hauen Zur vorigen ÜberschriftZur nächsten Überschrift

Bei den Methoden keyPress(int), keyRelease(int), mousePress(int) und mouseRelease(int) ist der int-Parameter erklärungsbedürftig. Der Parameter keycode ist der erste, der beachtet werden muss.

[zB]Beispiel

Der Roboter legt Tastendrücke in die Ereignisschlange:

Robot rob = new Robot();
rob.keyPress( KeyEvent.VK_SHIFT );
rob.keyPress( KeyEvent.VK_U );
rob.keyPress( 'I' );
rob.keyPress( '0' ); rob.keyPress( '0' ); rob.keyPress( '7' );
rob.keyRelease( KeyEvent.VK_SHIFT );
rob.keyPress( KeyEvent.VK_ENTER );

Wird das Programmstück in einer grafischen Applikation genutzt, muss sichergestellt sein, dass die Tasten auch die passende Komponente erwischen. Liegt der Fokus zum Beispiel auf einem Rollbalken, werden diese Tastendrücke natürlich ohne Wirkung bleiben. Aus diesem Grund ist es angebracht, in Swing mit requestFocus() den Fokus zu setzen.

Das Argument von keyPress(int) und keyRelease(int) ist eine Konstante der Klasse KeyEvent. Neben den alphanumerischen Tasten auf der Tastatur finden sich unter anderem Konstanten für Funktionstasten, Metatasten, Cursor-Tasten und weitere Sonderzeichen. Die Konstanten für Großbuchstaben und Ziffern decken sich mit den ASCII-Zeichen und können daher alternativ verwendet werden. Bei fast allen Sonderzeichen entspricht die Konstante dem ASCII-Code, doch ist dies nicht selbstverständlich. Die Kleinbuchstaben (ab 0x61) werden zum Beispiel auf den 10er-Block abgebildet (ab 0x60). Ist der übergebene Keycode undefiniert (durch die Konstante KeyEvent.VK_UNDEFINED vorgegeben), so erzeugt der Roboter eine IllegalArgumentException.

Um die Umschalttaste während der Automatisierung einzuschalten, nutzen wir die Methode keyPress(KeyEvent.VK_SHIFT) und lösen die Tasten mit keyRelease(int). Das Beispiel macht deutlich, dass das Freigeben nur für Operationen, wie zum Beispiel Umschalttaste, VK_ALT und VK_ALT_GRAPH nötig ist, allerdings nicht für normale Buchstaben.

 
Zum Seitenanfang

11.9.3Automatisierte Maus-Operationen Zur vorigen ÜberschriftZur nächsten Überschrift

Jetzt fehlen uns noch die Methoden mousePress(int) und mouseRelease(int). Beide erhalten als Argument eine Konstante der Klasse InputEvent: entweder BUTTON1_MASK, BUTTON2_MASK oder BUTTON3_MASK oder eine Kombination aus den dreien wie BUTTON2_MASK | BUTTON3_MASK.

[zB]Beispiel

Aktiviere die (meist linke) Maustaste, warte eine Sekunde, und lass die Maustaste wieder los:

rob.mousePress( InputEvent.BUTTON1_MASK );
rob.delay( 1000 );
rob.mouseRelease( InputEvent.BUTTON1_MASK );

Wenn die Mausaktion eine Komponente treffen soll, dann gilt das Gleiche wie für Tastendrücke. Nur muss hier der Fokus nicht auf der Komponente liegen, sondern die Mauskoordinaten müssen auf die Komponente zeigen. Damit die Bildschirmkoordinate einer Komponente ausgelesen werden kann, bietet Component eine Methode getLocationOnScreen() an, die ein Point-Objekt mit den Startkoordinaten liefert. Diese können mit einem kleinen Offset an mouseMove(int, int) weitergereicht werden. Dann befindet sich der Zeiger über der Komponente, und mousePress(int) kann seine Wirkung nicht mehr verfehlen.

 
Zum Seitenanfang

11.9.4Methoden zur Zeitsteuerung Zur vorigen ÜberschriftZur nächsten Überschrift

Einige Methoden der Klasse Robot steuern Verzögerungen:

class java.awt.Robot
  • void setAutoDelay(int ms)
    Die Robot-Klasse sendet zum Abspielen Ereignisse an die Oberfläche. Diese Methode setzt die Dauer der Verzögerung fest, die nach dem Ereignis vergehen soll. Mehr als 60 Sekunden sind auch hier nicht gültig.

  • int getAutoDelay()
    Liefert die Zeit, die nach dem Ereignisaufruf vergehen soll.

  • void waitForIdle()
    Wartet, bis alle Ereignisse in der Warteschlange bearbeitet sind.

  • void setAutoWaitForIdle(boolean isOn)
    Ist isOn = true, wird waitForIdle() nach einem Ereignis aufgerufen.

  • boolean isAutoWaitForIdle()
    Liefert true, falls der Robot automatisch waitForIdle() nach einem Ereignis aufruft.

 
Zum Seitenanfang

11.9.5Bildschirmabzüge (Screenshots) Zur vorigen ÜberschriftZur nächsten Überschrift

Eine sehr interessante Methode der Robot-Klasse ist createScreenCapture(Rectangle). Mit ihr lässt sich ein Bildschirmabzug (engl. screenshot) ohne Mauszeiger (zumindest unter Windows, Linux, Solaris und Mac OS X) machen. Die Methode createScreenCapture(Rectangle) erwartet als Argument ein Rechteck (speichert x, y, height und width), das den zu »fotografierenden« Bereich spezifiziert. Das Ergebnis der Methode ist ein BufferedImage-Objekt, das direkt mit ImageIO in eine Datei kommen kann.

Listing 11.20com/tutego/insel/ui/image/Screenshot.java, main()

BufferedImage bi = new Robot().createScreenCapture(
new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) );
ImageIO.write( bi, "jpg", new File("c:/screenshot.jpg") );
System.exit( 0 );

Mit createScreenCapture(Rectangle) lassen sich sehr interessante Lösungen realisieren. So lässt sich zum Beispiel überwachen, ob sich Bildschirminhalte ändern. Mit einer Bildanalyse ließe sich auch herausfinden, was der Anwender sich gerade anschaut.

In einem kleinen Beispiel wollen wir feststellen, ob der Benutzer aktiv vor dem Bildschirm ist oder nicht. Wir machen dies an der Anzahl der Pixel fest, die sich jede Sekunde verändern. Ein Programm soll dazu jede Sekunde einen Bildschirmabzug nehmen und ausgeben, um wie viel Prozent sich die Pixel gegenüber dem Vorgängerbild verändert haben:

Listing 11.21com/tutego/insel/ui/image/ImageDiffs.java

package com.tutego.insel.ui.image;

import java.awt.*;
import java.awt.image.*;

public class ImageDiffs {
public static void main( String args[] ) throws Exception {
Rectangle screenSize = new Rectangle( Toolkit.getDefaultToolkit().getScreenSize() );

BufferedImage image1 = new Robot().createScreenCapture( screenSize );

while ( true ) {
Thread.sleep( 1000 );

BufferedImage image2 = new Robot().createScreenCapture( screenSize );

DataBuffer dataBuffer1 = image1.getData().getDataBuffer();
DataBuffer dataBuffer2 = image2.getData().getDataBuffer();

int total = dataBuffer1.getSize(), diff = 0;

for ( int i = 0; i < total; i++ )
if ( dataBuffer1.getElem( i ) != dataBuffer2.getElem( i ) )
diff++;

System.out.printf( "Pixel total=%d, unterschiedliche Pixel=%d, Unterschied=%.2f%%%n",
total, diff, (double) 100 * diff / total );

image1 = image2;
}
}
}

Nachdem der Bildschirmabzug gemacht wurde, gilt es, auf die Pixel zuzugreifen und die beiden Bilder zu vergleichen. Um das Bild abzulaufen, könnten wir entweder vom BufferedImage mit der Methode getRGB(int x, int y) arbeiten oder uns – anders macht es getRGB() auch nicht – das Datenmodell der Grafik holen und es einfach komplett auflaufen; die Größe und Breite der beiden Bildschirmabzüge ist ja immer gleich, und so spielen die Höhe und Breite keine Rolle. Von den beiden DataBuffer-Objekten, die die Rohdaten der Grafik repräsentieren, erfragt getElem(int) den Farbwert. Wenn es Unterschiede gibt, inkrementiert das Programm einen Zähler. Nach dem Ablaufen aller Pixel folgt eine Statistik, die etwa so beginnen kann:

Pixel total=2304000, unterschiedliche Pixel=297, Unterschied=0,01 %
Pixel total=2304000, unterschiedliche Pixel=1708, Unterschied=0,07 %
Pixel total=2304000, unterschiedliche Pixel=1689, Unterschied=0,07 %
Pixel total=2304000, unterschiedliche Pixel=1000568, Unterschied=43,43 %
Pixel total=2304000, unterschiedliche Pixel=1002525, Unterschied=43,51 %
Pixel total=2304000, unterschiedliche Pixel=2087, Unterschied=0,09 %
 
Zum Seitenanfang

11.9.6Funktionsweise und Beschränkungen Zur vorigen ÜberschriftZur nächsten Überschrift

Für die Steuerung auf der Rechnerseite sind insbesondere unter Unix-Systemen beim netzwerkfähigen X-Window-System (X11) einige Anforderungen zu erfüllen. Hier sind Rechte erforderlich, um auf der unteren Ebene Ereignisse platzieren zu können. Ein X-Window-System benötigt hierfür die aktivierte Standarderweiterung XTEST 2.2. Verletzt die aktuelle Architektur diese Vorgaben, so wird während der Konstruktion eines Robot-Objekts eine AWTException ausgelöst.

 
Zum Seitenanfang

11.9.7MouseInfo und PointerInfo Zur vorigen ÜberschriftZur nächsten Überschrift

Mit der Klasse Robot lassen sich zwar Tastatur- und Maus-Ereignisse produzieren und Screenshots nehmen, doch Informationen über die aktuelle absolute Mausposition liefert die Klasse nicht. Die Klasse MouseInfo liefert diese Information. Die statische Methode MouseInfo.getPointerInfo() liefert ein PointerInfo-Objekt, das Aussagen über die anzeigende Einheit und über die Position des Mauszeigers macht. MouseInfo.getNumberOfButtons() liefert die Anzahl der Knöpfe.

Die Anzahl der Anwendungsfälle ist vielfältig. So ermöglicht dies zum Beispiel eine Farbpipette, mit der sich die Farbe eines Punktes nehmen lässt, der unter dem Mauszeiger steht.

Point location = MouseInfo.getPointerInfo().getLocation();
Color pixelColor = new Robot().getPixelColor( location.x, location.y );

Ein anderes Beispiel ist eine Bildschirmlupe:

Listing 11.22com/tutego/insel/ui/image/Magnifier.java, main()

final ImageIcon icon = new ImageIcon();
final JLabel label = new JLabel( icon );

new Timer( 100, new ActionListener() {
@Override public void actionPerformed( ActionEvent e ) {
try {
Rectangle location = new Rectangle(
MouseInfo.getPointerInfo().getLocation(), new Dimension( 40, 40 ) );
location.translate( –20, –20 );
BufferedImage image = new Robot().createScreenCapture( location );
icon.setImage( image.getScaledInstance( image.getWidth()*8,
image.getHeight()*8, Image.SCALE_FAST ) );
label.repaint();
}
catch ( AWTException ae ) { }
}
} ).start();

JOptionPane.showMessageDialog( null, label );
Screenshot der Anwendung Magnifier

Abbildung 11.22Screenshot der Anwendung Magnifier

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java SE 8 Standard-Bibliothek Java SE 8 Standard-Bibliothek
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Java ist auch eine Insel
Java ist auch eine Insel


Zum Rheinwerk-Shop: Professionell entwickeln mit Java EE 8
Professionell entwickeln mit Java EE 8


Zum Rheinwerk-Shop: Besser coden
Besser coden


Zum Rheinwerk-Shop: Entwurfsmuster
Entwurfsmuster


Zum Rheinwerk-Shop: IT-Projektmanagement
IT-Projektmanagement


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2018
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern