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

Copyright © Galileo Press 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.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de