background image

Mariusz Chmielewski

1

Programowanie 

Zdarzeniowe

Komponenty Swing

Delegacyjny model 

zdarzeń

Obsługa zdarzeń

kpt. mgr inż. Mariusz Chmielewski

Instytut Systemów Informatycznych

Wydział Cybernetyki

Wojskowa Akademia Techniczna

background image

Delegacyjny model obsługi zdarzeń – 

Delegation Event Model

• Prosta idea : źródło (source) generuje 

zdarzenie (event), które jest wysyłane 
do zarejestrowanych (jednego lub 
wielu) obiektów nasłuchujących 
(listener); 

• Obiekt nasłuchujący oczekuje na 

odebranie zdarzenia. W momencie jego 
odebrania wywoływana jest procedura 
obsługi zdarzenia i następnie następuje 
przekazanie sterowania. 

• Obiekt nasłuchujący musi zarejestrować 

się do nasłuchiwania danego typu 
zdarzeń w źródle. Ten fakt bezpośrednio 
pozwala identyfikować tylko te obiekty 
nasłuchujące które jawnie 
zadeklarowały się do nasłuchiwania 
zdarzeń danego typu z danego źródła. 

background image

• Zaletą tego rozwiązania jest również 

separacja kodu obsługi (logiki) 
przetwarzania zdarzeń oraz logiki 
interfejsu generującej te zdarzenia;

• Element interfejsu użytkownika jest w 

stanie delegować kod obsługi zdarzeń 
do innych fragmentów kodu:

– Jednej wspólnej klasy obsługi zdarzeń 

(klasa obsługująca zdarzenia dla grupy 
przycisków budowanego GUI);

– Specjalizowanej klasy obsługi kojarzonej z 

danym komponentem (klasa specjalizująca 
się w obsłudze zdarzeń dla pojedynczego 
przycisku);

Delegacyjny model obsługi zdarzeń – 

Delegation Event Model

background image

Zdarzenia

• W modelu delegacyjnym zdarzenie 

identyfikowane jest jako obiekt 
opisujący aktualny stan źródła. 
Zdarzenie może być definiowane jako 
pewien typ sygnału stanowiący o 
zmianie stanu – „coś się stało”;

• Zdarzenie jest obiektem 

generowanym przez zewnętrzne 
akcje użytkownika takie jak ruchy 
myszy, kliknięcia przycisków myszy 
oraz klawiatury lub zdarzenia 
generowane przez system 
operacyjny (timer).

•  Komponent GUI na którym 

wygenerowane zostało zdarzenie 
jest nazywany „źródłem zdarzenia”. 

background image

Klasy zdarzeń

AWTEvent

EventObject

AdjustmentEvent

ComponentEvent

TextEvent

ItemEvent

ActionEvent

InputEvent

WindowEvent

MouseEvent

KeyEvent

ContainerEvent

FocusEvent

PaintEvent

ListSelectionEvent

Klasą bazową wszystkich zdarzeń jest 

java.util.EventObj

Podklasy 

EventObj

 zajmują się odwzorowaniem 

konkretnych typów zdarzeń dla konkretnych 
typów komponentów graficznych – akcje 
przycisków, zdarzenia okna aplikacji, 
specjalizowane zdarzenia komponentów, 
zdarzenia myszy i klawiatury.  

background image

Akcje użytkownika, źródła 
zdarzeń, typy zdarzeń

Źródło

Generowane
Akcja użytkownika

zdarzenia

zdarzenie

Clicked a button

JButton

ActionEvent

Changed text

JTextComponent

TextEvent

Double-clicked on a list item

JList

ActionEvent

Selected or deselected an item

JList

ItemEvent

 with a single click
Selected or deselected an item

JComboBox

ItemEvent

Mouse moved or dragged

Component

MouseEvent

Mouse pressed, released, 
clicked, entered, or exited

Component

MouseEvent

 

Window opened, closed
iconified, deiconified, closed

Window

WindowEvent

Click a check box

JCheckBox

ItemEvent, 

ActionEvent

Click a radio button

JRadioButton

ItemEvent, 

 . . .

ActionEvent

background image

Rejestracja do nasłuchu 

zdarzenia

Source Object

Trigger an event

Listener Object

Register a listener object

EventObject

Event Handler

Notify listener

Generate

an event

User

action

background image

8

Model delegacji zdarzeń

 

source: SourceClass 

 

 +addXListener(listener: XListener) 

 

listener: ListenerClass 

User 

Action 

Trigger an event 

XListener

 

 

 

+

handler(event: XEvent)

 

Register by invoking 
source.addXListener(listener); 

(a) A generic source component 

with a generic listener 

 

 

source: JButton 

 +addActionListener(listener: ActionListener) 

 

listener: CustomListenerClass 

ActionListener

 

 

+

actionPerformed(event: ActionEvent)

 

Register by invoking 
source.addActionListener(listener); 

(b) A JButton source component 
with an ActionListener

 

background image

9

Generyczny model - reprezentacja komponentów 

GUI

 

source: SourceClass 

 

 +addXListener(XListener listener) 
 

(a) Internal function of a generic source object 

event: XEvent 

listener1 

listener2 

… 

listenern 

 

 

 

+

handler(

Keep it a list 

Invoke  

listener1.handler(event) 

listener2.handler(event) 

… 
listenern.handler(event) 

An event is 

triggered 

 

source: JButton 

 

 +addActionListener(ActionListener listener) 
 

(b) Internal function of a JButton object 

event: 
ActionEvent 

listener1 

listener2 

… 

listenern 

 

 

 

+

handler(

Keep it a list 

Invoke  

listener1.actionPerformed(event) 

listener2.actionPerformed(event) 

… 
listenern.actionPerformed(event) 

An event is 

triggered 

 

background image

Obsługa zdarzeń akcji

Obiekt nasłuchujący musi spełniać następujące 

wymagania:

Musi zostać zarejestrowany w przynajmniej jednym 
źródle w celu otrzymywania określonych typów 
zdarzeń. 

Musi implementować metody do odbierania i 
przetwarzania danego typu powiadomień.

A listener object must implement the corresponding 
listener interface. 

Przykład: Klasa nasłuchująca dla klasy JButton musi 
implementować interfejs ActionListener. Interfejs 
ten zawiera metodę  actionPerformed(ActionEvent 
e)

Obiekt zdarzenia jest przesyłany do metody obsługi i 
zawiera wszystkie potrzebne dane dotyczące źródła 
zdarzenia e.getSource() oraz samego zdarzenia.  

background image

Wybrane obiekty Listener

Event Class

Listener Interface

Listener Methods (Handlers)

ActionEvent

ActionListener

actionPerformed(ActionEvent e)

ItemEvent

ItemListener

itemStateChanged(ItemEvent e)

WindowEvent

WindowListener

windowClosing(WindowEvent e)
windowOpened(WindowEvent e)

ContainerEvent

ContainerListener

componentAdded(ContainerEvent e)
componentRemoved(ContainerEvent)

MouseEvent 

MouseListener

mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)

MouseMotionListener 

mouseDraged(MouseEvent e)
mouseMoved(MouseEvent e)

KeyEvent

KeyListener

keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)

TexEvent

TextListener

TextValueCnanged(TextEvent e)

background image

Prosty przykład obsługi 

zdarzeń

Cel: Wyświetlenie dwóch przycisków w 

oknie aplikacji. Wynikiem kliknięcia na 
jeden z przycisków ma być komunikat na 
ekranie.
    1. Utwórz dwa przyciski – źródła 
zdarzeń;

        2. Dodaj przyciski do okna;
        3. Zarejestruj obiekty (obiekt) 

nasłuchujący dla dodanych przycisków;

        4. Zaimplementuj (nadpisz) obiekt 

nasłuchujący.      

background image

1. Deklaracja źródeł zdarzeń

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TestActionEvent extends JFrame
                         

implements ActionListener

 

{

 // 

1 krok

Deklaracja źródeł zdarzeń(2 przyciski)

  

 private JButton jbtOK = new Jbutton(“OK”);
 private JButton jbtCL = new Jbutton(“Cancel”);

background image

2. Rejestracja do nasłuchu

// Constructor
public TestActionEvent () {
  setTitle();
  Container cp = getContentPane();  
  cp.setLayout(new FlowLayout());   
  // 

2 krok: dodanie źródeł zdarzeń do głównego 

okna

  cp.add(jbtOK);   
  cp.add(jbtCL);   
  // 

3 krok: rejestracja obiektu nasłuchującego

; 

jbtOK.addActionListener(this); 

  jbtCL.addActionListener(this); 

}

background image

3. Obsługa zdarzeń

//

 4 krok: implementacja metody obsługi (handler)

public void actionPerformed(ActionEvent e) {
 if(e.getSource() == jbtOK) {
  System.out.println(“Wcisnieto przycisk OK”);
 }
 if(e.getSource() == jbtCL) {
  System.out.println(“Wcisnieto przycisk Cancel“);
 }// actionPerformed
}

background image

4. Test

 public static void main(String[] args) {
    TestActionEvent frame = new TestActionEvent();
    

frame.setDefaultCloseOperation(

                     JFrame.EXIT_ON_CLOSE);

    frame.setSize(100,100); 
    frame.setVisible(true);
  }//main

}// class

background image

 

Drugi przykład – specjalizowana klasa 

obsługi zdarzeń

public class Button2Demo extends JFrame 
{
  private JButton jbtOK, jbtCL;
  ActionListener handler = new ButtonHandler();

  public Button2Demo() {

     jbtOK = new JButton(“OK”);
     jbtOK.addActionListener(handler); 
     jbtCL = new JButton(“Cancel”);
     jbtCL.addActionListener(handler); 
  } 
...

background image

Handling Action Events

  ...
  // 

Inner class

  class ButtonHandler implements ActionListener {
    public void actionPerformed(ActionEvent e) 
    {  
      if(e.getSource() == jbtOK) {
        System.out.println(“Wcisnieto OK”); 
      }//if       
      if(e.getSource() == jbtCL) {
        System.out.println(“Wcisnieto Cancel”); 
      } //if 
    }// actionPerformed()
  }// 

Inner class

}// public class

background image

Przykład : 

Palindrom

background image

1. Deklaracja komponentów GUI

import Palindrome; // Import class Palindrome
class PalindromeDemo extends JFrame {
  
// 3 przyciski
  private JButton jbtClear, jbtCheck, jbtExit; 
  
// pole tekstowe
  private JTextField jtfString; 
  
// etykiety na opis i komunikaty
  private JLabel jlResult, jlInstr; 
  
// specjalizowany obiekt obsługi zdarzeń
  ActionListener handler = new ButtonHandler();

background image

2. Tworzenie komponentów GUI

public PalindromeDemo() {

    // trzy przyciski
   jbtCheck  = new JButton(“Check”);
   jbtClear  = new JButton(“Clear”);
   jbtExit   = new JButton(“Exit”);
   
// pole tekstowe
   jtfString = new JTextField(32);
   
// etykiety
   jlInstr  = new JLabel(“Enter phrase to be tested:”);
   jlResult = new JLabel(“”);

   ... 

background image

3. Dodanie komponentów do okna, 

rejestracja  obiektów (obiektu) 

nasłuchujących 

background image

4a. Implementacja obsługi jako klasy 

wewnętrznej

class ButtonHandler implements ActionListener {
 public void actionPerformed(ActionEvent e)  {  
  if(e.getSource() == jbtClear) {
     jtfString.setText(“”); 
     jlResult.setText(“”); 
  }//if       
  if(e.getSource() == jbtCheck) {
    String str = jtfString.getText();
    Palindrome pal = new Palindreme(str);
    boolean result = pal.IsPalindrome();
   
    if(result) jlResult.setText(“Yes”); 
    else       jlResult.setText(“No”); 
  } //if 
  if(e.getSource() == jbtExit) {
         System.exit(0); 
  }
 }// actionPerformed()
}// inner class ButtonHandler

Wykorzystanie klasy  
Palindrome do weryfikacji.

background image

4b. Implementacja obsługi jako klasy 

wewnętrznej

background image

5. Budowa aplikacji – metoda Main

public static void main(String[] args) {
   String title = “Is it Palindrome?”;
   // Create the frame with UI as an object of
   // PalindromeDemo Class.
   PalindromeDemo frame = new PalindromeDemo(title);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setsize(400,150); 
   frame.setVisible(true);
}//main

background image

Klasy anonimowe

Język Java pozwala na definiowanie 
klas anonimowych, definiowanych bez 
nazwy i konstruktora. Muszą one być 
określane w kodzie według 
następującej zasady: 

new NazwaNadKlasy(arg, arg, ...) 
BlokInstrukcji

gdzie: 
NazwaNadKlasy jest nazwą nadklasy 
definiowanej klasy anonimowej, 
arg są argumentami konstruktora 
nadklasy (zależnie od podanych 
argumentów wywoływany jest 
odpowiedni konstruktor nadklasy: 
super NazwaNadKlasy(arg, arg, ...) ), 
BlokInstrukcji jest blokiem instrukcji 
definiujących klasę anonimową. 

Przyjmuje się, że w przypadku kiedy 
nie ma jawnej definicji nadklasy jest 
nią klasa Object

Mariusz Chmielewski

26

background image

Klasy anonimowe

Powyższa definicja oznacza stworzenie obiektu klasy anonimowej 
dziedziczącej z klasy Contents. Zwracana referencja nowego obiektu klasy 
anonimowej jest automatycznie rzutowana na klasę Contents. 
Definicja klasy anonimowej jest skrótem następującej definicji:

class MyContents implements Contents {
   private int i = 11; 
   public int value() {
       return i;
   }
 } return new MyContents();

W przypadku, gdy klasa anonimowa jest podklasą klasy wewnętrznej, 
definicja klasy anonimowej przyjmuje postać: 

    obiektZewnętrzny.new NazwaNadKlasy(arg, arg, ...) Blok 

gdzie:
  obiektZewnętrzny - obiekt klasy zewnętrznej zawierającej powtórną 
definicję anonimowej klasy wewnętrznej.  W tym przypadku wywoływany 
jest konstruktor nadklasy: obiektZewnętrzny.new NazwaNadKlasy(arg, arg, 
...)

Mariusz Chmielewski

27

background image

Obsługa zdarzeń z wykorzystaniem 

klasy anonimowej

// alternatywny sposób definicji klas obsługi
private JButton jbtCheck = new JButton(”Check");
jbtCheck.addActionListener(new ActionListener() {   
   public void actionPerformed(ActionEvent e)    { 
      String str = jtfString.getText(); 
      boolean result = isPalindrome(str)
      if(result == TRUE)
         jlResult.setText(”Yes");
      else
         jlResult.setText(”No");
   }
});

background image

2. Inny sposób obsługi zdarzeń

private JButton jbtClear = new JButton(”Clear");
jbtClear.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        jtfString.setText("");
        jlResult.setText("");
      }
    });

background image

3. Inny sposób obsługi zdarzeń

private JButton jbtExit = new JButton(”Exit");
jbtExit.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e) {
           System.exit(0);
  }
});


Document Outline