Programowanie komponentowe

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

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

InsERT GT Własne COM 1.0

Dziedziczenie : Dziedziczenie to nic innego jak definiowanie nowych klas w oparciu o już istniejące.

0.1 Hierarchia klas Diagram Krótkie wyjaśnienie

WYMAGANIA EDUKACYJNE I KRYTERIA OCENIANIA Z PRZEDMIOTU PROGRAMOWANIE APLIKACJI INTERNETOWYCH

System Informatyczny CELAB. Przygotowanie programu do pracy - Ewidencja Czasu Pracy

Spis treści 1. Wstęp 2. Projektowanie systemów informatycznych

Aplikacje internetowe i rozproszone - laboratorium

Opis obsługi systemu Ognivo2 w aplikacji Komornik SQL-VAT

ECDL Advanced Moduł AM3 Przetwarzanie tekstu Syllabus, wersja 2.0

SKRÓCONA INSTRUKCJA OBSŁUGI ELEKTRONICZNEGO BIURA OBSŁUGI UCZESTNIKA BADANIA BIEGŁOŚCI

INSTRUKCJA WebPTB 1.0

Praca na wielu bazach danych część 2. (Wersja 8.1)

Chmura obliczeniowa. do przechowywania plików online. Anna Walkowiak CEN Koszalin

Spis treści. Rozdział 1 ewyniki. mmedica - INSTR UKC JA UŻYTKO W NIKA

Microsoft Management Console

Kancelaris - Zmiany w wersji 2.50

Bazy danych. Andrzej Łachwa, UJ, /15

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

Instrukcja programu PControl Powiadowmienia.

Kompozycja i dziedziczenie klas

Opis zmian funkcjonalności platformy E-GIODO wprowadzonych w związku z wprowadzeniem możliwości wysyłania wniosków bez podpisu elektronicznego

Politechnika Warszawska Wydział Matematyki i Nauk Informacyjnych ul. Koszykowa 75, Warszawa

Zintegrowane Systemy Zarządzania Biblioteką SOWA1 i SOWA2 SKONTRUM

Bazy danych II. Andrzej Grzybowski. Instytut Fizyki, Uniwersytet Śląski

Budowa systemów komputerowych

Instrukcja Obsługi STRONA PODMIOTOWA BIP

Konfiguracja historii plików

Oprogramowanie FonTel służy do prezentacji nagranych rozmów oraz zarządzania rejestratorami ( zapoznaj się z rodziną rejestratorów FonTel ).

VLAN Ethernet. być konfigurowane w dowolnym systemie operacyjnym do ćwiczenia nr 6. Od ćwiczenia 7 należy pracować ć w systemie Linux.

Tomasz Greszata - Koszalin

Instrukcja obsługi Norton Commander (NC) wersja 4.0. Autor: mgr inż. Tomasz Staniszewski

dbsamples.udl lub przygotowany wcześniej plik dla Excela) i OK,

Uniwersytet Rzeszowski

Rozwiązywanie nazw w sieci. Identyfikowanie komputerów w sieci

Wartości domyślne, szablony funkcji i klas

Systemy mikroprocesorowe - projekt

Instalacja. Zawartość. Wyszukiwarka. Instalacja Konfiguracja Uruchomienie i praca z raportem Metody wyszukiwania...

Automatyzacja procesu publikowania w bibliotece cyfrowej

System kontroli wersji SVN

Projektowanie bazy danych

Pierwsze kroki. Krok 1. Uzupełnienie danych własnej firmy

Archiwum Prac Dyplomowych

Specyfikacja techniczna banerów Flash

Pracownia internetowa w każdej szkole. Opiekun pracowni internetowej SBS 2003 PING

Wdrożenie modułu płatności eservice dla systemu Virtuemart 2.0.x

Centrum Informatyki "ZETO" S.A. w Białymstoku. Instrukcja użytkownika dla urzędników nadających uprawnienia i ograniczenia podmiotom w ST CEIDG

Aktualizacja CSP do wersji v7.2. Sierpień 2014

Aplikacje internetowe oparte na kluczowych technologiach Java Enterprise(Servlet,JSP,JDBC, )

System zarządzania bazą danych (SZBD) Proces przechodzenia od świata rzeczywistego do jego informacyjnej reprezentacji w komputerze nazywać będziemy

Oprogramowanie klawiatury matrycowej i alfanumerycznego wyświetlacza LCD

Zarządzanie projektami. wykład 1 dr inż. Agata Klaus-Rosińska

Zaawansowane Aplikacje Internetowe

W dobie postępującej digitalizacji zasobów oraz zwiększającej się liczby dostawców i wydawców

G PROGRAMMING. Part #4

GEO-SYSTEM Sp. z o.o. GEO-RCiWN Rejestr Cen i Wartości Nieruchomości Podręcznik dla uŝytkowników modułu wyszukiwania danych Warszawa 2007

Instrukcja dotycząca generowania klucza dostępowego do Sidoma v8

elektroniczna Platforma Usług Administracji Publicznej

INSTRUKCJA DO PROGRAMU LICZARKA 2000 v 2.56

I. Zakładanie nowego konta użytkownika.

Wtedy wystarczy wybrać właściwego Taga z listy.

Miejski System Zarządzania - Katowicka Infrastruktura Informacji Przestrzennej

INSTRUKCJA RUCHU I EKSPLOATACJI SIECI DYSTRYBUCYJNEJ

Poniżej instrukcja użytkowania platformy

PERSON Kraków

INFORMATOR TECHNICZNY WONDERWARE

Przekształcenie danych przestrzennych w interaktywne mapy dostępne na stronach www (WARSZTATY, poziom podstawowy)

Harmonogramowanie projektów Zarządzanie czasem

JĘZYK UML JAKO NARZĘDZIE MODELOWANIA PROCESU PROJEKTOWO-KONSTRUKCYJNEGO

Jak usprawnić procesy controllingowe w Firmie? Jak nadać im szerszy kontekst? Nowe zastosowania naszych rozwiązań na przykładach.

enova Workflow Obieg faktury kosztowej

Przedmiot: Projektowanie dokumentów WWW. Laboratorium 3: Strona domowa cz. III Formularze. Opracował: Maciej Chyliński

Logowanie do systemu Faktura elektroniczna

API transakcyjne BitMarket.pl

WYMAGANIA EDUKACYJNE Przedmiot: Podstawy technik komputerowych technik informatyk. klasa 1, 3 godziny tygodniowo

VinCent Office. Moduł Drukarki Fiskalnej

Droga do DCOM DCOM (1996) Windows clipboard (1987) OLE 1 DDE (1992) OLE 2 (1993) COM (1995) Distributed computing (1980s)

INTERAKTYWNA APLIKACJA MAPOWA MIASTA RYBNIKA INSTRUKCJA OBSŁUGI

Postanowienia ogólne. Usługodawcy oraz prawa do Witryn internetowych lub Aplikacji internetowych

Firma Informatyczna JazzBIT

1. Korzyści z zakupu nowej wersji Poprawiono Zmiany w słowniku Stawki VAT Zmiana stawki VAT w kartotece Towary...

Sieć komputerowa grupa komputerów lub innych urządzeo połączonych ze sobą w celu wymiany danych lub współdzielenia różnych zasobów, na przykład:

Regulamin korzystania z wypożyczalni online Liberetto. z dnia r., zwany dalej Regulaminem

8. Konfiguracji translacji adresów (NAT)

Projektowanie i programowanie obiektowe (materiały do wykładu cz. VI)

Strategia rozwoju kariery zawodowej - Twój scenariusz (program nagrania).

Programowanie obiektowe

Regulamin Usługi Certyfikat SSL. 1 Postanowienia ogólne

Co nowego w systemie Kancelaris 3.31 STD/3.41 PLUS

Integracja systemów, integracja procesów

Zdalne odnawianie certyfikatów do SWI


Zainstalowana po raz pierwszy aplikacja wymaga aktualizacji bazy danych obsługiwanych sterowników.

Tytuł pracy. Praca dyplomowa inżynierska. Filip Piechocki. Tytuł Imię i Nazwisko

Sieci komputerowe cel

Instrukcja wgrywania synoptyki pola (wersja modelu danych do 634)

Nowe funkcjonalności

Komunikacja w sieci Industrial Ethernet z wykorzystaniem Protokołu S7 oraz funkcji PUT/GET

Transkrypt:

Programowanie komponentowe Henryk Budzisz wersja 1.0 Koszalin 2006 Wprowadzenie Beans COM NET XML CORBA H.Budzisz

Program wykładów Wprowadzenie Technologia JavaBeans Technologia CORBA Technologie COM/DCOM/COM+ Technologia.NET Technologia XML Wprowadzenie Beans COM NET XML CORBA H.Budzisz 2

Wprowadzenie Koncepcje Komponent programowy Technologie Wprowadzenie Beans COM NET XML CORBA H.Budzisz 3

Klejenie aplikacji Programowanie komponentowe (PK) jest procesem tworzenie aplikacji (systemu informatycznego) poprzez sklejanie jej z gotowych, odpowiednio przygotowanych, wymiennych komponentów programowych. Budowanie aplikacji z komponentów jest często porównywane do budowania (żargonowo klejenia) układu (urządzenia) elektronicznego z gotowych, seryjnych komponentów elektronicznych (scalaków, tranzystorów, przełączników). Zarówno w jednym jak i w drugim przypadku, komponenty muszą być przystosowane do tego klejenia (wykonane według określonych standardów). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 4

Zastępowalność Podstawowym celem praktycznym PK, jest stworzenie warunków do łatwej zastępowalności komponentów. Systemy informatyczne podlegają ciągłym zmianom. Jest to proces kosztowny i często naruszający niezawodność oprogramowania. Możliwość zastąpienia komponentu przez jego nową wersję lub zupełnie inną implementację, bez potrzeby rozmontowywania całego systemu, jest niezwykle atrakcyjna z praktycznego punktu widzenia. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 5

Programowanie komponentowe a programowanie obiektowe Komponent musi odpowiadać specyfikacjom określonym dla danej technologii. Sposób implementacji komponentu nie jest narzucany. Ponieważ idee programowania komponentowego i programowania obiektowego w dużym stopniu pokrywają się, komponenty są zwykle definiowane poprzez klasy. Klasy definiujące komponenty muszą spełniać wymagania określone w specyfikacji, np. zapewnić serializację, mechanizmy łączenia i komunikacji, samoinstalację itp. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 6

Komponent programowy Komponent jest wyizolowaną (autonomiczną) jednostką programową, która zgodnie z przyjętymi standardami: zawiera dane i metody realizujące operacje na tych danych niezależnie od otoczenia (hermetyzacja) udostępnia zestaw oferowanych usług poprzez interfejs programowy. zapewnia komunikację z innymi komponentami. zapewnia utrwalanie i odtwarzanie stanu wewnętrznego. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 7

Technologie JavaBeans wprowadzona do języka Java już od pierwszej wersji. CORBA (ang. Common Object Request Broker Architecture ) COM (ang. Component Object Model) opracowana przez Microsoft; następnie rozszerzona do DCOM i COM+.NET lansowana przez Microsoft jako następca COM/DCOM/COM+ XML nowy zawodnik w grze komponentowej Wprowadzenie Beans COM NET XML CORBA H.Budzisz 8

Technologie sieciowe Wraz z rozwojem programowania sieciowego i rozproszonego wspomniane technologie zostały zostały rozszerzone: EJB Enterprice Java Beans firmy Sun CCM CORBA Component Model DCOM/COM+ - rozszerzenie technologii COM Wprowadzenie Beans COM NET XML CORBA H.Budzisz 9

Mój klej jest lepszy od twojego kleju Jaką technologię klejenia wybrać? Patrząc z odległości 1000 m, efekt klejenia w każdej technologii jest podobny. Podstawowe koncepcje są wspólne. Z bliska jednak dostrzegamy, że w każdej technologii stosuje się zdecydowanie różne techniki i style programowania dla osiągnięcia celu. Każda technologia komponentowa ma swoich zwolenników. Na razie nie widać przegranych. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 10

Technologia JavaBeans Wprowadzenie Budowa komponentu Bean Zdarzenia Refleksja i introspekcja Serializacja Podsumowanie Wprowadzenie Beans COM NET XML CORBA H.Budzisz 11

Wprowadzenie Definicja komponentu Bean Cechy komponentu Bean Komponenty wizualne Środowiska programowe Przykład: pakiet ICEBrowser Wprowadzenie Beans COM NET XML CORBA H.Budzisz 12

Definicja Bean jest obiektem, którego właściwości i funkcjonalność mogą być odczytywane i zmieniane zgodnie z określonym protokołem (JavaBean specification). Protokół ten określa zasady komunikacji pomiędzy Beanem, a otoczeniem (zwykle środowiskiem wizualnym). Definiując Bean definiujemy klasę, uwzględniając konwencje narzucone przez specyfikacje standardu. Nakład dodatkowej pracy na bycie komponentem Bean jest niewielki. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 13

Cechy komponentu Bean Komponenty Bean mają wspólne cechy: Wsparcie dla introspekcji (ang. introspection) - udostępnianie informacji o właściwościach i obsługiwanych zdarzeniach. Wsparcie dla dostosowywania (ang. customization) ustawiania wyglądu i zachowania komponentu. Wsparcie dla obsługi zdarzeń (ang. events) komunikacji między komponentami Wsparcie dla utrwalania (ang. persistency) zapisywania i odczytywania informacji o stanie komponentu do/z pliku. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 14

Komponenty wizualne Większość komponentów Bean jest definiowana jako komponenty wizualne (zawierają metodę public void paint(graphics g) {... }). Takie komponenty wyprowadzane są z klasy java.awt.component (lub klas pochodnych), aby mogły być umieszczane w kontenerach. Klasy bibliotek AWT i Swing są komponentami Bean. Komponenty, które nie są wizualne (np. Timer lub ButtonGroup z biblioteki Swing), nie muszą być wyprowadzone z żadnej konkretnej klasy. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 15

Środowiska programowe Przykłady programowe zademonstrowane zostaną w dwóch środowiskach: RealJ bardzo proste środowisko tekstowe, dające pełną kontrolę nad tekstem źródłowym programu (środowisko niczego nie dopisuje ). NetBeans złożone środowisko graficzne dużo ułatwień, ale łatwo też stracić kontrolę nad tym co się dzieje w projekcie i w tekstach źródłowych. Popularnym środowiskiem graficznym jest Eclipse. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 16

Pakiet ICEBrowser Zestaw komponentów do budowania przeglądarki dokumentów HTML pochodzących z różnych żródeł (z połączenia HTTP, z anonimowego połączenia FTP, z lokalnego dyskowego systemu plikowego, z pliku spakowanego.jar, ze strumienia javowego Reader) Pakiet zrealizowany został w firmie ICEsoft Technologies, Inc. (www.icesoft.com). Wersja komercyjna jest bardziej rozbudowana i występuje w produktach wielu firm (Sun, Novell, Oracle,...). Komponenty zawarte są w pliku spakowanym icebrowserbean.jar. Dostępna jest również dokumentacja i przykłady użycia komponentów. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 17

Komponenty ICEBrowser Pakiet ice.htmlbrowser zawiera oprócz klas pomocniczych trzy komponenty: Document komponent interpretujący hipertekst i zarządzający dokumentami HTTP. Zbudowany na bazie klasy Panel biblioteki AWT. Browser komponent na bazie klasy Document, umożliwiający dostęp do hipertekstu pochodzącego z różnych źródeł, prowadzenie historii, itp. ICEBrowser gotowy aplet reprezentujący przeglądarkę dokumentów hipertekstowych. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 18

Komponent Document Dostępnych jest ok. 70 metod. Wybrane metody: gotolocation ustawia wskazany dokument w głównej ramce get-/setcurrentlocation pobiera/ustawia dokument w bieżącej ramce get-/setcurrentframe pobiera/ustawia bieżącą ramkę get-/setdocumenttitle pobiera/ustawia tytuł dokumentu getselectedtext pobiera zaznaczony tekst reload ponownie załadowuje dokument (odświeżanie) add-/removemouseoverlinklistener obsługa zdarzeń dot. linków add-/removepropertychangelistener obsługa zdarzeń dot. właściwości firepropertychange wygenerowanie zdarzenia dot. zmiany właściwości search wyszukuje podany tekst w dokumencie printdoc organizuje wydruk dokumentu HTML lub ramki Wprowadzenie Beans COM NET XML CORBA H.Budzisz 19

Komponent Browser Browser dziedziczy metody komponentu Document, a ponadto zawiera 12 własnych metod. Wybrane metody: gotolocation załaduj dokument HTML goback wróć do poprzedniego dokumentu goforward wróć do dokumentu wcześniejszego getbackhistory zwróć historię odwiedzin getforwardhistory - zwróć historię odwiedzin get-/setcachesize podaj/ustaw rozmiar buforu dokumentów Wprowadzenie Beans COM NET XML CORBA H.Budzisz 20

Zastosowania komponentów ICEBrowser do budowy systemu pomocy on-line dla aplikacji. dostęp do stron www z poziomu aplikacji. budowanie interfejsu dla aplikacji rozproszonych. Przykłady: HTMLBrowser\demo1 (RealJ) HTMLBrowser\TestHTMLBrowser1 (NetBeans) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 21

Budowa komponentu Bean Konstruktor bezparametrowy Właściwości i akcesory Właściwości proste Właściwości logiczne Właściwości indeksowane Właściwości związane i ograniczone Metody publiczne komponentu Wprowadzenie Beans COM NET XML CORBA H.Budzisz 22

Konstruktor bezparametrowy Komponent JavaBeans musi zawierać konstruktor bezparametrowy, np.: void Button() {... } Umożliwia to dynamiczne ładowanie klasy i tworzenie obiektu przy użyciu metody Bean.instantiate(...) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 23

Właściwości i akcesory Właściwość (ang. property) jest definiowana poprzez nazwę funkcji nazywanej akcesorem (ang. accessor). Nazwa ta rozpoczyna się przedrostkiem get-, set- lub is-. Getter jest akcesorem służącym do pobierania wartości właściwości. Przykład: getlabel definiuje właściwość label (zmiana wielkości pierwszej litery) Setter służy do ustawiania właściwości, np.: setcolor definiuje właściwość color. Zmiana właściwości jest często uzgadniana z innymi komponentami. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 24

Właściwości proste Właściwość prosta ma pojedynczą wartość. Getter: <typ właściwości> get<nazwa właściwości> () { <definicja> } Setter: void set<nazwa właściwości> (<typ właściwości>) { <definicja> } Przykład definiowania właściwości prostej foreground: private Color color; // zmienna pomocnicza // definicja akcesorów public Color getforeground() // getter { return color; } public void setforeground(color c) // prosty setter { color = c; } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 25

Fragment kodu klasy AbstractButton.java (Sun Microsystems) /** * Returns the button's text. * @return the buttons text * @see #settext */ public String gettext() { return text; } /** * Sets the button's text. * @param text the string used to set the text * @see #gettext * @beaninfo * bound: true * preferred: true * attribute: visualupdate true * description: The button's text. */ public void settext(string text) { String oldvalue = this.text; this.text = text; firepropertychange(text_changed_property, oldvalue, text); updatedisplayedmnemonicindex(text, getmnemonic()); if (accessiblecontext!= null) { accessiblecontext.firepropertychange( AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, oldvalue, text); } if (text == null oldvalue == null!text.equals(oldvalue)) { revalidate(); repaint(); } } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 26

Właściwości logiczne Właściwość logiczna jest właściwością prostą typu boolean, ale ma inne akcesory. Getter: boolean is<nazwa właściwości> () { <definicja> } Setter: void set<nazwa właściwości> (boolean) { <definicja> } Przykład: private boolean selected; // definicja akcesorów public boolean isselected() // getter { return selected; } public void setselected(boolean sel) // prosty setter { selected = sel; } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 27

Fragment kodu klasy AbstractButton.java (Sun Microsystems) /** * Returns the state of the button. True if the * toggle button is selected, false if it's not. * @return true if the toggle button is selected, otherwise false */ public boolean isselected() { return model.isselected(); } /** * Sets the state of the button. Note that this method does not * trigger an <code>actionevent</code>. * Call <code>doclick</code> to perform a programatic action change. * * @param b true if the button is selected, otherwise false */ public void setselected(boolean b) { boolean oldvalue = isselected(); model.setselected(b); } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 28

Właściwości indeksowane Właściwość indeksowana jest tablicą elementów. Getter elementu: <typ właściwości> get<nazwa właściwości> (int) { <definicja> } Setter elementu: void set<nazwa właściwości> (int, <typ właściwości>) { <definicja> } Getter tablicy: <typ właściwości>[] get<nazwa właściwości> () { <definicja> } Setter tablicy: void set<nazwa właściwości> (<typ właściwości>[]) { <definicja> } Przykład: void setwykaz (String[]) {... } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 29

Właściwości związane i ograniczone Właściwości komponentu mogą być związane (ang. bounded), tzn. o zmianie tej właściwości informowane są inne komponenty i reagują na tą zmianę. Właściwości komponentu mogą być ograniczane (ang. constrained), tzn. o zmianie powiadamiane są inne komponenty; zmiana dochodzi do skutku jeżeli żaden z powiadomionych komponentów nie zawetuje zmiany. Mechanizm ten funkcjonuje w oparciu o generowanie i rozsyłanie odpowiednich zdarzeń. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 30

Metody publiczne komponentu Metody publiczne komponentu są często wykorzystywane w trakcie komunikacji pomiędzy komponentami (są wywoływane w trakcie obsługi zdarzeń przychodzących z innych komponentów). Metody te powinny być synchronizowane dla zapewnienia poprawnej obsługi wywołań pochodzących z różnych wątków. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 31

Zdarzenia Koncepcja Hierarchia zdarzeń Tworzenie słuchacza Przyłączanie słuchacza Adaptery Anonimowe klasy wewnętrzne Klasa narzędziowa PropertyChangeSupport Rozgłaszanie zmian właściwości Wetowanie zmian właściwości Wprowadzenie Beans COM NET XML CORBA H.Budzisz 32

Koncepcja Źródło zdarzenie Słuchacz Programowa realizacja: Utworzyć obiekt Słuchacza (obiekt klasy implementującej interfejs nasłuchu lub klasy potomnej z adaptera). Przyłączyć obiekt słuchacza do jednego lub większej liczby komponentów. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 33

Object EventObject Hierarchia zdarzeń PropertyChangeEvent AWTEvent ActionEvent AdjustmentEvent ItemEvent TextEvent ComponentEvent ContainerEvent WindowEvent FocusEvent InputEvent KeyEvent MouseEvent Wprowadzenie Beans COM NET XML CORBA H.Budzisz 34

gdzie: Zdarzenie ActionEvent ActionEvent(Object source, int id, String command) source - odniesienie na obiekt, który jest źródłem zdarzenia; słuchacz może użyć metody getsource aby pobrać to odniesienie. id identyfikator liczbowy (zwykle stała ACTION_PERFORMED); słuchacz może użyć metody getid command dowolny łańcuch, np. etykietka przycisku albo nazwa opcji menu; słuchacz może użyć metody getactioncommand Przykład generowania zdarzenia: ActionEvent action = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, label); Powiadamianie przyłączonego słuchacza o zdarzeniu action: listener.actionperformed(action); Wprowadzenie Beans COM NET XML CORBA H.Budzisz 35

Zdarzenie MouseEvent public MouseEvent(Component source, int id, long when, int modifiers, int x, int y, int clickcount, boolean popuptrigger) Parametry: source odniesienie na żródło zdarzeń id identyfikator liczbowy (patrz: dokumentacja JDK) when czas powstania zdarzenia. modifiers modyfikator wskazujący na użycie klawisza modyfikującego (np.: shift, ctr, alt). x, y- współrzędne kursora myszki. clickcount liczba kliknięć myszki związanych ze zdarzeniem. popuptrigger zmienna logiczna; prawdziwa jeżeli zdarzenie wyzwala menu rozwijane. Parametry te są dostępne z poziomu słuchacza poprzez gettery. Przykład: demo2.java klasa Nawigacja funkcja mousereleased (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 36

Zdarzenie PropertyChangeEvent PropertyChangeEvent(Object source, String propertyname, Object oldvalue, Object newvalue) Parametry: source komponent JavaBean, który jest źródłem zdarzenia. propertyname nazwa właściwości, która została zmieniona. oldvalue poprzednia wartość właściwości. newvalue nowa wartość właściwości. Przykład generowania zdarzenia: PropertyChangeEvent propevt = new PropertyChangeEvent(this, text, oldtxt, newtxt); Jeżeli wartość właściwości jest typu prostego (np. int), musi być przekształcona w obiekt klasy opakowującej (dla int jest to Integer) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 37

Tworzenie słuchacza Słuchacz - to klasa, która może obsługiwać zdarzenie. Każda klasa, która implementuje interfejs nasłuchu staje się Słuchaczem, np.: public class MojaKlasa implements ActionListener {... } Każda klasa implementująca interfejs musi zdefiniować metody interfejsu. Dla interfejsu ActionListener jest to: public void actionperformed(actionevent e) { // instrukcje obsługujące zdarzenie } Klasa-słuchacz może też implementować większą liczbę interfejsów nasłuchu (określamy w ten sposób zestaw obsługiwanych zdarzeń). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 38

EventListener Interfejsy nasłuchu ActionListener Action WindowListener MouseListener MouseInputListener MouseMotionListener MenuListener PropertyChangeListener VetoableChangeListener Wprowadzenie Beans COM NET XML CORBA H.Budzisz 39

Interfejsy nasłuchu zmian właściwości Interfejs PropertyChangeListener ma jedną metodę: public void propertychange(propertychangeevent e) Interfejs VetoableChangeListener również ma jedną metodę: public void vetoablechange(propertychangeevent e) throws PropertyVetoException Schemat definiowania słuchacza: public class Listener implements PropertyChangeListener {... public void propertychange(propertychangeevent e) {... } // propertychange... } Przykład: demo6.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 40

Przyłączanie słuchacza Wszystkie komponenty JavaBeans powinny umożliwiać przyłączanie/odłączanie określonych typów Słuchaczy. Służą do tego metody: addxxxlistener() oraz removexxxlistener(), gdzie XXX jest typem słuchacza. Np.: zdarzenie ActionEvent może być obsłużone przez Słuchacza implementującego interfejs ActionListener; Słuchacz taki może być przyłączony do komponentów, które mają dostęp do metody addactionlistener(). Są to: Button, List, TextField, MenuItem oraz klasy pochodne. Przykład: Słuchacz słuchacz = new Słuchacz(); przyciskok.addactionlistener(słuchacz); Przykład programowy Demo2.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 41

Rejestracja słuchaczy (AWTEventMulticaster) Przykład użycia klasy bibliotecznej java.awt.awteventmulticaster do rejestrowania słuchaczy w komponencie AWT (JDK Help) 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); } public void processevent(awtevent e) { // when event occurs which causes "action" semantic ActionListener listener = actionlistener; if (listener!= null) { listener.actionperformed(new ActionEvent()); } } } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 42

Rejestracja słuchaczy w kontenerze // Utility field holding table of ActionListeners. // Generic type is used to declare this container. private Vector<ActionListener> listeners = new Vector<ActionListener>(); // Registers ActionListener to receive events. public synchronized void addactionlistener(actionlistener listener) { listeners.addelement(listener); } // Removes ActionListener from the list of listeners. public synchronized void removeactionlistener(actionlistener listener) { listeners.removeelement(listener); } // Notifies all registered listeners about the event. private void fireactionperformed(actionevent event) { Vector<ActionListener> targets; synchronized (this) { targets = (Vector<ActionListener>)listeners.clone(); } } for (ActionListener target : targets) target.actionperformed(event); Przykład (NetBeans) : OvalButton.java Wprowadzenie Beans COM NET XML CORBA H.Budzisz 43

Adaptery Implementację interfejsu można wykonać w pomocniczej klasie zwanej adapterem, a następnie zdefiniować klasę słuchacza jako rozszerzenie adaptera, np.: class WindowAdapter implements WindowListener { public void windowactivated(windowevent e) {} public void windowclosed(windowevent e) {} // następne metody } class Słuchacz extends WindowAdapter { // definicja potrzebnej metody } Pakiet java.awt.event zawiera takie adaptery. Przykład: Demo3.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 44

Anonimowe klasy wewnętrzne Klasa wewnętrzna jest definiowana wewnątrz innej klasy, np.: class KlasaZewnętrzna { class KlasaWewnętrzna {... }... } Klasa wewnętrzna może być zdefiniowana nawet wewnątrz funkcji. Klasa anonimowa, to klasa bez nazwy, definiowana w momencie tworzenia obiektu (tj. przy użyciu operatora new). Przykłady: Demo4.java, Demo5.java (RealJ) i TestHTMLBrowser2 (NetBeans) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 45

Klasa narzędziowa PropertyChangeSupport Wybrane metody klasy: public PropertyChangeSupport(Object sourcebean) // constructor public void addpropertychangelistener(propertychangelistener listener) public void removepropertychangelistener(propertychangelistener listener) public void firepropertychange(string propertyname, Object oldvalue, Object newvalue) public void firepropertychange(string propertyname, int oldvalue, int newvalue) public void firepropertychange(string propertyname, boolean oldvalue, boolean newvalue) public void firepropertychange(propertychangeevent evt) Dla właściwości ograniczonych stosuje się klasę VetoableChangeSupport. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 46

Rozgłaszanie zmian właściwości Setter, który zmienia właściwość związaną powinien powiadomić o tym wszystkich słuchaczy zmian właściwości (obiekty klas implementujących interfejs PropertyChangeListener) przyłączonych do komponentu, np.: private PropertyChangeSupport propertysupport = new PropertyChangeSupport(this);... public void seturl(string URL) { String oldurl = this.url; this.url = URL; propertysupport.firepropertychange("url", oldurl, URL); } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 47

Demonstruje: Przykład: HyperlinkedLabel Użycie klasy narzędziowej PropertyChangeSupport. Setter i getter właściwości hyperlinkcolor oraz URL. Zgłaszanie zmian właściwości hyperlinkcolor oraz URL. Implementację interfejsu MouseListener (jest słuchaczem zdarzeń MouseEvent). Sposób dodawania i usuwania słuchaczy akcji. Generowanie i rozsyłanie zdarzeń ActionEvent w odpowiedzi na kliknięcie myszki. Dorysowanie podkreślenia pod etykietką. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 48

Wetowanie zmian właściwości Setter, który zmienia właściwość ograniczoną powinien przed tą zmianą powiadomić wszystkich przyłączonych słuchaczy implementujących interfejs VetoableChangeListener, np.: public void setcount(int newcount) throws PropertyVetoException { int oldcount = count; // count - wartość właściwości vetoablechangesupport.firevetoablechange("count",oldcount,newcount); count = newcount; // przy braku wyjątku dochodzi do zmiany } Słuchacze mogą z przesłanego zdarzenia typu PropertyChangeEvent, odczytać (getnewvalue) proponowaną nową wartość. Jeżeli proponowana nowa wartość nie może być zaakceptowana, zgłaszany jest wyjątek PropertyVetoException. Zgłoszenie wyjątku przerywa wykonywanie dalszych instrukcji (do zmiany właściwości nie dochodzi) i następuje przejście do obsługi wyjątku. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 49

Przykład: Counter komponent JavaBeans klasa słuchacza wyjątek (exception) sterowanie wetowanie decbutton (JButton) addactionlistener addvetoablechangelistener limitator (Limitator) anonymous (ActionListener) decreace PropertyVetoExceprion addactionlistener anonymous settext counter (ActionListener) (Counter) setcounter (JTextField) increace ostrzeganie anonymous addpropertychangelistener (ActionListener) proplistener settext counterwarning (PropertyChangeListener) (JLabel) incbutton (JButton) addactionlistener Wprowadzenie Beans COM NET XML CORBA H.Budzisz 50

Podsumowanie Zasady definiowania komponentu JavaBeans: Klasę definiującą komponent należy zdefiniować jako serializowaną. Należy zdefiniować konstruktor bezparametrowy. Właściwości komponentu są zdefiniowane przez zestaw setterów i getterów (również odziedziczonych). Zdarzenia obsługiwane przez komponent określone są przez parę metod addxxxlistener/removexxxlistener (gdzie: XXX jest nazwą zdarzenia) zdefiniowanych w komponencie (lub odziedziczonych). Metody publiczne komponentu powinny być synchronizowane. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 51

Refleksja i introspekcja Automatyzacja tworzenia i dostosowywania komponentu Klasa Class Dynamiczne ładowanie klas Dynamiczne pobieranie metody Dynamiczne wywołanie metody Introspekcja Narzędzia graficzne Wprowadzenie Beans COM NET XML CORBA H.Budzisz 52

Automatyzacja tworzenia i dostosowywania komponentu Przeciągnięcie ikony komponentu z palety na obszar projektowanego interfejsu graficznego powoduje utworzenie obiektu tej klasy. Przy użyciu mechanizmu refleksji rozpoznaje się typ komponentu, a następnie stosując konstruktor bezparametrowy, tworzy się obiekt. Następnie, stosując introspekcję należy z komponentu wydobyć informacje o właściwościach, setterach, getterach, obsługiwanych zdarzeniach i dostępnych metodach publicznych (bez dostępu do kodu źródłowego). W końcu, przy użyciu mechanizmu refleksji, należy udostępnić wartości właściwości (z możliwością edycji) oraz przyłączyć stosownych słuchaczy. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 53

Klasa Class W trakcie wykonywania instrukcji: Button anuluj = new Button( Anuluj ); potrzebna jest definicja klasy java.awt.button. JVM odszukuje plik Button.class, dekoduje binarny format klasy, sprawdza kompatybilność z innymi klasami, weryfikuje sekwencję operacji kodu bajtowego, ładuje do pamięci i tworzy obiekt klasy Class zawierający metadane udostępniające informacje o modyfikatorach, konstruktorach, metodach i polach klasy Button. Dostęp do tego obiektu jest możliwy przez użycie metody getclass z klasy Object lub dodanie literału.class do nazwy klasy. Przykłady: Class c = anuluj.getclass(); Class c = java.awt.button.class; Przykład programowy: Introspekcja\ClassViewer.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 54

Dynamiczne ładowanie klas Jeżeli w trakcie realizacji programu potrzebny jest obiekt pewnej klasy, można ją odszukać i załadować przy użyciu metody forname z klasy Class, np.: Class c = null; try { c = Class.forName( beans.counter ); } catch (ClassNotFoundException ex) { // obsługa wyjątku } Obiekt załadowanej klasy można stworzyć przy użyciu metody newinstance z klasy Class, np.: Object Objekt object objekt = = null; new c(); try { object = c.newinstance(); } catch... Nie można użyć operatora new Wprowadzenie Beans COM NET XML CORBA H.Budzisz 55

Dynamiczne pobieranie metody W załadowanej klasie, dostępnej przez obiekt klasy Class (w przykładzie beanclass) występują pola i metody. Dostęp do zdefiniowanej metody uzyskuje się przez podanie jej nazwy i parametrów jako argumentów metody getmethod z klasy Class. // tablica parametrów odpowiadających argumentom metody Class[] parametertypes = new Class[] {String.class}; Method addtxt = null; try { addtxt = beanclass.getmethod("addtext", parametertypes); } catch (NoSuchMethodException ex) {...} Definicja metody jest reprezentowana przez obiekt klasy Method. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 56

Dynamiczne wywoływanie metody beanobject.addtxt( Anuluj ); Metodę reprezentowaną przez obiekt klasy Method (w przykładzie addtxt) wywołuje się stosując metodę invoke. Argumentami jej są: obiekt na rzecz którego jest wywoływana i argumenty wywołania. Object[] arguments = Anuluj ; try { addtxt.invoke(beanobject, arguments); } catch (IllegalArgumentException ex) {... } catch (InvocationTargetException ex) {... } catch (IllegalAccessException ex) {... } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 57

Podsumowanie W mechanizmie refleksji wykorzystuje się następujące klasy: java.lang.class reprezentuje klasę lub interfejs. java.lang.object udostępnia metodę getclass. java.lang.reflect.constructor udostępnia konstruktor klasy. Umożliwia dynamiczne tworzenie obiektu klasy. java.lang.reflect.method udostępnia metodę klasy. Umożliwia wywołanie metody. java.lang.reflect.field udostępnia pole klasy i dynamiczny dostęp do tego pola. java.lang.reflect.modifier udostępnia informacje o modyfikatorach definicji klasy (abstract, public, final). java.lang.reflect.array umożliwia dynamiczne deklarowanie tablic. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 58

Introspekcja Dynamicznie załadowany Bean musi zostać przebadany. Służy do tego klasa Introspector, umieszczając wynik badania w obiekcie klasy BeanInfo. Służy do tego metoda: getbeaninfo(class<?> beanclass, Class<?> stopclass) Następuje odczytanie informacji o właściwościach, metodach i zdarzeniach w podanej klasie beanclass oraz wszystkich klasach bazowych, aż do klasy stopclass (ale bez niej). Przykład: BeanInfo bi = null; try { bi = Introspector.getBeanInfo(bean, Object.class); } catch(introspectionexception e) { // obsługa wyjątku } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 59

Wynik introspekcji Informacje o właściwościach, getterach, setterach, zdarzeniach i metodach umieszczone są w obiektach odpowiednich klas (rysunek), zdefiniowanych w pakiecie java.beans. PropertyDescriptor[] descriptors = bi.getpropertydescriptors(); for(propertydescriptor d: descriptors) // extended for print("nazwa właściwości:\n " + d.getname()); // inne metody klasy PropertyDescriptor // getproperttype, getreadmethod, getwritemethod,... Przykład: BeanDumper.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 60

Sterowanie introspekcją Realizuje się przez zdefiniowanie klasy o nazwie: <nazwa komponentu>beaninfo, np.: JugglerBeanInfo implementującej interfejs BeanInfo. Ponieważ interfejs wymusza implementację ośmiu metod, wygodniejsze jest rozszerzenie pomocniczej klasy SimpleBeanInfo, np.: public class JugglerBeanInfo extends SimpleBeanInfo { } W klasie tej definiuje się metody wykorzystywane podczas introspekcji: BeanDescriptor getbeandescriptor() PropertyDescriptor[] getpropertydescriptors(); MethodDescriptor[] getmethoddescriptors(); EventSetDescriptor[] geteventsetdescriptors(); Definiując metodę geticon, można przypisać do komponentu ikonę. Przykład: JugglerBeanInfo.java (NetBeans) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 61

Narzędzia graficzne W środowisku graficznym nazwy komponentów są zastąpione przez ikony. Przeciągnięcie ikony z palety do obszaru projektowego powoduje utworzenie obiektu z użyciem konstruktora bezparametrowego. Poprzez introspekcję odczytane zostają właściwości komponentu oraz obsługiwane zdarzenia. Nazwy właściwości tworzą pierwszą kolumnę tabeli edycyjnej. Wartości właściwości są odczytywane przez gettery i tworzą drugą kolumnę tabeli edycyjnej. Do edycji właściwości używane są wyspecjalizowane edytory (koloru, czcionki, łańcuchów itp.). Nowe wartości są ustawiane w komponencie przez settery. W podobny sposób wiąże się zdarzenia z funkcjami odpowiedzi. Przykład: PropertyViewer.java (NetBeans) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 62

Serializacja komponentów Serializacja obiektu, czyli zapis stanu obiektu w pliku dyskowym realizuje metoda writeobject() z klasy ObjectOutputStream. Jest to klasa opakowująca dowolny strumień zdefiniowany przez klasę wyprowadzoną z klasy abstrakcyjnej OutputStream. Przykład: JButton przycisk = new JButton( Pomoc ); // serializacja obiektu przycisk ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream( przycisk.ser )); out.writeobject(przycisk); // pominięto wyjątki Klasy obiektów serializowanych muszą implementować interfejs Serializable. Interfejs ten nie zawiera żadnych metod. Składowe klasy, których nie chcemy serializować (hasła, zmienne pomocnicze itp.) oznaczamy słowem kluczowym transient. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 63

Deserializacja komponentów Deserializacja obiektu, czyli odczytanie stanu obiektu wcześniej zserializowanego realizuje metoda readobject() z klasy ObjectInputStream. Jest to klasa opakowująca dowolny strumień zdefiniowany przez klasę wyprowadzoną z klasy abstrakcyjnej InputStream. Przykład: ObjectInputStream in = new ObjectInputStream( new FileInputStream( przycisk.ser )); // deserializacja obiektu przycisk JButton przycisk = (JButton)in.readObject(); Przykład programowy: Serializacja.java i Deserializacja.java (RealJ). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 64

Serializacja do dokumentu XML Możliwa jest również serializacja przez utworzenie dokumentu tekstowego XML. Klasy ObjectOutputStream i ObjectInputStream zastępuje się odpowiednio przez klasy XMLEncoder i XMLDecoder zdefiniowane w pakiecie java.beans. Klasy te mają takie same metody odczytu i zapisu: readobject() i writeobject(). Przykład: SerializacjaXML.java i DeserializacjaXML.java (RealJ) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 65

Podsumowanie technologii JavaBeans Wprowadzenie Beans COM NET XML CORBA H.Budzisz 66

Technologia COM COM Interfejsy Technologia COM w Visual C++ Globally Unique Identifiers (GUIDs) Biblioteka COM Tworzenie obiektu COM Inteface IUnknown Definiowanie komponentu Wprowadzenie Beans COM NET XML CORBA H.Budzisz 67

COM co to jest? COM (Component Object Model) jest opracowaną przez Microsoft technologią umożliwiającą efektywną komunikację między aplikacjami Component Object Model definiuje: binarny standard wywoływania funkcji między komponentami, struktury interfejsów udostępnianych przez poszczególne obiekty, mechanizmy jednoznacznej identyfikacji komponentów i ich interfejsów. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 68

Klient Obiekt komponentowy (instancja komponentu) wskaźnik na VTBL (pole prywatne) Diagram binarnego standard wywoływania funkcji VTBL jest wspólna dla wszystkich klientów korzystających z danego komponentu COM Serwer wskaźnik na funkcję1 wskaźnik na funkcję2 wskaźnik na funkcję3 VTBL (tablica funkcji wirtualnych) funkcja1(pobj,arg1,arg2,...) {... } Implementacja komponentu COM zawarta zwykle w bibliotece DLL Wprowadzenie Beans COM NET XML CORBA H.Budzisz 69

Komponenty COM w jednym procesie Technologia COM definiuje sposób współpracy pomiędzy komponentem a jego klientem. W pojedynczym procesie, klient łączy się z komponentem bez pośrednich komponentów. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 70

Komponenty COM w różnych procesach Klient, który chce się skomunikować z komponentem musi skorzystać z pośrednictwa tzw. RPC stubs oraz obiektów Proxy, istniejących po obu stronach połączenia. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 71

Komponenty COM na różnych komputerach Jeżeli klient i komponent rezydują na różnych komputerach, w technologii DCOM (Distributed COM) komunikację międzyprocesorową zastępuje się protokołem sieciowym. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 72

COM Interfejsy Obiekty COM udostępniają swoje funkcje obiektom zewnętrznym za pośrednictwem interfejsów. Interfejs jest zestawem prototypów funkcji składowych komponentu COM (metod). Nazwy interfejsów przyjęło się poprzedzać przedrostkiem I, np.: ILookup Interfejs można zdefiniować na bazie innego interfejsu, czyli zastosować dziedziczenie (ale wyłącznie jednobazowe) Interfejs nie posiada własnej implementacji. Każdy komponent może implementować wiele interfejsów - oferować wiele zestawów usług. Klienty (aplikacje lub inne komponenty) odwołują się do interfejsów za pośrednictwem wskaźników. Każdy interfejs posiada własny, unikalny identyfikator - Globally Unique Identifier (GUID). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 73

Interfejsy Schemat implementacji interfejsu Każdy komponent może implementować wiele interfejsów - oferować wiele zestawów usług. IA IB Komponent COM (coclass) IC Komponent lub coclass (skrót od component object class) zawiera kod wszystkich funkcji udostępnianych przez interfejsy, funkcje pomocnicze i dane. Komponent jest umieszczony w serwerze COM - pliku binarnym (DLL lub EXE). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 74

Implementacja interfejsu Implementacja interfejsu (definicja komponentu) może być zrealizowana w różnych językach programowania. Komponenty mogą być używane przez inne komponenty lub aplikacje realizowane w różnych językach programowania. Technologia COM definiuje standardy komunikowania się na poziomie binarnym. Na poziomie źródłowym ta sama funkcja będzie kodowana zgodnie ze składnią danego języka, np.: Visual Basic object.add( Time As Double, Name As String ) As Variant C++ HRESULT Add( double Time, BSTR Name, VARIANT* pval ); Java public com.ms.com.variant Add( double Time, String Name ); Trzeba ponadto zapewnić konwersję typów danych. Szczegóły w dokumentacji MSDN (COM Language Translation). Wprowadzenie Beans COM NET XML CORBA H.Budzisz 75

Technologia COM w Visual C++ Preferowanym językiem implementacji jest C++. Interfejs jest definiowany jako klasa abstrakcyjna z czystymi funkcjami wirtualnymi. Do tworzonych obiektów automatycznie dołączana jest Vtable (tablica wywołań funkcji wirtualnych). W C trzeba taką tablicę samemu zdefiniować. Każda metoda musi mieć wskaźnik zwrotny na obiekt. W C++ automatycznie dodawany jest wskaźnik this. W C trzeba dodać do każdej funkcji dodatkowy parametr. Definicja klasy stanowi też automatycznie przestrzeń nazw dla składowych. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 76

Globally Unique Identifiers (GUIDs) Do identyfikacji każdego interfejsu i każdego komponentu, używany jest unikalny identyfikator (128-bitowa struktura; long + uint + uint + 8*char = 16 bajtów). Plik guiddef.h zawiera definicję struktury opisującej GUID i pomocnicze makrodefinicje, np.: DEFINE_GUID. Programista zamiast tego identyfikatora używa związanej z nim stałej symbolicznej IID_<nazwa interfejsu> lub CLSID_<nazwa komponentu>. Przykład definicji stałej IID_ILOOKUP: DEFINE_GUID(IID_ILOOKUP, 0xc4910d71, 0xba7d, 0x11cd, 0x94, 0xe8, 0x08, 0x00, 0x17, 0x01, 0xa8, 0xa3); Do generowania GUID udostępnione są programy narzędziowe (w Visual C++ Tools/Create GUID) oraz funkcja CoCreateGuid z COM API. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 77

Obsługa błędów Wszystkie funkcje COM w Visual C++ (z wyjątkiem AddRef i Release z interfejsu IUnknown) zwracają jako wynik wartość typu HRESULT zawierającą informacje o błędach (plik winerror.h wiersz 17 040). Typowy schemat obsługi błędów: HRESULT hr; hr = funkcja_com(parametry); if (hr == S_OK) { } // dalsze operacje... else cerr << Wywołanie funkcja_com nie powiodło się ; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 78

Makrodefinicje do obsługi błędów Powszechną praktyką jest wykorzystywanie do obsługi błędów makrodefinicji SUCCEEDED i FAILED, którym przekazuje się wynik wywołania funkcji typu HRESULT. Przykład: if ( FAILED( CoInitialize(NULL) )) { cerr << "Inicjacja nie powiodła się"; return 1; } Kod błędu można odczytać z HRESULT stosując makrodefinicję HRESULT_CODE. Opis tekstowy błędu (na podstawie jego kodu, np.: 0x800401F0) można uzyskać przy użyciu narzędzia Tools/Error Lookup w VC++. Opis jest widoczny również w debuggerze. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 79

Biblioteka COM COM library API udostępnia funkcje i makra do obsługi zadań związanych z definiowaniem i używaniem obiektów COM. Bibliotekę trzeba przed użyciem zainicjować przy użyciu funkcji HRESULT CoInitialize(LPVOID pvreserved); Schemat inicjacji: // Inicjacja biblioteki COM - załadowanie plików DLL. if ( FAILED( CoInitialize(NULL) )) { cerr << "Inicjacja biblioteki COM nie powiodła się" << endl; return 1; }... // Zwolnij zasoby przydzielone bibliotece COM. CoUninitialize(); Wprowadzenie Beans COM NET XML CORBA H.Budzisz 80

Tworzenie obiektu COM Aby otworzyć obiekt COM i uzyskać wskaźnik na interfejs stosuje się funkcję CoCreateInstance() z COM API HRESULT CoCreateInstance( REFCLSID rclsid, LPUNKNOWN punkouter, DWORD dwclscontext, REFIID riid, LPVOID* ppv); Parametry: rclsid identyfikator komponentu, np.: CLSID_ShellLink. punkouter używany przy agregacji obiektu COM (NULL gdy nie jest stosowana agregacja) dwclscontext rodzaj serwera; dla serwera DLL w tym samym procesie stosuje się stałą CLSCTX_INPROC_SERVER. riid - identyfikator interfejsu, np.: IID_IShelLink. ppv - wskaźnik na interfejs; parametr zwrotny funkcji. Zwracane wartości: S_OK, REGDB_E_CLASSNOTREG, CLASS_E_NOAGGREGATION lub E_NOINTERFACE. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 81

Interfejs IUnknown Podstawowym interfejsem implementowanym przez każdy obiekt COM jest interfejs IUnknown, udostępniający trzy funkcje: QueryInterface, AddRef, Release. IUnknown QueryInterface AddRef Release Komponent COM implementacja implementacja implementacja Wprowadzenie Beans COM NET XML CORBA H.Budzisz 82

IUnknown funkcje AddRef i Release Funkcje AddRef i Release zarządzają licznikiem referencji do interfejsów. AddRef jest wywoływana, gdy klient używa danego interfejsu i zwiększa licznik o 1. Release jest wywoływana, gdy klient nie potrzebuje już interfejsu i zmniejsza licznik. Obie zwracają nową wartość licznika referencji. Funkcja QueryInterface zostanie omówiona w dalszej części wykładu. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 83

Schemat tworzenia i użycia obiektu COM HRESULT hr; // zmienna przechowująca wynik wywołania IShellLink* pisl; // wskaźnik na interfejs hr = CoCreateInstance ( CLSID_ShellLink, // CLSID komponentu NULL, // nie używa się agregacji CLSCTX_INPROC_SERVER, // typ serwera IID_IShellLink, // IID interfejsu (void**) &pisl ); // zwracany wskaźnik if ( SUCCEEDED ( hr ) ) { // Wywołania metod komponentu z użyciem pisl... pisl->release(); // powiadom obiekt COM o zakończeniu } else { // Nie utworzono obiektu COM; hr zawiera kod błędu } Wprowadzenie Beans COM NET XML CORBA H.Budzisz 84

Przykład użycia komponentu Active Desktop Active Desktop jest usługą Internet Explorera pozwalającą na wyświetlanie stron www, dokumentów HTML, apletów Javy i komponentów ActiveX na tapecie (bez użycia przeglądarki; Uwaga! Spowalnia system). Działania zrealizowane w przykładzie: 1. Inicjalizacja biblioteki COM (funkcja CoInitialize). 2. Utworzenie obiektu COM typu ActiveDesktop i pobranie wskaźnika do interfejsu IActiveDesktop. 3. Wywołanie metody GetWallpaper() komponentu ActiveDesktop. 4. Jeżeli wywołanie zakończyło się powodzeniem wydrukowanie nazwy pliku przechowującego tapetę widoczną na pulpicie. 5. Pobranie przy użyciu metody GetDesktopItemCount() liczby elementów (stron www dodanych do listy) wydruk informacji. 6. Pobranie (w pętli) informacji o elementach (funkcja GetDesktopItem) do struktury COMPONENT i wydruk nazw elementów (stron www). 7. Zwolnienie interfejsu (funkcja Release) 8. Zwolnienie zasobów przydzielonych bibliotece COM (funkcja CoUninitialize). Przykład: C:\HB\Programowanie komponentowe\com\pulpit (project Pulpit1) Wprowadzenie Beans COM NET XML CORBA H.Budzisz 85

Łańcuchy w technologii COM uzupełnienie przykładu Łańcuchy zwracane przez funkcje COM kodowane są w Unikodzie (2 bajty na znak). Znak w Unikodzie definiowany jest w VC++ przez typ WCHAR, np.: char tekst1[80]; // zwykła tablica znakowa WCHAR tekst2[80]; // tablica znaków w Unikodzie Do przekształcenia tekstu Unikod na tekst ASCII służy funkcja WideCharToMultiByte(). Prostszym sposobem jest użycie klasy CString z biblioteki MFC, której konstruktor akceptuje zarówno łańcuchy ASCII jak i Unikod (konwersja polskich znaków jest poprawna), np.: CString str1(unicode_text); Strumień standardowy wcout akceptuje teksty wyłącznie w Unikodzie. Zwykły tekst musi być przekształcony w Unikod (prefiks L, np.: L Nazwa: ). Uwaga: nie radzi sobie z polskimi znakami przerywa wyprowadzanie. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 86

IUnknown funkcja QueryInferface Funkcja QueryInterface dostępna w każdym komponencie (ponieważ zdefiniowana jest w interfejsie IUnknown) pozwala na uzyskanie dostępu do innych interfejsów danego obiektu. Jej składnia jest następująca: HRESULT QueryInterface (REFIID iid, void** ppvobject); Parametry: iid - identyfikator GUID żądanego interfejsu ppvobject - wskaźnik do żądanego interfejsu; parametr zwrotny. Gdy interfejs jest dostępny, funkcja zwraca wartość S_OK. W przypadku, gdy interfejs nie jest zaimplementowany zwracana jest wartość E_NOINTERFACE. Wprowadzenie Beans COM NET XML CORBA H.Budzisz 87

Przykład użycia komponentu z wieloma interfejsami Zadaniem programu (Pulpit2) jest dodanie na pulpicie skrótu do własnego pliku exe. Etapy realizacji zadania: 1. Pobranie ścieżki do własnego pliku exe (GetModuleFileName). 2. Pobranie ścieżki do foldera pulpitu (SHGetSpecialFolderPath). 3. Uzupełnienie ścieżki o nazwę pliku typu.lnk zawierającego link. 4. Sprawdzenie czy plik już istnieje (CFile::GetStatus). 5. Przekształcenie ścieżki z nazwą pliku na łańcuch w Unikodzie (MultiByteToWideChar). 6. Inicjacja biblioteki COM (CoInitialize). 7. Utworzenie obiektu COM typu Shell Link (CoCreateInstance) i uzyskanie wskaźnika na interfejs IShellLink. 8. Ustawienie ścieżki do pliku, dla którego tworzony jest skrót (IShellLink::SetPath) 9. Uzyskanie wskaźnika na kolejny interfejs IPersistFile obiektu Shell Link (IShellLink::QueryInterface) 10. Zapisanie pliku skrótu do foldera pulpitu (IPersistFile::Save) 11. Zwolnienie interfejsów IPersistFile i IShellLink (Release) oraz CoUninitialize Wprowadzenie Beans COM NET XML CORBA H.Budzisz 88

Definiowanie komponentu Definiowanie interfejsu Makra i typy danych stosowane w definicjach Implementacja interfejsu Użycie biblioteki MFC Wprowadzenie Beans COM NET XML CORBA H.Budzisz 89

Definiowanie interfejsu Każdy interfejs komponentu COM musi być bezpośrednio lub pośrednio wyprowadzony z interfejsu IUnknown. Interfejs jest definiowany w języku IDL (Microsoft Interface Definition Language). Przykład: import "unknwn.idl"; // definicja interfejsu IUnknown [ object, uuid(4411b7fe-ee28-11ce-9054-080036f12502) ] interface ISome : IUnknown { HRESULT SomeMethod(void); }; [ object, uuid(4411b7fd-ee28-11ce-9054-080036f12502) ] interface ISomeOther : ISome { HRESULT SomeOtherMethod([in]long l); }; Definicja interfejsu zapisywana jest w pliku.idl Wprowadzenie Beans COM NET XML CORBA H.Budzisz 90

Definiowanie interfejsu w VC++ W SDK VC++ dostępna jest klasa IUnknown (plik nagłówkowy unknown.h) reprezentująca interfejs IUnknown. Z klasy tej można wyprowadzić własny interfejs stosując składnię C++, np.: // {15038B10-3D3E-11ce-9EE5-00AA004231BF} DEFINE_GUID(IID_IPrintInterface, 0x15038b10, 0x3d3e, 0x11ce, 0x9e, 0xe5, 0x0, 0xaa, 0x0, 0x42, 0x31, 0xbf); class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions virtual HRESULT QueryInterface(REFIID riid, LPVOID ppvobj)=0; virtual ULONG AddRef(void) = 0; virtual ULONG Release(void) = 0; // This interface virtual HRESULT PrintObject(void) = 0; }; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 91

Makra i typy danych stosowane w definicjach typedef struct _GUID { unsigned long Data1; // 32 bity unsigned short Data2; // 16 bitów unsigned short Data3; // 16 bitów byte Data4[ 8 ]; // 8*8 = 64 bity } GUID; // definicja Globally Unique Identifier, 128 bitów typedef GUID IID - identyfikator interfejsu; synonim GUID typedef IID* LPIID; - wskaźnik daleki na ID interfejsu #define REFIID const IID& - referencja na identyfikator interfejsu typedef GUID CLSID - identyfikator co-klasy; synonim GUID typedef CLSID* LPCLSID; - wskaźnik daleki na ID co-klasy typedef long HRESULT; - typ wyniku funkcji COM; synonim long Wprowadzenie Beans COM NET XML CORBA H.Budzisz 92

Konwencja wywoływania metod interfejsu W Microsoft C++ wprowadzono kilkanaście dodatkowych słów kluczowych (rozpoczynających się od ), które służą do sterowania kompilacją. Słowo kluczowe stdcall określa sposób wywołania wymagany przez funkcje Win32 API. class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions virtual HRESULT stdcall QueryInterface(REFIID riid, LPVOID ppvobj)=0; virtual ULONG stdcall AddRef(void) = 0; virtual ULONG stdcall Release(void) = 0; // This interface virtual HRESULT stdcall PrintObject(void) = 0; }; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 93

Makrodefinicja STDMETHODCALLTYPE Definicja: #ifdef _WIN32 // Win32 doesn't support export #define STDMETHODCALLTYPE stdcall #else #define STDMETHODCALLTYPE export stdcall #endif class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID ppvobj)=0; virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; virtual ULONG STDMETHODCALLTYPE Release(void) = 0; // This interface virtual HRESULT STDMETHODCALLTYPE PrintObject(void) = 0; }; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 94

Makra STDMETHODIMP_ oraz STDMETHODIMP #define STDMETHODIMP HRESULT STDMETHODCALLTYPE #define STDMETHODIMP_(type) type STDMETHODCALLTYPE Pierwsze makro definiuje konwencję i wynik wywołania HRESULT, drugie podany typ wyniku. Przykład: class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID ppvobj)=0; virtual STDMETHODIMP_(ULONG) AddRef(void) = 0; virtual STDMETHODIMP_(ULONG) Release(void) = 0; // This interface virtual STDMETHODIMP PrintObject(void) = 0; }; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 95

Makra STDMETHOD_ i STDMETHOD #define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method #define STDMETHOD_(type,method) virtual type STDMETHODCALLTYPE method Pierwsza wersja definiuje funkcję wirtualną interfejsu, która zwraca wynik typu HRESULT. Druga definiuje funkcję, która zwraca wynik wskazanego typu. class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions STDMETHOD(QueryInterface)(REFIID riid, LPVOID ppvobj)=0; STDMETHOD_(ULONG, AddRef)(void) = 0; STDMETHOD_(ULONG, Release)(void) = 0; // This interface STDMETHOD(PrintObject)(void) = 0; }; Wprowadzenie Beans COM NET XML CORBA H.Budzisz 96

Makrodefinicja PURE Definiuje czystą funkcję wirtualną: #define PURE = 0 class IPrintInterface : public IUnknown { public: // Standard IUnknown interface functions STDMETHOD(QueryInterface)(REFIID riid, LPVOID ppvobj) PURE; STDMETHOD_(ULONG, AddRef)(void) PURE; STDMETHOD_(ULONG, Release)(void) PURE; // This interface STDMETHOD(PrintObject)(void) PURE; }; Przykład: SimpleComServ, projekt: MsgBoxServ, plik: ISimpleMsgBox.h Wprowadzenie Beans COM NET XML CORBA H.Budzisz 97