Wzorzec projektowy Obserwator idiomatyczne rozwiązanie

Podobne dokumenty
Kurs programowania. Wykład 4. Wojciech Macyna. 23 marca 2016

Programowanie zdarzeniowe

Rysowanie prostych obiektów graficznych przy użyciu biblioteki AWT (Abstract Window Toolkit)

Tworzenie elementów graficznych

Java - interfejs graficzny

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Grafika i komunikacja człowiek komputer Laboratorium. Część 3: Tekst, czcionki, kolory

Obsługa zdarzeń. Wykład 4

Język Java. Rysowanie GUI Określanie wyglądu komponentów

Programowanie obiektowe

Programowanie w języku Java

Wykład 12: Obsługa Zdarzeń

Języki i metody programowania Java Obsługa zdarzeń - przykłady

Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com

Java SE Laboratorium nr 5. Temat: Obsługa zdarzeń

Laboratorium z informatyki sem. III/ćw. 2 Wydział Transportu PW /19 MATERIAŁY POMOCNICZE DO ĆWICZENIA 2

Programowanie komputerów Wykład 6: Aplety Java

Programowanie graficznych interfejsów użytkownika

Henryk Budzisz. materiały przygotowane w ramach projektu ZPORR nr POKL /08-00

Podstawowe informacje o apletach

Java jako zdalny interfejs aplikacji Webowych aplety

SWING c.d. przydatne narzędzia: JFileChooser, JOptionPane. drag'n drop, menu kontekstowe.

Kontenery i komponenty graficzne

Tworzenie i obsługa graficznego interfejsu uŝytkownika

Grafika i komunikacja człowiek komputer Laboratorium. Część 1: Wstęp do grafiki

Graphic User Interfaces pakiet Swing

Programowanie zdarzeniowe

Java niezbędnik programisty spotkanie nr 12. Graficzny interfejs użytkownika

Programowanie Multimediów. Programowanie Multimediów JAVA. programowanie GUI. (AWT i Swing) [1]

Henryk Budzisz. materiały przygotowane w ramach projektu ZPORR nr POKL /08-00

Współbieżność w środowisku Java

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

setdefaultcloseoperation(jframe.exit_on_close);//obsługa zamykania aplikacji setvisible(true); } //wyświetlenie okna

Interfejs graczny w Javie.

Wątki (Threads) Potrzeby. Przetwarzanie równoległe i współbieŝne. Cechy programowania wątkowego. Concurrent programming is like

Przetwarzanie równoległe i współbieżne

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Kurs programowania. Wykład 5. Wojciech Macyna. 31 marzec 2016

Programowanie Multimediów. Programowanie Multimediów JAVA. grafika w JAVA 2D API [1]

II Tworzenie klasy Prostokąt dziedziczącej z klasy wątku

Polimorfizm. dr Jarosław Skaruz

Podstawy Swing. Tomasz Borzyszkowski

Wątki. Definiowanie wątków jako klas potomnych Thread. Nadpisanie metody run().

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt

Aplikacja wielowątkowa prosty komunikator

Programowanie obiektowe

Dokumentacja do API Javy.

4. W konstruktorze klasy Grafika wywołaj metodę określającą rozmiary ramki oraz ustaw kolor tła metodą setbackground():

Programowanie obiektowe

Informatyka I. Interfejs GUI wysokiego poziomu. Biblioteka Swing. Programowanie zdarzeniowe. Politechnika Warszawska Wydział Transportu 2018

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science

Programowanie w Javie Wykład 6 Okienka w Javie (AWT)

dziedziczenie - po nazwie klasy wystąpią słowa: extends nazwa_superklasy

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

1 Atrybuty i metody klasowe

Informatyka i Ekonometria Programowanie komputerów Ćwiczenia Tworzenie aplikacji wykorzystaniem graficznego interfejsu użytkownika - Swing.

1. Co będzie wynikiem wykonania poniŝszych instrukcji? g2d.gettransform().scale(1, -1); g2d.gettransform().translate(4, -8); g2d.drawline(4, 0, 4, 4);

Programowanie obiektowe

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Laboratorium z informatyki sem.iii/ćw. 4 Wydział Transportu PW /19

Podstawy tworzenia aplikacji z wykorzystaniem języka Java ME ćwiczenia 2

Programowanie Obiektowe Java

SWING. dr Jarosław Skaruz

Scenariusz Lekcji. Część organizacyjna:

Swing ćwiczenia 2 opis

Praktyczny kurs Java. Wydanie II

Applety Java. Applety są przykładem kodu Java wykonywanego po stronie klienta, ale bez ujawnionej (jak w przypadku skryptu) wersji źródłowej

Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 Zofia Kruczkiewicz

PWŚG Ćwiczenia 13. Ukończoną pracę należy przesłać na adres lub

PROJEKTOWANIE ABSTRAKCYJNEJ KLASY FIGURA PRZECHOWUJĄCEJ WSPÓLNE CECHY OBIEKTÓW GRAFICZNYCH

Język Java część 2 (przykładowa aplikacja)

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Kurs programowania. Wykład 6. Wojciech Macyna. 7 kwietnia 2016

Aplikacja wielow tkowa prosty komunikator

Programowanie obiektowe

Język obiektowy o składni podobnej do C++ Zarządzanie pamięcią niepotrzebne obiekty automatycznie usuwane

Systemy operacyjne na platformach mobilnych

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Interfejsy w Java. Przetwarzanie równoległe. Wątki.

Instrukcja implementacji sterownika wirtualnego portu szeregowego dla systemu Android. Opracowanie: Elzab Soft sp. z o.o.

Klasy abstrakcyjne. Klasę abstrakcyjną tworzymy przy pomocy modyfikatora abstract

Platformy Programistyczne Podstawy języka Java

INSTRUKCJA DO ĆWICZENIA 5

Wzorce logiki dziedziny

Grafika i komunikacja człowiek komputer Laboratorium. Część 2: Graphics

Iteracyjno-rozwojowy cykl oprogramowania 4

Zastosowanie słuchaczy zdarzeń wg

Programowanie w JAVA Lab. 5 - Wątki. 1. Wykorzystując metodę Monte Carlo narysować wykres funkcji oraz obliczyć całkę: 7 x ) xy, 8,8

Programowanie w języku Java WYKŁAD

Klasy abstrakcyjne i interfejsy

Interaktywne aplety obsługa zdarzeń, uruchamianie apletu przez przeglądarkę lub maszynę wirtualną Javy. Tworzenie łącz w apletach

STWORZENIE PRZYKŁADOWEJ

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Java: interfejsy i klasy wewnętrzne

Spis treści. 1 Aplet. 2 Od aplikacji do apletu. 1 Aplet 1. 2 Od aplikacji do apletu 1. 3 Budowa apletu 3. 4 Cykl życia apletu 4

Transkrypt:

Wzorzec projektowy Obserwator idiomatyczne rozwiązanie

Observator Pattern Simply, the Observer pattern allows one object (the observer) to watch another (the subject). The Observer pattern allows the subject and observer to form a publish-subscribe relationship. Through the Observer pattern, observers can register to receive events from the subject. When the subject needs to inform its observers of an event, it simply sends the event to each observer.

Observable /Observator pattern import java.util.observable ; public class Licznik51 extends Observable... public void impuls () { if (TR == true) { stan ++; if (stan > max) { stan=startvalue(); TF = true; setchanged() ; notifyobservers() ;

Observable /Observator pattern import java.util.observer ; import java.util.observable ; public class TestLicznik51 implements Observer... l51 = new Licznik51() ; l51.addobserver(this) ;... public void update(observable subject, Object arg) { message.settext("got event from " + subject) ; // it is like interrupt routine

Organizacja obsługi zdarzeń W Javie obowiązuje delegacyjny model obsługi zdarzeń, (idiomatyczna implementacja wzorca Obsrwator), zgodnie z którym obiekt-źródło zdarzenia zawiadamia obiektodbiorca (słuchacz) o wystąpieniu zdarzenia. Typowym źródłem zdarzeń są komponenty GUI, które mogą zawiadamiać słuchaczy o działaniach uŝytkownika, który poprzez te komponenty przekazuje dane (polecenia) do programu.

Model delegacyjny W istocie źródłem zdarzeń związanych z GUI jest uŝytkownik, który manewrując myszką, klawiaturą... wywołuje generację strumienia zdarzeń przekazywanych do komponentu, który okupuje określony obszar. Komponent zwykle filtruje ten niskopoziomowy strumień zdarzeń i generuje pewien rodzaj zdarzeń semantycznych związanych z przeznaczeniem komponentu. Dowolny obiekt moŝe zostać powiadomiony o zaistnieniu takiego zdarzenia pod warunkiem, Ŝe zostanie zarejestrowany jako słuchacz i potrafi je obsłuŝyć.

Multiple listeners Zdarzenie reprezentowane jest przez obiekt, który dostarcza informacji o samym zdarzeniu oraz identyfikuje źródło zdarzenia. Źródłem zdarzenia jest zwykle komponent GUI, ale inne obiekty równieŝ mogą generować zdarzenia!!! (Wkrótce będziemy projektować generator impulsów)

Interfejs słuchacza zdarzenia Odbiorca musi charakteryzować się umiejętnością obsługi zdarzeń określonego typu. Umiejętności te są określone przez zestaw metod wraz z argumentami stanowiący tzw. interfejs słuchacza zdarzeń określonego typu. Obiekt słuchacz musi implementować ten interfejs tzn. dostarczyć definicji wszystkich zadeklarowanych tam metod. W bibliotece AWT zdefiniowano stosowne interfejsy słuchaczy: (ActionListener, TextListener, ItemListener i inne). Deklaracja implementacji interfejsu: public class MyClass implements ActionListener { oznacza przyjęcie zobowiązania dostarczenia implementacji metod zdefiniowanych w tym interfejsie

Trzy elementy obsługi zdarzeń Deklaracja umiejętności słuchacza : public class MyClass implements ActionListener { Rejestracja słuchacza na komponencieźródle somecomponent.addactionlistener(instanceofmyclass ); Dostarczenie kodu reagującego na zdarzenie (event handler) public void actionperformed(actionevent e) {...//code that reacts to the action...

Modyfikacja klasy TestLicznikaGUI class TestLicznikaGUI extends Frame implements ActionListener { Licznik mylicznik; Button start,...; // konstruktor void makegui() { //... start = new Button( On ); start.addactionlistener(this); //... public void actionperformed(actionevent ae) { mylicznik.start(); // main

Obiekt moŝe obsługiwać zdarzenia z wielu źródeł public void actionperformed(actionevent ae) { Object source = ae.getsource() ; if (source == start) mylicznik.start() ; // przycisk start "odblokowuje" licznik if (source == stop) mylicznik.stop() ; // przycisk stop "blokuje" licznik if (source == inc) { mylicznik.inc() ; // przycisk inc inkrementuje licznik licznik updatestate() ; // zaktualizuj stan GUI

Zdarzenia ItemEvent i TextEvent ItemEvent TextEvent ItemListener TextListener additemlistener addtextlistener itemstatechanged textvaluechanged

WindowListener W interfejsie WindowListener zdefiniowano 7 (słownie siedem) metod!: windowiconified(), windowclosing()... MoŜna w klasie deklarującej implementację tego interfejsu umieszczać puste implementacje nieinteresujących metod windowiconified() { //i skupić się tylko na wybranych public void windowclosing(windowevent we) { we.getwindow().dispose() ; System.exit(0) ; // implements... addwindowlistener(...)

Adaptery class EndTestLicznika extends WindowAdapter { public void windowclosing(windowevent we) { we.getwindow().dispose() ; System.exit(0) ; class... //... addwindowlistener(new EndTestLicznika); Obsługą zdarzeń okienkowych ramy zajmuje się osobny obiekt!

JFrame reftojframe. setdefaultcloseoperation(jframe.exit_on_close);

Osobne obiekty reagujące na zdarzenia od poszczególnych komponentów class ReakcjaNaPrzyciskStart implements ActionListener{ public void actionperformed(actionevent ae) { mylicznik.start() ; // przycisk start "odblokowuje" licznik a następnie zamawiamy dostarczanie zdarzeń: start.addactionlistener(new ReakcjaNaPrzyciskStart()) ; OK?...

Anonimowe klasy wewnętrzne start.addactiolistener(new ActionListener() { public void actionperformed(actionevent ae) { mylicznik.start() ; ) ;

Projektowanie własnych komponentów A component is an object having a graphical representation that can be displayed on the screen and that can interact with the user

public abstract class Component public Color getbackground() public Color getforeground() public Font getfont(), void setfont(font f) public Dimension getpreferredsize() public Dimension getsize(), int getwidth(), getheight public void paint(graphics g) public boolean contains(int x, int y) public void setenabled(boolean b)

paint(graphics g) Argumentem metody paint() jest kontekst graficzny związany z komponentem określający system współrzędnych, kolor, Font... Współrzędne przebiegają między pikselami

paintcomponent (Swing) public void paintcomponent(graphics g) { Graphics2D g2 = (Graphics2D) g;...

Metody klasy Graphics getcolor() - Gets this graphics context's current color setcolor(color) - Sets this graphics context's current color to the specified color. Subsequent graphics operations using this graphics context use this specified color. drawline(int, int, int, int) - Draws a line, using the current color, between two points in this graphics context's coordinate system. drawpolyline(int[], int[], int) - Draws a sequence of connected lines defined by arrays of x and y coordinates. The figure will not be closed if the first point differs from the last point.

Metody klasy Graphics c.d. drawrect(int, int, int, int) - Draws the outline of the specified rectangle using the current color of the graphics context.. fillrect(int, int, int, int) - Fills the specified rectangle with the context's current color. drawroundrect(int, int, int, int, int, int) - Draws an outlined round-cornered rectangle fillroundrect(int, int, int, int, int, int) - Fills the specified rounded corner rectangle draw3drect(int, int, int, int, boolean) - Draws a 3-D highlighted outline of the specified rectangle. The edges of the rectangle are highlighted so that they appear to be beveled and lit from the upper left corner. It is raised when the parameter is true.

Metody klasy Graphics c.d. fill3drect(int, int, int, int, boolean) - Paints a 3-D highlighted rectangle drawoval(int, int, int, int) - Draws the outline of an oval in the current color. When the last two parameters are equal, this method draws a circle. filloval(int, int, int, int) - Fills an oval bounded by the specified rectangle with the current color. drawarc(int, int, int, int, int, int) - Draws the outline of a circular or elliptical arc covering the specified rectangle. fillarc(int, int, int, int, int, int) - Fills a circular or elliptical arc covering the specified rectangle

Metody klasy Graphics c.d. drawstring(string, int, int) - Draws the text given by the specified string, using this graphics context's current font and color. getfont() - Gets the current font. getfontmetrics() - Gets the font metrics of the current font. setfont(font) - Sets this graphics context's font to the specified font.

Rysowanie tekstu fontmetrics = g.getfontmetrics();

Klasa Color Model RGB Color(float r, float g, float b) Color(int r, int g, int b) public static final Color black public static final Color BLACK...(blue, yellow, red, green,... brighter() darker()

Klasa Font Fonty fizyczne (TrueType, Helvetica, Palatino, HonMincho...) implementation dependent Fonty logiczne (Serif, SansSerif, Monospaced, Dialog, and DialogInput)-mapped to physical fonts Font(String name, int style, int size) style PLAIN, BOLD, ITALIC (BOLD ITALIC ) Size -? 12, 14,...

Źródło zdarzeń semantycznych Jeśli projektujemy komponent, który słuŝy uŝytkownikowi do przekazywania danych do programu powinien on wygenerować zdarzenie i rozesłać do zarejestrowanych słuchaczy.

Do wykonania Reagujemy na zdarzenia niskopoziomowe (mysz, klawiatura) Pewne działania uznajemy za wystarczające do wygenerowania zdarzenia semantycznego (uŝytkownik chce za pomocą tego komponentu zawiadomić aplikację i przekazać dane wejściowe)

Do wykonania c.d. Kreujemy obiekt odpowiedniego zdarzenia Rozsyłamy do zarejestrowanych słuchaczy (musimy w tym celu prowadzić rejestr słuchaczy, którzy za pomocą metod add...listener i remove...listener rejestrują się i rezygnują z usługi )

Centralka rejestracji słuchaczy public mycomponent extends Component { ActionListener actionlistener = null; public synchronized void addactionlistener(actionlistener l) { actionlistener = AWTEventMulticaster.add(actionListener, l); public synchronized void removeactionlistener(actionlistener l) { actionlistener = AWTEventMulticaster.remove(actionListener, l);

Klasa ActionEvent public ActionEvent(Object source, int id, String command) String getactioncommand() public static final int ACTION_PERFORMED

Kompas 9

import java.awt.*; import java.awt.event.*; public class Kompas extends Component implements MouseListener{ int azymut = 0; int newazymut; boolean pressed = false; boolean entered = false; ActionListener actionlistener;//refers to a list of ActionListener objects public Kompas() { // konstruktor bezargumentowy this(0); //end of constructor public Kompas(int azymut) { // konstruktor this.azymut = this.newazymut = 0 ; addmouselistener(this); //end of constructor

public void addactionlistener(actionlistener listener) { actionlistener = AWTEventMulticaster.add(actionListener, listener); //end addactionlistener() //----------------------------------------------------------------------- //The following method removes ActionListener objects from the list // described above public void removeactionlistener(actionlistener listener) { actionlistener = AWTEventMulticaster.remove(actionListener, listener); //end removeactionlistener public Dimension getminimumsize() {//overridden getminimumsize() return new Dimension(100, 100); //end getminimumsize() public Dimension getpreferredsize() {//overridden getpreferredsize() return new Dimension(100, 100);

public void paint(graphics g) { Dimension d = getsize(); int r,w,h; r = Math.min(d.height,d.width); h = d.height ; w = d.width ; g.setcolor(color.gray); g.filloval((w-r)/2,(h-r)/2,r-1,r-1); g.setcolor(color.green); if (entered) g.filloval((w-r-2)/2,(h-r-2)/2,r-5,r-5); g.setcolor(color.red); int alfa = 90 - azymut; g.drawline(w/2, h/2, w/2 + (int) (r/2*math.cos(alfa*math.pi/180)), h/2 - (int) (r/2*math.sin(alfa*math.pi/180)) );

// paint c.d. setfont(new Font("Helvetica", Font.BOLD, 14)); g.drawstring("s", w/2-4,(h+r)/2-4); g.drawstring("w", (w-r)/2, h/2 +5); g.setcolor(color.black); g.fill3drect(w/2-20, h/2-20, 40, 20, false); g.setcolor(color.red); setfont(new Font("Helvetica", Font.BOLD, 16)); g.drawstring(new Integer(newAzymut).toString(), w/2-10, h/2-5);

Oddziaływanie na komponent public void setazymut(int newazymut) { this.newazymut = newazymut; repaint(); public int getazymut() { return(newazymut);

Reakcja na operacje myszką public void mouseentered(mouseevent me) { entered = true; repaint(); public void mouseexited(mouseevent me) { entered = false; pressed=false; repaint(); public void mousepressed(mouseevent me) { pressed = true; repaint();

Generacja zdarzenia semantycznego public void mousereleased(mouseevent me) { int x,y; if(pressed == true) { pressed = false; x=me.getx(); y=me.gety(); double yy = (getsize().height/2.0-y); double xx = (x-getsize().width/2.0) ; newazymut = 90 - (int) (180/Math.PI*Math.atan(yy/xx) ); if (xx<0) newazymut+= 180; azymut = newazymut ; repaint(); if(actionlistener!=null) actionlistener.actionperformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,??? ")); // ignorujemy zwolnienie przycisku poza komponentem!

Zdarzenia a klasa Licznik Czy przepełnienie licznika moŝe spowodować wykreowanie zdarzenia (Action) i dostarczenie do zarejestrowanych słuchaczy?