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 7
2 Threads und nebenläufige Programmierung
3 Datenstrukturen und Algorithmen
4 Raum und Zeit
5 Dateien, Verzeichnisse und Dateizugriffe
6 Datenströme
7 Die eXtensible Markup Language (XML)
8 Dateiformate
9 Grafische Oberflächen mit Swing
10 Grafikprogrammierung
11 Netzwerkprogrammierung
12 Verteilte Programmierung mit RMI
13 RESTful und SOAP Web-Services
14 JavaServer Pages und Servlets
15 Applets
16 Datenbankmanagement mit JDBC
17 Technologien für die Infrastruktur
18 Reflection und Annotationen
19 Dynamische Übersetzung und Skriptsprachen
20 Logging und Monitoring
21 Java Native Interface (JNI)
22 Sicherheitskonzepte
23 Dienstprogramme für die Java-Umgebung
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
Java 7 - Mehr als eine Insel von Christian Ullenboom
Das Handbuch zu den Java SE-Bibliotheken
Buch: Java 7 - Mehr als eine Insel

Java 7 - Mehr als eine Insel
Rheinwerk Computing
1433 S., 2012, geb.
49,90 Euro, ISBN 978-3-8362-1507-7
Pfeil 10 Grafikprogrammierung
Pfeil 10.1 Grundlegendes zum Zeichnen
Pfeil 10.1.1 Die paint()-Methode für das AWT-Frame
Pfeil 10.1.2 Zeichnen von Inhalten auf ein JFrame
Pfeil 10.1.3 Auffordern zum Neuzeichnen mit repaint()
Pfeil 10.1.4 Java 2D-API
Pfeil 10.2 Einfache Zeichenmethoden
Pfeil 10.2.1 Linien
Pfeil 10.2.2 Rechtecke
Pfeil 10.2.3 Ovale und Kreisbögen
Pfeil 10.2.4 Polygone und Polylines
Pfeil 10.3 Zeichenketten schreiben und Fonts
Pfeil 10.3.1 Zeichenfolgen schreiben
Pfeil 10.3.2 Die Font-Klasse
Pfeil 10.3.3 Einen neuen Font aus einem gegebenen Font ableiten
Pfeil 10.3.4 Zeichensätze des Systems ermitteln *
Pfeil 10.3.5 Neue TrueType-Fonts in Java nutzen
Pfeil 10.3.6 Font-Metadaten durch FontMetrics *
Pfeil 10.4 Geometrische Objekte
Pfeil 10.4.1 Die Schnittstelle Shape
Pfeil 10.4.2 Kreisförmiges
Pfeil 10.4.3 Kurviges *
Pfeil 10.4.4 Area und die konstruktive Flächengeometrie *
Pfeil 10.4.5 Pfade *
Pfeil 10.4.6 Punkt in einer Form, Schnitt von Linien, Abstand Punkt/Linie *
Pfeil 10.5 Das Innere und Äußere einer Form
Pfeil 10.5.1 Farben und die Paint-Schnittstelle
Pfeil 10.5.2 Farben mit der Klasse Color
Pfeil 10.5.3 Die Farben des Systems über SystemColor *
Pfeil 10.5.4 Composite und Xor *
Pfeil 10.5.5 Dicke und Art der Linien von Formen bestimmen über Stroke *
Pfeil 10.6 Bilder
Pfeil 10.6.1 Eine Übersicht über die Bilder-Bibliotheken
Pfeil 10.6.2 Bilder mit ImageIO lesen
Pfeil 10.6.3 Ein Bild zeichnen
Pfeil 10.6.4 Programm-Icon/Fenster-Icon setzen
Pfeil 10.6.5 Splash-Screen *
Pfeil 10.6.6 Bilder im Speicher erzeugen *
Pfeil 10.6.7 Pixel für Pixel auslesen und schreiben *
Pfeil 10.6.8 Bilder skalieren *
Pfeil 10.6.9 Schreiben mit ImageIO
Pfeil 10.6.10 Asynchrones Laden mit getImage() und dem MediaTracker *
Pfeil 10.7 Weitere Eigenschaften von Graphics *
Pfeil 10.7.1 Eine Kopie von Graphics erstellen
Pfeil 10.7.2 Koordinatensystem verschieben
Pfeil 10.7.3 Beschnitt (Clipping)
Pfeil 10.7.4 Zeichenhinweise durch RenderingHints
Pfeil 10.7.5 Transformationen mit einem AffineTransform-Objekt
Pfeil 10.8 Drucken *
Pfeil 10.8.1 Drucken der Inhalte
Pfeil 10.8.2 Bekannte Drucker
Pfeil 10.9 Benutzerinteraktionen automatisieren, Robot und Screenshots *
Pfeil 10.9.1 Der Roboter
Pfeil 10.9.2 Automatisch in die Tasten hauen
Pfeil 10.9.3 Automatisierte Mausoperationen
Pfeil 10.9.4 Methoden zur Zeitsteuerung
Pfeil 10.9.5 Bildschirmabzüge (Screenshots)
Pfeil 10.9.6 Funktionsweise und Beschränkungen
Pfeil 10.9.7 MouseInfo und PointerInfo
Pfeil 10.10 Zum Weiterlesen

Rheinwerk Computing - Zum Seitenanfang

10.9 Benutzerinteraktionen automatisieren, Robot und Screenshots *Zur 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 (http://fest.easytesting.org/swing/wiki/pmwiki.php), die Benutzerinteraktionen automatisieren.


Rheinwerk Computing - Zum Seitenanfang

10.9.1 Der RoboterZur nächsten ÜberschriftZur vorigen Ü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.

Rheinwerk Computing - Zum Seitenanfang

10.9.2 Automatisch in die Tasten hauenZur nächsten ÜberschriftZur vorigen Überschrift

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

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, mit requestFocus() den Fokus zu setzen.

Das Argument von keyPress() und keyRelease() ist eine Konstante der Klasse KeyEvent. Neben den alphanumerischen Tasten auf der Tastatur finden sich unter anderem Konstanten für Funktionstasten, Meta-Tasten, 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(). 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.


Rheinwerk Computing - Zum Seitenanfang

10.9.3 Automatisierte MausoperationenZur nächsten ÜberschriftZur vorigen Überschrift

Jetzt fehlen uns noch die Methoden mousePress() und mouseRelease(). 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.

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() weitergereicht werden. Dann befindet sich der Zeiger über der Komponente, und mousePress() kann seine Wirkung nicht mehr verfehlen.


Rheinwerk Computing - Zum Seitenanfang

10.9.4 Methoden zur ZeitsteuerungZur nächsten ÜberschriftZur vorigen Ü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.

Rheinwerk Computing - Zum Seitenanfang

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

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

Listing 10.28: com/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() 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 10.29: com/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() 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 %

Rheinwerk Computing - Zum Seitenanfang

10.9.6 Funktionsweise und BeschränkungenZur nächsten ÜberschriftZur vorigen Ü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.


Rheinwerk Computing - Zum Seitenanfang

10.9.7 MouseInfo und PointerInfoZur vorigen Ü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 10.30: com/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 );

Abbildung

Abbildung 10.30: Screenshot der Anwendung Magnifier



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Neuauflage: Java SE 8 Standard-Bibliothek
Neuauflage: Java SE 8 Standard-Bibliothek
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Java EE 7






 Professionell
 entwickeln mit
 Java EE 7


Zum Katalog: Java ist auch eine Insel






 Java ist auch
 eine Insel


Zum Katalog: Einstieg in Eclipse






 Einstieg in Eclipse


Zum Katalog: Einstieg in Java






 Einstieg in Java


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das 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