Eclipse RCP
RCP, czyli Rich Client Platform, doskonale wpisuje się w trend w jakim zmierzają wszyscy twórcy aplikacji użytkowych. Bogactwo środowisk, czy „frameworków”, upraszczających budowę interfejsów użytkownika, oraz konstrukcję aplikacji (także internetowych) świadczy o zapotrzebowaniu na narzędzia, dzięki którym twórcy oprogramowania będą mogli więcej czasu poświęcać logice swoich aplikacji, a mniej szczegółom technicznym, unikać pisania tzw. stałych części aplikacji i czynić je łatwiejszymi do zarządzania, utrzymania i dalszego rozwoju.
Niniejszy artykuł prezentuje platformę wspomagającą tworzenie aplikacji biurkowych, opartych o te same elementy co popularne środowisko programistyczne Eclipse. W dalszej części artykułu zakładam, że czytelnik miał kontakt ze środowiskiem Eclipse oraz zna podstawy programowania w Javie.
Zanim zaczniemy
By zacząć pracę z RCP należy się upewnić że Eclipse, którym dysponujemy zawiera odpowiednie wtyczki. Na potrzeby tego artykułu korzystano z instalacji Eclipse for RCP/Plug-in Developers w wersji 3.3, dostępnej na www.eclipse.org. Jeśli już posiadamy Eclipse 3.3, będzie się on nadawał pod warunkiem że ma perspektywę Plug-in Development. Jeżeli jej nie ma, wystarczy doinstalować opcję Eclipse Plug-in Development Environment (PDE) korzystając z menu Help -> Software Updates -> Find and Install... i wybierając następnie Search for new features to install i Europa Discovery Site.
W dalszej części stworzymy prostą aplikację RCP, korzystając z szablonów dostępnych w PDE. W raz z rozwojem naszej aplikacji można ją wzbogacać o elementy standardowo dostępne w Eclipse, a więc np. własne widoki (charakterystyczne „małe okienka”, które znamy z codziennej pracy z Eclipse), preferencje użytkownika, system pomocy, a nawet cały mechanizm automatycznej aktualizacji. Swoją aplikację można rozbudowywać niemal jak z klocków, dodając wtyczki dostarczane przez innych, np. do raportowania, czy do graficznej edycji danych. Do tego tematu wrócimy w dalszej części artykułu.
Podstawy architektury
Zanim jednak stworzymy pierwszą aplikację RCP, by lepiej zrozumieć miejsce i rolę jaką będzie odgrywał nasz przyszły kod, pokrótce przyjrzyjmy się budowie samego Eclipse. Eclipse słynie z wtyczek (ang. plug-in), w rzeczywistości całość kodu w Javie jest podzielona na nie i są one domyślnie przechowywane w katalogu plugins w głównym katalogu Eclipse. Wtyczki które realizują wspólne funkcje, np. możliwości edycji Javy, czy mechanizm pomocy są pogrupowane w składniki, czy bardziej znane z angielskiego interfejsu Eclipse features. Składniki są przechowywane w katalogu features. Składnik w najprostszej postaci ma tylko plik xml definiujący listę wtyczek, jakie się na niego składają. Składniki znacznie upraszczają zarządzanie wtyczkami, których mogą być setki. Z poziomu managera aktualizacji dostępnego w Help -> Software Updates widzimy tylko składniki, możemy je dodawać, włączać i wyłączać, a także diagnozować problemy. Składniki mają także dodatkowe opisy i ikony ułatwiające użytkownikowi ich identyfikację. Tworząc własne wtyczki z myślą o wykorzystaniu istniejącego mechanizmu aktualizacji, warto więc przygotować także własny składnik. Poza wtyczkami i składnikami w katalogu Eclipse, znajduje się także folder configuration zawierający informacje pozwalające wystartować całe środowisko, oraz wszelkiego rodzaju informacje gromadzone w trakcie działania, np. cache, preferencje, pamięć o ostatnich operacjach użytkownika itp. Ostatnim niezbędnym elementem jest binarny plik wykonywalny, np. w Windows jest to plik eclipse.exe. Ten bardzo prosty program służy do uruchomienia Eclipse w nowej maszynie wirtualnej Javy z parametrami przekazanymi z linii poleceń oraz z pliku konfiguracyjnego (eclipse.ini).
Wracając do wtyczek, najczęściej w ramach jednej funkcjonalności, np. środowiska do Javy, istnieje podział na osobne wtyczki zawierające właściwą logikę (np. kompilator – org.eclipse.jdt.core), elementy interfejsu graficznego (org.eclipse.jdt.ui), dokumentację (org.eclipse.jd.doc), itp. Jest to podział czysto umowny, bo całość na ogół równie dobrze mogłaby być reprezentowana w postaci jednej wtyczki, jednak ułatwia zarządzanie wtyczkami i np. podmianę tylko wybranych w zależności od potrzeb. Również użytkownicy wykorzystujący istniejące wtyczki na tym korzystają, bo w swoich aplikacjach RCP mogą załączać np. same narzędzia kompilacji, bez związanych z nimi elementów interfejsu, czy dokumentacji.
HelloWorld!
W naszym przykładzie dla wygody ograniczymy się do jednej wtyczki. Po jej stworzeniu przejdziemy do uruchamiania i testowania a następnie wyeksportujemy jako produkt gotowy dla docelowego użytkownika. Nową wtyczkę tworzymy wybierając New -> Project... a następnie Plug-in Project. W kreatorze podajemy nazwę helloWorld, naciskamy Next, na kolejnej stronie upewniamy się że opcja Would you like to create rich client application jest wybrana i jednocześnie wyłączamy opcję This plug-in will make contributions to UI, potwierdzamy Next, wybieramy Headless Hello RCP i Finish. Akceptujemy propozycję środowiska, aby przejść do perspektywy Plug-in development - jest ona prawie taka sama, jak perspektywa Javy. Zanim przyjrzymy się bliżej wygenerowanemu projektowi, najlepiej od razu zaryzykować i uruchomić go klikając prawym przyciskiem na projekcie i wybierając z menu kontekstowego Run as -> Eclipse Application. Uruchomienie zajmie tylko chwilę i spowoduje wypisanie na konsoli Hello RCP World!. To nasze pierwsze RCP!
Rysunek 1. Kreator podczas tworzenia projektu helloWorld
Pora zajrzeć do projektu helloWorld. Składa się na niego kod źródłowy, w katalogu src. Jest to pakiet helloworld z dwiema klasami: Activator oraz Application. Kolejny element, to zależności niezbędne do działania projektu – biblioteka JRE – wymagana do kompilacji wszelkiego kodu w javie, oraz Plug-in Dependencies – lista innych wtyczek wymaganych przez tą stworzoną przez nas. Niemal każda wtyczka ma jakieś wymagania co do swojego środowiska pracy. Pozostałe elementy, tj. META-INF/MANIFEST.MF, plugin.xml oraz build.properties to pliki konfiguracyjne. Zarówno MANIFEST.MF jak i plugin.xml są edytowane korzystając z jednego, wspólnego edytora - Plug-in Manifest Editor i definiują własności całej wtyczki. Zmieniając wartości w tym edytorze tak naprawdę modyfikujemy MANIFEST.MF i plugin.xml. MANIFEST.MF jest zgodny z typowym manifestem plików JAR. Jest on jednak rozszerzony o informacje specyficzne dla standardu OSGI, na którym opiera się Eclipse. Niesie m.in. takie informacje jak nazwa i wersja wtyczki, wymagane inne wtyczki, wymagana wersja Javy, oraz wiele innych, dodatkowych pozwalających poprawnie zainicjalizować wtyczkę. Z kolei plugin.xml wiąże się z punktami rozszerzeń.
Rysunek 2. Wynik działania programu helloWorld
Koncepcja punktów rozszerzeń pozwala na zmniejszenie zależności między klasami z różnych wtyczek, oraz umożliwienie rozszerzania dowolnych koncepcji aplikacji przez innych dostawców. Brzmi to trochę abstrakcyjnie, ale spoglądając na pierwszy lepszy element interfejsu użytkownika, np. widoki, zauważymy, że nie są one statyczne. Wręcz przeciwnie, zmieniają się zależnie od sytuacji, perspektywy i zbioru zainstalowanych wtyczek. Dzieje się tak dlatego, że jedna z głównych wtyczek interfejsu graficznego Eclipse (w tym wypadku org.eclipse.ui) ma zdefiniowany punkt rozszerzeń (org.eclipse.ui.views – nazewnictwo punktów rozszerzeń ma podobną konwencję jak nazwy klas, jednak to tylko identyfikator, nie klasa). Do tak zdefiniowanego punktu rozszerzeń każdy może się podpiąć i dostarczyć własną implementację (w tym przypadku własnym widok) z dowolnej wtyczki. Mechanizm rozszerzeń pozwala zredukować zależności między klasami Javy, oraz uniezależnić się od szczegółów implementacji.
Rozszerzenie jest dodawane poprzez wpis w pliku plugin.xml. W zależności od typu rozszerzenia czasem konieczne jest zaimplementowanie odpowiedniej klasy, jednak nie jest to regułą. W samym tylko interfejsie użytkownika jest kilkadziesiąt punktów rozszerzeń, pozwalających dodawać m.in. edytory, perspektywy, menu, kreatory, akcje, skróty klawiszowe – by wymienić tylko kilka. Poza GUI wiele wtyczek udostępnia bardzo wyspecjalizowane punkty rozszerzeń, np. system pomocy pozwala dodawać kolejne rozdziały pomocy, słowa kluczowe, czy też silniki wyszukiwania (ang. search engines).
Nasz pierwszy projekt nie korzysta z GUI, jednak korzysta z jednego punktu rozszerzeń, o nazwie org.eclipse.core.runtime.applications, by zdefiniować aplikację która ma być uruchamiana (tą klasę, która wypisuje Hello RCP World!). Poprzez dwuklik na pliku plugin.xml otwieramy edytor manifestu wtyczki, na karcie Extensions, gdzie widzimy rozszerzenie org.eclipse.core.runtime.applications a po rozwinięciu drzewka, element helloworld.Application, oraz po prawej stronie nazwę klasy helloworld.Application. Na ogół klasa wskazywana w punkcie rozszerzeń musi implementować odpowiedni interfejs, co pozwoli środowisku we właściwy sposób skorzystać z klasy. W tym przypadku, gdy otworzymy klasę helloworld.Application, zauważymy że faktycznie implementuje ona interfejs IApplication i posiada dwie metody start i stop. Klasa ta jest bardzo prosta bo nasza aplikacja ma ubogi – tekstowy interfejs. W przyszłości zobaczmy analogiczną klasę, która inicjalizuje środowisko graficzne. Jeszcze chwilę uwagi należy poświęcić drugiej klasie – helloworld.Activator. Na pierwszy rzut oka jest bardzo podobna do Application – również ma metody start i stop. Jednak o ile klasa Application reprezentuje całą aplikację – na ogół jest tylko jedna dla całego zbioru wtyczek w naszym RCP, to klasy Activator są specyficzne dla poszczególnych wtyczek i każda osobno może mieć tam kod niezbędny do wykonania w momencie inicjalizacji, np. wykonanie połączenia z bazą danych, lub załadowanie zasobów.
Rysunek 3. Punkty rozszerzeń w projekcie helloWorld
Drugi przykład
Teraz, gdy znamy już strukturę wtyczek, wróćmy do kreatora w menu New -> Project...-> Plug-in Project. Stworzymy ciekawszą aplikację – z interfejsem użytkownika. Będzie to klient poczty. Tym razem w kreatorze, na ekranie Plug-in Content zaznaczamy This plug-in will make contributions to UI i oczywiście Would you like to create a rich client application?. Po naciśnięciu Next pojawia się inny zestaw przykładów. Wybieramy ostatni - RCP Mail Template. Wygenerowany projekt jest tym razem znacznie bardziej rozbudowany od poprzedniego. Co prawda nie jest to w pełni funkcjonalna aplikacja pocztowa, a jedynie interfejs użytkownika, jednak nie powinno to przeszkadzać w poznawaniu zagadnień RCP.
Warto zwrócić uwagę plik plugin.xml. Po otwarciu go, na karcie Extensions zauważymy dużo więcej wykorzystanych punków rozszerzeń, m.in. definicję własnej perspektywy (org.eclipse.ui.perspectives), czy własnego widoku (org.eclipse.ui.views). Perspektywa definiuje w jaki sposób mają być ułożone główne elementy w oknie aplikacji, czyli widoki. W tym przypadku okno składa się z widoku folderów (klasa NavigationView) – poczty przychodzącej, wychodzącej, itp. W głównej części jest natomiast miejsce na widoki wiadomości (klasa View). Ponadto jest zdefiniowany szereg komend – abstrakcyjnych czynności, jak np. otwarcie wiadomości (punkt rozszerzeń org.eclipse.ui.commands), oraz definicje skrótów klawiszowych (punkt rozszerzeń org.eclipse.ui.bindings). Jeśli wspomnimy poprzedni przykład, była tam klasa Application, która jest także i w tym przykładzie. Jednak tym razem jest bardziej rozbudowana i uruchamia interfejs graficzny naszego programu. By uruchomić klienta pocztowego ponownie należy kliknąć prawym klawiszem myszy na projekcie i z menu wybrać Run as -> Eclipse Application.
Rysunek 4. Punkty rozszerzeń w projekcie mailClient
Poniżej omówione zostaną poszczególne klasy klienta pocztowego.
- Activator – Niejako punkt zaczepienia wtyczki w środowisku Eclipse. Jej położenie wskazuje nieobowiązkowe pole Bundle-Activator w pliku MANIFEST.MF. W klasie tej można zdefiniować akcje wykonywane podczas inicjalizacji, lub przed usunięciem wtyczki z środowiska. Warto przy tym pamiętać, że wtyczki są w tym względzie bardzo elastyczne, a usunięcie wybranej z nich powoduje zniknięcia wszystkich jej funkcji i nie wymaga restartu środowiska. Ponadto ta klasa zawiera id wtyczki (PLUGIN_ID), ustawienia preferencji (getPreferenceStore()), czy pozwala odwoływać się do jej plików.
- Application – Ta klasa implementuje interfejs IApplication. Typowo w całej aplikacji RCP jest tylko jedna klasa IApplication, chociaż nie jest to z góry ograniczone. Klasa tego typu pozwala zaimplementować dodatkowe akcje wykonywane podczas uruchamiania lub zamykania aplikacji.
- ApplicationActionBarAdvisor – Konfiguracja pasków i menu aplikacji, w szczególności górnego paska opcji ( MenuBar), czesto znajdującego się pod nim paska z ikonami (CoolBar), paska statusu (StatusLine). W przykładowej aplikacji, klasa ta definiuje kilka standardowych akcji korzystając z fabryki ActionFactory:
exitAction = ActionFactory.QUIT.create(window); register(exitAction); aboutAction = ActionFactory.ABOUT.create(window); register(aboutAction);
Tutaj rejestrowane są także własne akcje klienta poczty – akcja do otwierania widoków (OpenViewAction) i do wyświetlania komunikatów (MessagePopupAction).
Ponadto, w metodzie fillMenuBar(IMenuManager) definiowana jest struktura menu. W menu można umieszczać bezpośrednio utworzone wcześniej akcje, lub tylko zaznaczać miejsca dodania nowych akcji (ang. Group Markers). Dzięki temu programiści innych wtyczek z łatwością będą mogli dodać własne akcje do menu.
- ApplicationWorkbenchAdvisor – Konfiguracja wyglądu aplikacji. W przykładowej implementacji, w tym miejscu zdefiniowana jest tylko domyślna perspektywa, wg. której program ma skonfigurować okno przy uruchomieniu aplikacji. Ta klasa dostarcza także szczegółowej konfiguracji głównego okna (w metodzie createWorkbenchAdvisor(IWorkbnechWindowConfigurer))
- ApplicationWorkbenchWindowAdvisor – Konfiguracja głównego okna (zwracana przez ApplicationWorkbenchAdvisor). Zawiera szczegóły techniczne wyglądu okna, jak np. jego rozmiar, położenie, elementy które mają być widoczne (pasek stanu, menu). Rozszerzając implementacje metod nadrzędnej klasy, ( WorkbenchWindowAdvisor) można zdefiniować dodatkowe akcje, które miałyby być wykonane w różnych etapach cyklu życia okna, jak np. przed jego utworzeniem, po jego otwarciu, itp.
- ICommandIds – Definicje nazw akcji klienta pocztowego. Klasa pomocnicza pozwala uniknąć każdorazowego powtarzania nazw bezpośrednio w kodzie. Nazwy te odnoszą się do akcji zdefiniowanych w pliku plugin.xml.
- MessagePopupAction, OpenViewAction – Przykładowe akcje. Akcje w Eclipse reprezentują elementarne czynności, jakie może wykonać użytkownik. W przykładowym kliencie nie jest ich zbyt wiele, jednak niezależnie od liczby, wszystkie akcje cechują pewne wspólne elementy. Każda akcja ma swój unikalny identyfikator, nazwę czytelną dla użytkownika, ikonę oraz oczywiście samą implementację czynności (w metodzie run()). Listę wszystkich dostępnych w danej chwili akcji można przejrzeć otwierając interfejs IAction (skrót klawiszowy Ctrl+Shift+T i wpisując IAction), a następnie przeglądając hierarchię klas implementujących ten interfejs (po zaznaczeniu w edytorze interfejsu fragmentu tekstu IAction, naciskamy Ctrl+T). Na liście znajdziemy więc poza definicjami własnych klas, także całą listę standardowych akcji domyślnie zaimplementowanych w środowisku.
- NavigationView, View – implementacje przykładowych widoków. Podobnie jak akcje, również i widoki mają swoje unikalne identyfikatory, ponadto aby widok był dostępny i można go było wyświetlić w oknie aplikacji, musi być zarejestrowany w punkcie rozszerzeń org.eclipse.ui.views. Widoki muszą implementować interfejs IViewPart, jednak najczęściej rozszerzają klasę ViewPart, zawierającą implementacje wybranych podstawowych metod. Najczęściej w widoku będziemy samodzielnie implementować metodę createPartControl(Composite), gdyż to ona jest wywoływana przy pierwszym otwarciu widoku i to ona definiuje sam jego wygląd. Obiekt Composite dostarczany w parametrze metody to miejsce gdzie można wstawiać wszelkie przyciski, listy, panele, itp. zarówno korzystając z API biblioteki SWT jak i JFace.
- Perspective – konfiguracja domyślnej perspektywy aplikacji, tj. domyślnego ułożenia wszystkich widoków w oknie. Widoki można rozmieszczać wokół obszaru edytora, który ze względu na pierwotne zastosowanie Eclipse jako IDE, był centralnym punktem aplikacji. Rozmieszczając widoki podaje się dodatkowo jaką część okna mają zajmować. Widoki można także grupować przy wykorzystaniu tzw. folderów. Przykładowe rozmieszczenie widoków w perspektywie przedstawia zrzut ekranu komunikatora Sametime bazującego na Eclipse (Rysunek 5) – domyślne okno składa się z trzech widoków (Contacts, Stock Ticker, BuddyNote), z których pierwszy jest rozwinięty, a dwa kolejne zminimalizowane.
Rysunek 5. Aplikacje RCP nie zawsze przypominają wyglądem Eclipse.
Narodziny produktu
Pierwszy element aplikacji, którego nie widzieliśmy do tej pory to okno powitalne z logo. Często jest to pierwszy krok, od którego zaczyna się „upiększanie” produktu – ku uciesze oka jego przyszłych użytkowników. Produkt musi mieć identyfikowalną z nim ikonę, musi być łatwo sprawdzić kto jest jego producentem oraz którą mamy wersję. Po utworzeniu takiej definicji produktu, zawierającej wszystkie tego typu informacje Eclipse w prosty sposób wyeksportować program, gotowy do instalacji na komputerach użytkowników.
Aby stworzyć definicję produktu, należy z menu File wybrać New -> Other i odszukać Product Configuration. Jako lokalizację podać projekt mailClient, nazwę pliku np. product.product i pozostawić zaznaczoną opcję Use an existing product.... Okazuje się bowiem, że w punkcie rozszerzeń org.eclipse.core.runtime.products w plugin.xml projektu był już zdefiniowany produkt, jednak edytowanie go w ten sposób nie jest zbyt wygodne.
Po utworzeniu konfiguracji produktu naszym oczom ukazuje się edytor z następującymi kartami: Overview, Configuration, Launching, Splash oraz Branding. Po kolei, na karcie Overview, można zdefiniować nazwę naszego programu, uruchamiać go (ramka Testing), oraz eksportować jako zewnętrzną aplikację – do tematu eksportu jeszcze wrócimy.
Na karcie Configuration jest lista wtyczek, które będzie zawierał produkt. Jest to niezwykle ważna lista, ponieważ jeśli produkt nie będzie zawierał wtyczek które są wymagane, może się nie uruchomić. Jednocześnie im więcej wtyczek dodamy na liście, tym produkt będzie większy i cięższy do wysyłania.
Na karcie Launcher zauważymy że każda ramka zawiera takie same opcje dla czterech rodzajów systemów operacyjnych – linux, macos, solaris, win32. Może już zapomnieliśmy, ale aplikacje na bazie Eclipse są multiplatformowe, więc można je uruchamiać na różnych systemach operacyjnych. Jednak dla każdego systemu jest wymagana osobna wersja instalacyjna i będzie utworzony specjalny plik binarny, jak np. dla Windows znany nam eclipse.exe. Na tej karcie jest także miejsce by podać własną nazwę pliku wykonywalnego (pole Launcher Name), np. mailClient. Tutaj można także podać parametry maszyny wirtualnej programu, jak np. potrzebny rozmiar pamięci. Jeśli mamy obawy, czy przyszli użytkownicy będą mieli zainstalowaną Javę, możemy od razu załączać ją do programu. Pozostałe dwie karty, tj. Splash i Branding pozwalają zdefiniować ekran powitalny oraz dodatkowe informacje, jakie mają być wyświetlane w okienku About aplikacji.
Po ustawieniu wszystkich opcji, zawsze warto. A jeśli dodajemy lub usuwamy wtyczki na karcie Configuration nawet trzeba, wrócić na kartę Overview i przetestować, jak nasza aplikacja działa. W ramce Testing trzeba kliknąć Synchronize i Launch Eclipse application. Jeśli wszystko jest tak, jak oczekiwaliśmy, przechodzimy do eksportu aplikacji, czyli do ramki Exporting i klikamy link Eclipse Product export wizard. Podajemy tylko katalog docelowy (lub archiwum) i klikamy Finish. We wskazanym katalogu zostanie wygenerowana cała aplikacja, o strukturze niemal identycznej jak struktura Eclipse – opisywana na początku, czyli z plikiem wykonywalnym, tym razem mailClient.exe, katalogiem plugins, oraz configuration.
Rysunek 6. Końcowy efekt, wyeksportowany program mailClient
Jak widać, przy pisaniu aplikacji RCP, wyłania się powoli schemat: na ogół dodanie nowej funkcji zaczynamy od dodania właściwego punktu rozszerzeń, oraz klas implementujących stosowne interfejsy. W podobny sposób własną aplikację można rozszerzyć o pomoc, podpowiedzi, własne kreatory, skróty klawiszowe, funkcje wyszukiwania, zarządzanie zasobami użytkownika (Resources).
Co dalej...
Oczywiście, im większe będziemy mieli wymagania wobec przyszłej aplikacji, tym lepiej trzeba poznać API platformy Eclipse. Warto więc także wypróbować kilka innych przykładowych aplikacji, jakie są dostępne w kreatorze wtyczek. Dalsze kroki najlepiej natomiast skierować na strony takie jak np. http://www.eclipse.org/evangelism, gdzie znajdziemy kolejne przykłady, a także dokumentację RCP. Poza standardowym środowiskiem, to co naprawdę stanowi o sile RCP to bogactwo innych projektów gotowych do integracji z naszymi wtyczkami. Są to np. środowisko do tworzenia narzędzi graficznych – GMF, czy silne wsparcie dla MDA (Model Driven Architecture), w postaci EMF – omówione w niniejszym numerze, BIRT (Business Inteligence and Reporting Tools) dostarczający funkcjonalność raportów biznesowych, czy projekt ECF (Eclipse Communication Framework) - moduł komunikacji korzystający z popularnych otwartych standardów jak np. XMPP, znany z Jabbera, lub Google Talk, czy IRC.
Podsumowanie
W artykule przyjżeliśmy się budowie aplikacji Eclipse RCP, tworząc dwie proste aplikacje oraz budując program gotowy do dostarczenia klientowi. Na pierwszy rzut oka RCP nie różni się zbyt wiele od tworzenia zwykłych aplikacji w Javie. Pozwala uniknąć programowania wielu stałych elementów aplikacji, a skupić się tylko na interfejsie użytkownika głównych elementów oraz na logice i kluczowych modułach systemu. Jednocześnie znacząco ułatwia personalizację aplikacji, dzięki dużej elastyczności w definiowaniu wyglądu i zachowania aplikacji.
Linki do innych materiałów o Eclipse Rich Client Platform:
http://wiki.eclipse.org/index.php/Rich_Client_Platform
http://www.eclipsercp.org/
http://wiki.eclipse.org/RCP_Custom_Look_and_Feel
http://wiki.eclipse.org/RCP_FAQ
http://www.eclipsezone.com/eps/10minute-rcp/
http://wiki.eclipse.org/index.php/The_Official_Eclipse_FAQs
http://www.eclipsecon.org/2007/index.php?page=sub/&area=rich-client
http://www.eclipse.org/evangelism
Nie ma jeszcze komentarzy.