Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 3. Auflage
<< | < | > | >> | API | Kapitel 29 - Low-Level-Events

## 29.3 Mouse-Events

- 29.3 Mouse-Events

Ein Mouse-Event entsteht, wenn der Anwender innerhalb der Client-Area des Fensters eine der Maustasten drückt oder losläßt. Dabei reagiert das Programm sowohl auf Klicks der linken als auch - falls vorhanden - der rechten Maustaste und zeigt an, welche der Umschalttasten `[STRG]`, `[ALT]`, `[UMSCHALT]` oder `[META]` während des Mausklicks gedrückt waren. Des weiteren ist es möglich, zwischen einfachen und doppelten Mausklicks zu unterscheiden.

Ein Empfänger für Mouse-Events muß das Interface `MouseListener` implementieren und bekommt Events des Typs `MouseEvent` übergeben. `MouseEvent` erweitert die Klasse `InputEvent` und stellt neben `getID` und `getSource` eine Reihe zusätzlicher Methoden zur Verfügung, die wichtige Informationen liefern. Die Registrierung der Empfängerklasse erfolgt mit der Methode `addMouseListener`, die in allen Klassen zur Verfügung steht, die aus `Component` abgeleitet wurden:

    public void addMouseListener(MouseListener l)
| java.awt.Component

Tabelle 29.3 gibt eine Übersicht der Methoden von `MouseListener` und erklärt ihre Bedeutung:

Ereignismethode | Bedeutung
`mousePressed` | Eine Maustaste wurde gedrückt.
`mouseReleased` | Die gedrückte Maustaste wurde losgelassen.
`mouseClicked` | Eine Maustaste wurde gedrückt und wieder losgelassen. Diese Methode wird nach `mouseReleased` aufgerufen.
`mouseEntered` | Der Mauszeiger wurde in den Client-Bereich der auslösenden Komponente hineinbewegt.
`mouseExited` | Der Mauszeiger wurde aus dem Client-Bereich der auslösenden Komponente herausbewegt.

Tabelle 29.3: Methoden von MouseListener

|  | Damit ein Programm auf Mausklicks angemessen reagieren kann, benötigt es zusätzliche Informationen, die es sich mit den Methoden der Klasse `MouseEvent` bzw. ihrer Vaterklasse `InputEvent` beschaffen kann. Zunächst kann mit `getX`, `getY` und `getPosition` die Position des Mauszeigers zum Zeitpunkt des Ereignisses ermittelt werden: |  |
Hinweis

    public int getX()
    public int getY()

    public Point getPoint()
| java.awt.event.MouseEvent

`getX` liefert die x- und `getY` die y-Koordinate des Punktes, an dem der Mauszeiger sich beim Auftreten des Ereignisses befindet. `getPoint` liefert dieselbe Information zusammengefaßt als `Point`-Objekt.

|  |  |  | Die Koordinatenwerte werden relativ zum Ursprung der auslösenden Komponente angegeben. Bei einem Fenster des Typs `Frame` bedeutet dies, daß bei einem Klick in der oberen linken Ecke nicht `(0,0)` zurückgegeben wird, sondern `(getInsets().left, getInsets().top)`. Dies stimmt mit dem Ursprung des Koordinatensystems überein, das auch beim Aufruf der Grafikroutinen zugrunde gelegt wird. |  |
Tip

Des weiteren gibt es in `MouseEvent` die Methode `isPopupTrigger`, mit der abgefragt werden kann, ob das Klickereignis den Aufruf eines Popup-Menüs anzeigen soll. Wir werden darauf in Kapitel 30 zurückkommen.

Die Methode `getClickCount` liefert die Anzahl der Mausklicks, die dem aktuellen Ereignis zugeordnet ist:

    public int getClickCount()
| java.awt.event.MouseEvent

Normalerweise hat dieser Zähler den Wert 1, bei Mehrfachklicks gibt es aber auch `MouseEvents` mit dem Wert 2 oder (je nach Schnelligkeit der Klicks) noch höheren Werten. Die Abfrage von `getClickCount` kann dazu verwendet werden, auf Doppelklicks zu reagieren. Hierzu ist lediglich beim Aufruf von `mousePressed` oder `mouseClicked` zu überprüfen, ob `getClickCount` den Wert 2 liefert. In diesem Fall handelt es sich um einen Doppelklick. Zu beachten ist, daß bei einem Doppelklick zwei aufeinanderfolgende `mousePressed`-`mouseReleased`-`mouseClicked`-Sequenzen gesendet werden. In der ersten hat der Zähler den Wert 1, um den ersten (einfachen) Mausklick zu signalisieren, und erst in der zweiten steht er auf 2. Vor einem Doppelklick wird also immer erst der zugehörige Einzelklick übertragen.

|  | Eine alternative Methode, Doppelklicks zu erkennen, besteht darin, die Zeitspanne zwischen zwei Klicks und den Abstand der beiden Koordinatenpaare voneinander zu messen und bei hinreichend kleinen Differenzen einen Doppelklick anstelle zweier Einfachklicks zu melden. Dazu wird mit der Methode `getWhen` der Klasse `InputEvent` der Zeitpunkt (in Millisekunden) und mit `getPoint` oder `getX` und `getY` die Mausposition zweier aufeinanderfolgender Events bestimmt: |  |
Hinweis

    public long getWhen()
| java.awt.event.InputEvent

Diese Vorgehensweise hat den Vorteil, daß die zeitliche und positionelle Toleranz für Doppelklicks selbst beeinflußt werden kann, was bei dem oben beschriebenen Standardverfahren nicht möglich ist.

Neben den bisher besprochenen Methoden stehen die aus `InputEvent` geerbten Methoden zur Verfügung. `InputEvent` ist die gemeinsame Basisklasse von `MouseEvent` und `KeyEvent` und stellt Methoden zur Verfügung, die generelle Informationen über den Zustand der Umschalttasten `[STRG]`, `[ALT]`, `[UMSCHALT]` oder `[META]` zum Zeitpunkt des Ereignisses liefern:

    public boolean isShiftDown()
    public boolean isControlDown()
    public boolean isMetaDown()
    public boolean isAltDown()
| java.awt.event.InputEvent

|  | Während die Tasten `[UMSCHALT]`, `[STRG]` und `[ALT]` erwartungsgemäß die zugehörigen Tasten erkennen, zeigt `isMetaDown` unter Windows 95 an, ob der Klick von der rechten oder der linken Maustaste stammt. Ist der Rückgabewert `true`, so wurde die rechte Maustaste gedrückt, andernfalls die linke. |  |
Hinweis

Das folgende Programm ist ein einfaches Beispiel für die Reaktion auf Mausklicks. Es zeichnet an den Stellen, wo die Maustaste gedrückt wird, einen kleinen Smiley auf den Bildschirm:

    001 /* Listing2903.java */
    002
    003 import java.awt.*;
    004 import java.awt.event.*;
    005
    006 public class Listing2903
    007 extends Frame
    008 {
    009   public static void main(String[] args)
    010   {
    011     Listing2903 wnd = new Listing2903();
    012     wnd.setSize(300,200);
    013     wnd.setLocation(200,100);
    014     wnd.setVisible(true);
    015   }
    016
    017   public Listing2903()
    018   {
    019     super("Mausklicks");
    020     addWindowListener(new WindowClosingAdapter(true));
    021     addMouseListener(new MyMouseListener());
    022   }
    023
    024   class MyMouseListener
    025   extends MouseAdapter
    026   {
    027     int cnt = 0;
    028
    029     public void mousePressed(MouseEvent event)
    030     {
    031       Graphics g = getGraphics();
    032       int x = event.getX();
    033       int y = event.getY();
    034       if (event.getClickCount() == 1) { //Gesicht
    035         ++cnt;
    036         //Kopf und Augen
    037         g.drawOval(x-10,y-10,20,20);
    038         g.fillRect(x-6,y-5,4,5);
    039         g.fillRect(x+3,y-5,4,5);
    040         //Mund
    041         if (event.isMetaDown()) { //grimmig
    042            g.drawLine(x-5,y+7,x+5,y+7);
    043         } else {                  //lächeln
    044            g.drawArc(x-7,y-7,14,14,225,100);
    045         }
    046         //Zähler
    047         g.drawString(""+cnt,x+10,y-10);
    048       } else if (event.getClickCount() == 2) { //Brille
    049         g.drawLine(x-9,y-3,x+9,y-3);
    050       }
    051     }
    052   }
    053 }
| Listing2903.java

Listing 29.3: Reaktion auf Mausklicks

Beim Drücken der linken Maustaste lächelt das Gesicht, bei der rechten sieht es grimmig aus. Bei einem Doppelklick bekommt der Smiley zusätzlich eine Brille aufgesetzt. Die Ausgabe des Programms sieht beispielsweise so aus:

Abbildung 29.2: Die Ausgabe des Mausklick-Programms

|  | Erwähnenswert ist die Tatsache, daß das Programm ohne `paint`-Methode auskommt. Tatsächlich beschafft die Methode `mousePressed` sich die zum Zeichnen erforderliche Instanz der Klasse `Graphics` durch Aufruf von `getGraphics` selbst. Die Methode `getGraphics` gibt immer den Grafikkontext des aktuellen Fensterobjekts zurück. Das gelieferte `Graphics`-Objekt kann auf dieselbe Weise verwendet werden wie das als Parameter an `paint` übergebene. |  |
Hinweis

Leider hat das Beispielprogramm eine gravierende konzeptionelle Schwäche, denn die gezeichneten Smileys sind nicht dauerhaft. Wird das Fenster in den Hintergrund gestellt, nachdem einige Mausklicks durchgeführt wurden, sind bei erneuter Anzeige des Fensters die zuvor gezeichneten Smileys wieder verschwunden. Der Grund dafür ist, daß wir in unserem Beispiel nicht die `paint`-Methode überlagert haben, sondern die Ausgaben als direkte Reaktion auf ein Mausereignis erledigten. Da Windows nicht dafür sorgt, den Inhalt eines zuvor verdeckten Fensters zu rekonstruieren, ist die Anwendung selbst dafür verantwortlich, dies in ihrer `paint`-Methode zu tun. Eine bessere Implementierung dieses Programms würde also darin bestehen, die Koordinaten und Eigenschaften aller gezeichneten Objekte zu speichern und sie beim Aufruf von `paint` später selbst zu rekonstruieren. Wir werden diese Vorgehensweise in einem späteren Beispiel genauer kennenlernen.

Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 3. Auflage, Addison Wesley, Version 3.0
<< | < | > | >> | API | © 1998-2002 Guido Krüger, http://www.javabuch.de