11. Obsługa zdarzeń
11.1. Dwa modele zdarzeń
Model 1.0:
•
•
•
Model 1.1:
11.2. Zdarzenia związane z myszką i klawiaturą
Obsługa zdarzeń związanych z myszką i klawiaturą zaimplementowana jest w 3 interfejsach:
Interfejs odbiorcy |
Zdarzenie |
Metoda |
MouseListener |
wciśnięcie przycisku myszki |
public void mousePressed (MouseEvent e ) |
|
zwolnienie przycisku myszki |
public void mouseReleased (MouseEvent e ) |
|
wejście wskaźnika myszki w obszar apletu lub jego elementu |
public void mouseEntered (MouseEvent e ) |
|
wyjście wskaźnika myszki z obszaru apletu lub jego elementu |
public void mouseExited (MouseEvent e ) |
|
kliknięcie przyciskiem myszki |
public void mouseClicked (MouseEvent e ) |
MouseMotionListener |
przesunięcie wskaźnika myszki |
public void mouseMoved (MouseMotionEvent e ) |
|
przeciągniecie wskaźnika myszki |
public void mouseDragged (MouseMotionEvent e ) |
KeyListener |
wciśnięcie klawisza |
public void keyPressed (KeyEvent e ) |
|
zwolnienie klawisza |
public void keyReleased (KeyEvent e ) |
|
naciśnięcie klawisza (wciśnięcie i zwolnienie) |
public void keyTyped (KeyEvent e ) |
W modelu 1.02 trzeba utworzyć odbiorcę każdej grupy zdarzeń. Można to zrobić na dwa sposoby:
zdefiniować aplet jako odbiorcę;
stworzyć osobną klasę odbiorcy zdarzeń.
Zmodyfikowanie apletu w taki sposób, aby stał się odbiorcą zdarzeń jest proste: wystarczy zaimplementować w nim odpowiednie interfejsy. Pokazują to przykłady Kulki i Linie.
Po ustaleniu, które zdarzenia mają być obsługiwane, i utworzeniu odbiorców tych zdarzeń trzeba zarejestrować tych odbiorców. Służą do tego metody
addMouseListener ( <odbiorca> );
addMouseMotionListener ( <odbiorca> );
addKeyListener ( <odbiorca> );
zdefiniowane w klasie Component.
Przykład
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;
public class Kulki extends java.applet.Applet
implements MouseListener {
int xspots [ ] = new int [ MAXSPOTS ];
int yspots [ ] = new int [ MAXSPOTS ];
int currspots = 0;
boolean zaDuzo = false;
Font f = new Font ( "Arial", Font.BOLD, 12 );
static final int MAXSPOTS = 5;
public void init ( ) {
setBackground ( Color.white );
addMouseListener ( this );
}
public void mouseReleased ( MouseEvent e ) { }
public void mouseClicked ( MouseEvent e ) { }
public void mouseEntered ( MouseEvent e ) { }
public void mouseExited ( MouseEvent e ) { }
public void mousePressed ( MouseEvent e ) {
if ( currspots < MAXSPOTS ) {
addspot ( e.getX ( ), e.getY ( ) );
repaint ( );
}
else {
zaDuzo = true;
repaint ( );
}
}
void addspot ( int x, int y ) {
xspots [ currspots ] = x;
yspots [ currspots ] = y;
currspots++;
}
public void paint ( Graphics g ) {
g.setColor ( Color.blue );
if ( !zaDuzo ) {
for ( int i = 0; i < currspots; i++ ) {
g.fillOval ( xspots[ i ] -10,
yspots[ i ] - 10, 20, 20 );
}
}
else {
g.setFont ( f );
g.drawString ( "Za duzo punktow", 10, 20 );
}
}
}
Przykład
import java.awt.event.*;
import java.awt.*;
public class Linie extends java.applet.Applet
implements MouseListener, MouseMotionListener {
final int MAX = 5; // maks. liczba linii
Point startowe [ ] = new Point [ MAX ]; // punkty poczatkowe
Point koncowe [ ] = new Point [ MAX ]; // punkty końcowe
Point poczatek; // początek aktualnej linii
Point koniec; // koniec aktualnej linii
int linia; // indeks linii
public void mouseClicked ( MouseEvent e ) { }
public void mouseEntered ( MouseEvent e ) { }
public void mouseExited ( MouseEvent e ) { }
public void mouseMoved ( MouseEvent e ) { }
public void init ( ) {
linia = 0;
setBackground ( Color.yellow );
addMouseListener ( this );
addMouseMotionListener ( this );
}
public void stop ( ) {
Font f = new Font ( "Arial", Font.PLAIN, 16 );
FontMetrics fm = getFontMetrics ( f );
String s = "Za dużo linii";
int xs, ys; // pozycja napisu
Graphics g = this.getGraphics ( );
g.setFont ( f );
xs = ( size ( ).width - fm.stringWidth ( s ) )/2;
ys = size ( ).height - 10;
g.drawString ( s, xs, ys );
}
public void mousePressed ( MouseEvent e ) {
if ( linia < MAX )
poczatek = new Point ( e.getX ( ), e.getY ( ) );
else stop ( );
}
public void mouseReleased ( MouseEvent e ) {
if ( linia < MAX )
addline (e.getX ( ), e.getY ( ) );
}
public void mouseDragged ( MouseEvent e ) {
if ( linia < MAX ) {
koniec = new Point ( e.getX ( ), e.getY ( ) );
repaint ( );
}
}
void addline ( int x, int y ) {
startowe [ linia ] = poczatek;
koncowe [ linia ] = new Point ( x, y );
linia++;
koniec = null;
poczatek = null;
repaint ( );
}
public void paint ( Graphics g ) {
g.setColor ( Color.blue );
for ( int i = 0; i < linia; i++ ) {
g.drawLine ( startowe [ i ].x, startowe [ i ].y,
koncowe [ i ].x, koncowe [ i ].y);
}
g.setColor ( Color.red );
if ( koniec != null )
g.drawLine ( poczatek.x, poczatek.y,
koniec.x, koniec.y );
}
}
11.3. Zdarzenia związane z elementami AWT
Komponenty AWT (przyciski, pola wyboru, pola opcji, listy rozwijane, pola tekstowe) generują zdarzenia wyższego rzędu. Poniższa tabela podaje interfejsy i metody obsługi takich zdarzeń.
Interfejs odbiorcy |
Zdarzenie |
Metoda |
ActionListener |
akcja |
public void ActionPerformed (ActionEvent e ) |
ItemListener |
wybór elementu z listy |
public void itemStateChanged (ItemEvent e ) |
|
zmiana wybranego elementu |
public void itemStateChanged (ItemEvent e ) |
FocusListener |
otrzymanie ogniska wprowadzania |
public void focusGained (FocusEvent e ) |
|
utrata ogniska wprowadzania |
public void focusLost (FocusEvent e ) |
TextListener |
zmiana zawartości pola tekstowego |
public void textValueChanged ( TextEvent e ) |
ContainerListener |
dodanie elementu do pojemnika |
public void componentAdded (ContainerEvent e ) |
|
usunięcie elementu z pojemnika |
public void componentRemoved (ContainerEvent e ) |
Odbiorcą zdarzeń związanych z elementami AWT może być sam aplet lub osobna klasa.
Do rejestracji odbiorców zdarzeń służą metody
addActionListener ( <odbiorca> );
addItemListener ( <odbiorca> );
addFocusListener ( <odbiorca> );
Należy przy tym pamiętać, że odbiorców zdarzeń związanych z myszką i klawiaturą rejestrujemy w aplecie, a odbiorców zdarzeń związanych z elementami AWT rejestrujemy w tych elementach.
Przykład Przycisk2 pokazuje wykorzystanie samego apletu jako odbiorcy zdarzeń.
Przykład
import java.awt.*;
import java.awt.event.*;
public class Przycisk2 extends java.applet.Applet
implements ActionListener {
Panel grafika, komunikaty, przyciski;
Button open, close, exit;
Frame okno; // w nim umieścimy aplet
Linie linie; // aplet do rysowania linii
int x0, y0, // wspolrzedne okna do wyswietlania grafiki
b, h, // wymiary calego apletu
b1, h1; // wymiary okna do wyswietlania grafiki
// pominięta część ( układanie elementów)
…
public void actionPerformed ( ActionEvent e ) {
Button przycisk = ( Button ) e.getSource ( );
String nazwa = przycisk.getLabel ( );
if ( nazwa == "OPEN" ) {
if ( !okno.isVisible ( )) okno.setVisible ( true );
linie.init ( );
}
else
if ( nazwa == "CLOSE" ) {
if ( okno.isVisible ( )) okno.setVisible ( false );
linie.stop ( );
}
else
if ( nazwa == "EXIT" ) this.setVisible ( false );
}
public void init ( ) {
// pominięta część ( układanie elementów )
…
przyciski.setLayout ( new GridLayout ( 3, 1, D, D ) );
b = getSize ( ).width;
h = getSize ( ).height;
b1 = ( int ) ( 0.70 * b );
h1 = ( int ) ( 0.77 * h );
x0 = D;
y0 = 5*D;
okno = new Frame ( "LINIE" );
okno.setLocation ( x0, y0 );
okno.setSize ( b1, h1 );
linie = new Linie ( );
okno.add ( linie );
okno.setVisible ( false );
open = new Button ( "OPEN" );
przyciski.add ( open );
open.addActionListener ( this );
close = new Button ( "CLOSE" );
przyciski.add ( close );
close.addActionListener ( this );
exit = new Button ( "EXIT" );
przyciski.add ( exit );
exit.addActionListener ( this );
}
}
Do tworzenia osobnych klas obsługi zdarzeń najlepiej wykorzystać adaptery MouseAdapter, MouseMotionAdapter i KeyAdapter z pakietu java.awt.event. Przykład ich wykorzystania pokazuje aplet Przycisk3.
Przykład
import java.awt.*;
import java.awt.event.*;
public class Przycisk3 extends java.applet.Applet {
Panel grafika,
komunikaty,
przyciski;
Button open,
close,
exit;
Frame okno; // do wyświetlania grafiki
Linie linie; // aplet do rysowania linii
ObslugaPrzycisku op;
…
public void init ( ) {
…
przyciski.setLayout ( new GridLayout ( 3, 1, D, D ));
op = new ObslugaPrzycisku ( this, okno, linie );
open = new Button ( "OPEN" );
przyciski.add ( open );
open.addActionListener ( op );
close = new Button ( "CLOSE" );
przyciski.add( close );
close.addActionListener ( op );
exit = new Button ( "EXIT" );
przyciski.add( exit );
exit.addActionListener ( op );
}
}
Do obsługi przycisków utworzyliśmy osobną klasę:
import java.awt.*;
import java.awt.event.*;
public class ObslugaPrzycisku implements ActionListener {
Przycisk3 aplet;
Frame okno;
Linie linie;
ObslugaPrzycisku ( Przycisk3 aplet, Frame okno,
Linie linie ) {
this.aplet = aplet;
this.okno = okno;
this.linie = linie;
}
public void actionPerformed ( ActionEvent e ) {
Button przycisk = ( Button ) e.getSource ( );
String nazwa = przycisk.getLabel ( );
if ( nazwa == "OPEN" ) {
if ( !okno.isVisible ( )) okno.setVisible ( true );
linie.init ( );
}
else
if ( nazwa == "CLOSE" ) {
if ( okno.isVisible ( )) okno.setVisible ( false );
linie.stop ( );
}
else
if ( nazwa == "EXIT" ) {
if ( okno.isVisible ( )) okno.setVisible ( false );
linie.stop ( );
aplet.setVisible ( false );
}
}
}
Adam Borkowski Język programowania „Java” 11−2
Adam Borkowski Język programowania „Java” 11−16
mouseDown ( )
handleEvent ( )
Zdarzenie n
Zdarzenie 2
Zdarzenie 1
keyDown ( )
ActionListener
KeyListener
MouseMotionListener
MouseListener
inicjalizacja odbiorców zdarzeń
wywołanych myszką
inicjalizacja odbiorców zdarzeń
wywołanych klawiaturą
inicjalizacja odbiorców zdarzeń
wywołanych przez elementy AWT
Zdarzenia
generowane
przesuwaniem
myszki
Zdarzenia
generowane
klawiaturą
Zdarzenia
generowane
klikaniem
myszką
Zdarzenia
generowane
w oknie