Kroki do wykonania - Księgarnia Warszawa
Transkrypt
Kroki do wykonania - Księgarnia Warszawa
Tytuł oryginału: Eclipse 4 Plug-in Development by Example: Beginner's Guide Tłumaczenie: Rafał Jońca ISBN: 978-83-246-8754-1 Copyright © Packt Publishing 2013. First published in the English language under the title „Eclipse 4 Plug-in Development by Example: Beginner's Guide”. Polish edition copyright © 2014 by Helion S.A. All rights reserved. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: [email protected] WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/eclip4 Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treĂci Przedmowa 15 Rozdziaï 1. Tworzenie pierwszej wtyczki 21 Przygotowanie Ărodowiska Kroki do wykonania — konfiguracja Ărodowiska Eclipse SDK Tworzenie pierwszej wtyczki Kroki do wykonania — tworzenie wtyczki Quiz — przestrzenie nazw i wtyczki Eclipse Uruchomienie wtyczki Kroki do wykonania — uruchomienie Eclipse z poziomu Eclipse Quiz — uruchamianie Eclipse Sprawdě siÚ — modyfikacja wtyczki Debugowanie wtyczki Kroki do wykonania — debugowanie wtyczki Kroki do wykonania — aktualizacja kodu w debuggerze Debugowanie z filtrami kroków Kroki do wykonania — ustawienie filtru kroków Korzystanie z róĝnych rodzajów punktów wstrzymania Kroki do wykonania — wstrzymanie przy wejĂciu do metody lub wyjĂciu z niej Warunkowe punkty wstrzymania Kroki do wykonania — ustawienie warunkowego punktu wstrzymania Wstrzymanie dziaïania po wystÈpieniu wyjÈtku Kroki do wykonania — wyïapywanie wyjÈtków Kroki do wykonania — obserwacja zmiennych i wyraĝeñ Quiz — debugowanie Sprawdě siÚ — korzystanie z punktów wstrzymania Podsumowanie Rozdziaï 2. Tworzenie widoków w SWT Tworzenie widoków i widgetów Kroki do wykonania — tworzenie widoku Kroki do wykonania — rysowanie wïasnego widoku Kroki do wykonania — rysowanie wskazówki sekund Kup książkę 21 22 25 25 28 28 28 31 31 31 31 34 35 35 37 37 38 39 40 40 43 45 45 46 47 48 48 50 53 Poleć książkę Spis treĞci Kroki do wykonania — animacja wskazówki sekund Kroki do wykonania — uruchomienie w wÈtku interfejsu uĝytkownika Kroki do wykonania — tworzenie widgetu wielokrotnego uĝytku Kroki do wykonania — korzystanie z ukïadu graficznego widoku Quiz — dziaïanie widoków Sprawdě siÚ — wskazówki minut i godzin ZarzÈdzanie zasobami Kroki do wykonania — wiÚcej kolorów Kroki do wykonania — znajdowanie wycieku Kroki do wykonania — zatykanie wycieku Quiz — dziaïanie zasobów Sprawdě siÚ — rozbudowa widgetu zegara Interakcja z uĝytkownikiem Kroki do wykonania — uzyskiwanie aktywnoĂci Kroki do wykonania — reakcja na dziaïania uĝytkownika Quiz — dziaïanie widgetów Sprawdě siÚ — aktualizacja widgetu zegara Korzystanie z innych widgetów SWT Kroki do wykonania — dodanie elementów do zasobnika Kroki do wykonania — reakcja na akcje uĝytkownika Kroki do wykonania — obiekty modalne i inne efekty Kroki do wykonania — grupy i zakïadki Quiz — korzystanie z SWT Sprawdě siÚ — rozbudowa widoku stref czasowych Podsumowanie Rozdziaï 3. Tworzenie widoków w JFace Dlaczego JFace? Tworzenie widoków TreeViewer Kroki do wykonania — tworzenie obiektu TreeViewer Kroki do wykonania — JFace i obrazy Kroki do wykonania — style w dostawcy etykiet Quiz — podstawy JFace Sprawdě siÚ — dodanie obrazów dla regionów Sortowanie i filtracja Kroki do wykonania — sortowanie elementów w widoku Kroki do wykonania — filtrowanie elementów w widoku Quiz — sortowanie i filtracja Sprawdě siÚ — rozwijanie gaïÚzi i filtracja Interakcje i wïaĂciwoĂci Kroki do wykonania — dodanie procedury obsïugi podwójnego klikniÚcia Kroki do wykonania — wyĂwietlanie wïaĂciwoĂci Quiz — dziaïanie wïaĂciwoĂci Dane tabelaryczne Kroki do wykonania — przeglÈdanie stref czasowych w tabeli Kroki do wykonania — synchronizacja wyboru Quiz — dziaïanie tabel Podsumowanie 54 55 56 58 61 61 61 62 63 65 67 67 67 67 69 70 70 71 71 73 74 76 82 82 82 83 83 84 84 88 91 93 93 93 94 95 97 97 98 98 101 105 105 105 109 111 112 4 Kup książkę Poleć książkę Spis treĞci Rozdziaï 4. Interakcja z uĝytkownikiem Tworzenie akcji, poleceñ i procedur obsïugi Kroki do wykonania — dodanie menu kontekstowego Kroki do wykonania — tworzenie poleceñ i procedur obsïugi Kroki do wykonania — powiÈzanie poleceñ ze skrótami Kroki do wykonania — zmiana kontekstu Kroki do wykonania — wïÈczanie i wyïÈczanie elementów menu Kroki do wykonania — wielokrotne uĝycie wyraĝeñ Kroki do wykonania — dodanie poleceñ do menu kontekstowego Sprawdě siÚ — wykorzystanie menu i pasków narzÚdziowych Quiz — dziaïanie menu Zadania i paski postÚpu Kroki do wykonania — uruchamianie operacji dziaïajÈcych w tle Sprawdě siÚ — uĝycie zadania UIJob Kroki do wykonania — raportowanie postÚpu prac Kroki do wykonania — sprawdzanie anulowania zadania Kroki do wykonania — podzadania i ich monitorowanie Kroki do wykonania — uĝycie monitorów i podmonitorów typu null Kroki do wykonania — ustawienie wïaĂciwoĂci klasy Job Sprawdě siÚ — wyĂwietlanie zadania w pasku systemowym Quiz — korzystanie z zadañ Zgïaszanie bïÚdów Kroki do wykonania — wyĂwietlanie bïÚdów Quiz — zgïaszanie bïÚdów Podsumowanie Rozdziaï 5. Przechowywanie preferencji i ustawieñ Przechowywanie preferencji Kroki do wykonania — trwaïoĂÊ wartoĂci Kroki do wykonania — utworzenie strony preferencji Kroki do wykonania — tworzenie komunikatów ostrzeĝeñ i bïÚdów Kroki do wykonania — wybór elementu z listy Kroki do wykonania — dodanie siatki Kroki do wykonania — lokalizacja strony preferencji Kroki do wykonania — uĝycie innych edytorów pól Kroki do wykonania — dodanie sïów kluczowych Kroki do wykonania — uĝycie IEclipsePreferences Sprawdě siÚ — tïumaczenie na inne jÚzyki Uĝycie IMemento i DialogSettings Kroki do wykonania — dodanie IMemento do widoku stref czasowych Kroki do wykonania — uĝycie DialogSettings Quiz — dziaïanie preferencji Podsumowanie 113 113 114 115 117 119 121 123 124 126 127 127 127 129 129 131 131 133 135 138 138 138 138 141 142 143 143 144 145 146 147 149 150 151 153 154 155 155 156 157 159 159 5 Kup książkę Poleć książkę Spis treĞci Rozdziaï 6. Korzystanie z zasobów 161 Korzystanie z przestrzeni roboczych i zasobów Kroki do wykonania — tworzenie edytora Kroki do wykonania — tworzenie parsera Kroki do wykonania — tworzenie systemu budujÈcego Kroki do wykonania — iteracja przez zasoby Kroki do wykonania — tworzenie zasobów Kroki do wykonania — implementacja budowania inkrementacyjnego Kroki do wykonania — obsïuga usuniÚcia Sprawdě siÚ — rozbudowa mechanizmu budowania Uĝycie charakterów projektu Kroki do wykonania — tworzenie charakteru projektu Sprawdě siÚ — ukrywanie charakteru Uĝycie znaczników Kroki do wykonania — znacznik bïÚdu, gdy plik jest pusty Kroki do wykonania — rejestracja rodzaju znacznika Sprawdě siÚ — prawidïowe dziaïanie, gdy plik jest naprawdÚ pusty Quiz — obsïuga zasobów, procesu budowania i znaczników Podsumowanie 161 162 164 165 168 170 172 172 174 175 175 178 178 179 180 181 182 182 Rozdziaï 7. Model Eclipse 4 183 Korzystanie z modelu Eclipse 4 Kroki do wykonania — instalacja narzÚdzi Eclipse 4 Kroki do wykonania — tworzenie aplikacji Eclipse 4 Kroki do wykonania — tworzenie czÚĂci Kroki do wykonania — obstylowanie interfejsu uĝytkownika za pomocÈ CSS Sprawdě siÚ — uĝycie menedĝera tematów Usïugi i konteksty Kroki do wykonania — dodanie logowania do dziennika zdarzeñ Kroki do wykonania — pobranie okna Kroki do wykonania — uzyskanie zaznaczenia Kroki do wykonania — korzystanie ze zdarzeñ Kroki do wykonania — obliczanie wartoĂci na ĝÈdanie Kroki do wykonania — uĝycie preferencji Kroki do wykonania — interakcja z interfejsem uĝytkownika Korzystanie z poleceñ, procedur obsïugi i elementów menu Kroki do wykonania — powiÈzanie menu z poleceniem i procedurÈ obsïugi Kroki do wykonania — przekazywanie parametrów polecenia Kroki do wykonania — utworzenie bezpoĂredniego menu i skrótów klawiszowych Kroki do wykonania — utworzenie menu kontekstowego i menu widoku Tworzenie wïasnych klas do wstrzykiwania Kroki do wykonania — tworzenie prostej usïugi Kroki do wykonania — wstrzykiwanie podtypów Sprawdě siÚ — uĝycie mostka narzÚdziowego Quiz — dziaïanie Eclipse 4 Podsumowanie 183 184 186 190 194 199 199 199 201 202 204 207 209 211 213 213 215 218 220 222 222 223 224 224 225 6 Kup książkę Poleć książkę Spis treĞci Rozdziaï 8. Tworzenie funkcjonalnoĂci, witryn aktualizacji, aplikacji i produktów Grupowanie wtyczek jako funkcjonalnoĂci Kroki do wykonania — tworzenie funkcjonalnoĂci Kroki do wykonania — eksport funkcjonalnoĂci Kroki do wykonania — instalacja funkcjonalnoĂci Kroki do wykonania — kategoryzacja witryny aktualizacji Kroki do wykonania — zaleĝnoĂÊ od innych funkcjonalnoĂci Kroki do wykonania — tworzenie oznaczeñ funkcjonalnoĂci Sprawdě siÚ — zdalna publikacja zawartoĂci Budowanie aplikacji i produktów Kroki do wykonania — wykonanie aplikacji bez interfejsu uĝytkownika Kroki do wykonania — tworzenie produktu Sprawdě siÚ — tworzenie produktu bazujÈcego na funkcjonalnoĂci Quiz — sposób dziaïania funkcjonalnoĂci, aplikacji i produktów Podsumowanie Rozdziaï 9. Automatyczne testy wtyczek Uĝycie frameworku JUnit do testów zautomatyzowanych Kroki do wykonania — wykonanie prostego przypadku testowego JUnit Kroki do wykonania — wykonanie testu wtyczki Wykorzystanie SWTBot do testów interfejsu graficznego Kroki do wykonania — tworzenie testów SWTBot Kroki do wykonania — korzystanie z menu Sprawdě siÚ — korzystanie z zasobów Korzystanie z SWTBot Kroki do wykonania — ukrywanie ekranu powitalnego Kroki do wykonania — unikanie bïÚdów wykonania z SWTBot Korzystanie z widoków Kroki do wykonania — wyĂwietlenie widoków Kroki do wykonania — przesïuchiwanie widoków Interakcja z interfejsem uĝytkownika Kroki do wykonania — pobranie wartoĂci z interfejsu uĝytkownika Kroki do wykonania — oczekiwanie na warunek Sprawdě siÚ — sterowanie kreatorem nowej klasy Quiz — dziaïanie SWTBot Podsumowanie Rozdziaï 10. Automatyczne budowanie przy uĝyciu Tycho Wykorzystanie Maven i Tycho do budowania wtyczek Eclipse Kroki do wykonania — instalacja Maven Kroki do wykonania — budowanie za pomocÈ Tycho Sprawdě siÚ — korzystanie z platform docelowych Budowanie funkcjonalnoĂci i witryn aktualizacji za pomocÈ Tycho Kroki do wykonania — tworzenie projektu nadrzÚdnego Kroki do wykonania — budowanie funkcjonalnoĂci Kroki do wykonania — budowanie witryny aktualizacji 227 228 228 230 232 234 237 239 241 241 242 245 249 249 249 251 251 252 253 254 254 256 258 258 258 259 260 260 261 262 262 263 265 265 265 267 267 268 270 272 273 273 275 276 7 Kup książkę Poleć książkę Spis treĞci Kroki do wykonania — budowanie produktu Sprawdě siÚ — zaleĝnoĂÊ od komponentów Maven Testy i publikacja Kroki do wykonania — uruchomienie testów automatycznych Kroki do wykonania — zmiana numeru wersji Sprawdě siÚ — wïÈczenie budowania dla pozostaïych wtyczek Podpisywanie witryn aktualizacji Kroki do wykonania — tworzenie certyfikatu podpisanego przez samego siebie Kroki do wykonania — podpisywanie wtyczek Kroki do wykonania — serwer z witrynÈ aktualizacji Quiz — automatyczne budowanie i witryny aktualizacji Podsumowanie Dodatek A Odpowiedzi do quizów Rozdziaï 1. Tworzenie pierwszej wtyczki Rozdziaï 2. Tworzenie widoków w SWT Rozdziaï 3. Tworzenie widoków w JFace Rozdziaï 4. Interakcja z uĝytkownikiem Rozdziaï 5. Przechowywanie preferencji i ustawieñ Rozdziaï 6. Korzystanie z zasobów Rozdziaï 7. Model Eclipse 4 Rozdziaï 8. Tworzenie funkcjonalnoĂci, witryn aktualizacji, aplikacji i produktów Rozdziaï 9. Automatyczne testy wtyczek Rozdziaï 10. Automatyczne budowanie przy uĝyciu Tycho Skorowidz 278 282 283 283 286 288 288 288 290 292 293 293 295 295 296 298 299 300 301 301 303 303 304 305 8 Kup książkę Poleć książkę 3 Tworzenie widoków w JFace W poprzednim rozdziale przyjrzeliĂmy siÚ podstawowym elementom SWT, które stanowiÈ pomost miÚdzy elementami systemu operacyjnego a JavÈ. W tym rozdziale poznamy JFace, który korzysta z SWT w celu zapewnienia architektury MVC, a takĝe dostarczenia wielu typowych widgetów uĝywanych przez Eclipse. W tym rozdziale: Q utworzymy widok do przedstawiania hierarchicznych danych, Q uĝyjemy zasobów obrazu, czcionki lub koloru, Q wygenerujemy stylizowany tekst, Q posortujemy i przefiltrujemy wpisy w widokach, Q dodamy akcje dla podwójnych klikniÚÊ, Q zaznaczymy i obsïuĝymy wïaĂciwoĂci, Q utworzymy widok dla danych tabelarycznych. Dlaczego JFace? ChoÊ SWT zapewnia podstawowÈ implementacjÚ prostych widgetów (na przykïad drzew, przycisków i etykiet), wszystko dziaïa na bardzo podstawowym poziomie, bo wykorzystywane sÈ teksty i indeksy zaznaczeñ. Aby ïatwiej wyĂwietlaÊ strukturyzowane dane, JFace udostÚpnia kilka zaawansowanych widoków, które stanowiÈ poïÈczenie widgetów SWT i menedĝerów zdarzeñ, co zapewnia wygodnÈ obsïugÚ interfejsu uĝytkownika dla strukturyzowanych treĂci. Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach Istnieje wiele rodzajów zaawansowanych widoków nazywanych viewer (wszystkie dziedziczÈ po klasie Viewer), ale najczÚĂciej stosowanymi sÈ te, które naleĝÈ do ContentViewer, na przykïad TreeViewer i TableViewer. IstniejÈ równieĝ wersje bazujÈce na tekĂcie (TextViewer ma podklasy dla SourceViewer), a takĝe widoki operacyjne (ConsoleViewer dla widoku Console lub DetailedProgressViewer dla widoku Progress). W tym rozdziale wykonamy widoki bazujÈce na klasach TreeViewer i TableViewer. Poniewaĝ JFace bazuje na SWT, wiedza na temat szczegóïów dziaïania SWT jest niezbÚdna do prawidïowego uĝytkowania JFace. Tworzenie widoków TreeViewer Wiele widgetów w Eclipse bazuje na widoku przypominajÈcym drzewo — jest to zarówno nawigator plików, jak i okno wyĂwietlania zawartoĂci klas. Framework JFace udostÚpnia klasÚ TreeViewer realizujÈcÈ wszystkie niezbÚdne funkcjonalnoĂci. Uĝyjemy jej do wykonania widoku TimeZoneTreeView. Kroki do wykonania — tworzenie obiektu TreeViewer Podobnie jak miaïo to miejsce w poprzednim rozdziale, nowy widok TimeZoneTreeView utworzymy przy uĝyciu edytora plugin.xml. Widok wyĂwietli strefy czasowe uïoĝone hierarchicznie wzglÚdem regionów. 1. Kliknij prawym przyciskiem myszy projekt com.packtpub.e4.clock.ui i wybierz polecenie Plug-in Tools/Open Manifest, by otworzyÊ plik plugin.xml, jeĂli jeszcze nie jest otwarty. 2. Otwórz zakïadkÚ Extensions i znajdě element org.eclipse.ui.views. Kliknij go prawym przyciskiem myszy i z menu wybierz polecenie New/View. Wypeïnij pola w sposób opisany poniĝej. Q W polu ID wpisz com.packtpub.e4.clock.ui.views.TimeZoneTreeView. Q W polu Name wpisz Widok drzewa stref czasowych. Q W polu Class wpisz com.packtpub.e4.clock.ui.views.TimeZoneTreeView. Q W polu Category wpisz com.packtpub.e4.clock.ui. Q W polu Icon wpisz icons/sample.gif. 3. Zapisz plik. Konfigurator umieĂciï w pliku plugin.xml nastÚpujÈcy wpis. <view category="com.packtpub.e4.clock.ui" class="com.packtpub.e4.clock.ui.views.TimeZoneTreeView" icon="icons/sample.gif" id="com.packtpub.e4.clock.ui.views.TimeZoneTreeView" name="Widok drzewa stref czasowych" restorable="true"> </view> 84 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace 4. Podobnie jak wczeĂniej, utwórz klasÚ TimeZoneTreeView, która rozszerza klasÚ ViewPart. 5. W metodzie createPartControl() utwórz instancjÚ TreeViewer z opcjami V_SCROLL, H_SCROLL i MULTI. ZapamiÚtaj obiekt w polu klasy. Zaimplementuj metodÚ setFocus(), by ustawiaïa widok drzewa jako aktywny element. public class TimeZoneTreeView extends ViewPart { private TreeViewer treeViewer; public void createPartControl(Composite parent) { treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | ´SWT.V_SCROLL ); } public void setFocus() { treeViewer.getControl().setFocus(); } } )E4: ChoÊ Eclipse 4 zostanie szczegóïowo omówione w rozdziale 7., warto wspomnieÊ, ĝe w Eclipse 4 nad metodÈ createPartControl() niezbÚdna jest adnotacja @Inject (by zapewniÊ przekazanie obiektu Composite), a nad metodÈ setFocus() — adnotacja @Focus. 6. Uruchom testowÈ wersjÚ Eclipse i przejdě do widoku, wybierajÈc polecenie Window/ShowView/Other/¥ledzenie czasu/Widok drzewa stref czasowych. 7. W odróĝnieniu od Swing, gdzie oczekuje siÚ otrzymywania danych w klasie bazujÈcej na konkretnym interfejsie, JFace nie wymaga ĝadnej konkretnej klasy. W zamian oczekuje obiektu wartoĂci do wyĂwietlenia (wejĂcie), interfejsu, który czyta dane (dostawca treĂci), i interfejsu do wyĂwietlania danych (dostawca etykiet). 8. Utwórz nowÈ klasÚ o nazwie TimeZoneLabelProvider dziedziczÈca po LabelProvider (z pakietu org.eclipse.jface.viewers). BÚdzie zawieraïa metodÚ o nazwie getText(), która otrzymuje obiekt i zamienia go na reprezentacjÚ tekstowÈ. Zamiast wywoïywaÊ toString(), zwróÊ odpowiedniÈ wartoĂÊ zwiÈzanÈ z Map.Entry lub TimeZone. public class TimeZoneLabelProvider extends LabelProvider { public String getText(Object element) { if (element instanceof Map) { return "Strefy czasowe"; 85 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach } else if return } else if return } else { return } (element instanceof Map.Entry) { ((Map.Entry) element).getKey().toString(); (element instanceof TimeZone) { ((TimeZone) element).getID().split("/")[1]; "Nieznany typ: " + element.getClass(); } } Poniewaĝ obiekt TreeViewer moĝe mieÊ wiele korzeni, test instanceof Map sïuĝy do sprawdzenia, czy to wierzchoïek drzewa, który powinien mieÊ nazwÚ Strefy czasowe. 9. Warto zapewniÊ wartoĂÊ domyĂlnÈ — nawet jeĂli jest to pusty tekst — bo otrzymanie nieznanego typu moĝna ïatwo wyĂledziÊ i naprawiÊ. 10. Utwórz nowÈ klasÚ TimeZoneContentProvider implementujÈcÈ interfejs ITreeContentProvider. Interfejs wymaga implementacji trzech metod z szeĂciu (pozostaïe mogÈ pozostaÊ puste). Oto one. Q hasChildren() — zwraca true, jeĂli wÚzeï ma potomków. Q getChildren() — zwraca potomków konkretnego wÚzïa. Q getElements() — zapewnia gïówne korzenie. 11. Metoda hasChildren() zwróci wartoĂÊ true, jeĂli zostanie do niej przekazany obiekt typu Map lub Collection, który nie bÚdzie pusty. Przekazanie Map.Entry spowoduje wywoïanie rekurencyjne. Dla drzew bazujÈcych na zagnieĝdĝonych Map lub Collection metoda hasChildren() bÚdzie wyglÈdaïa identycznie. public boolean hasChildren(Object element) { if (element instanceof Map) { return !((Map) element).isEmpty(); } else if (element instanceof Map.Entry) { return hasChildren(((Map.Entry)element).getValue()); } else if (element instanceof Collection) { return !((Collection) element).isEmpty(); } else { return false; } } 12. Implementacja getChildren() rekurencyjnie wchodzi do obiektów typu Map, Collection lub Map.Entry, stosujÈc przy tym opisany wczeĂniej wzorzec. Poniewaĝ metoda wymaga zwrócenia typu Object[], kod uĝywa funkcjonalnoĂci wbudowanej w klasÚ Map, by zamieniÊ zawartoĂÊ entrySet() na tablicÚ. public Object[] getChildren(Object parentElement) { if (parentElement instanceof Map) { return ((Map) parentElement).entrySet().toArray(); 86 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace } else if return } else if return } else { return } (parentElement instanceof Map.Entry) { getChildren(((Map.Entry)parentElement).getValue()); (parentElement instanceof Collection) { ((Collection) parentElement).toArray(); new Object[0]; } 13. Kluczem przy implementacji ITreeContentProvider jest zapewnienie staïej synchronizacji kodu metod getChildren() i hasChildren(). Jednym ze sposobów zapewnienia takiej sytuacji jest uĝycie w metodzie hasChildren() metody getChildren() i sprawdzanie, czy tablica jest pusta, ale wydajnoĂÊ takiej operacji nie bÚdzie najlepsza, jeĂli getChildren() to operacja bardzo zïoĝona obliczeniowo. 14. Poniewaĝ TreeViewer moĝe mieÊ wiele korzeni, istnieje metoda pobierajÈca tablicÚ korzeni z elementu wejĂciowego. BïÈd we frameworku JFace uniemoĝliwia argumentowi getElements() posiadanie wïasnej wartoĂci. Z tego powodu przyjÚïo siÚ, ĝe najlepiej przekazaÊ tablicÚ (zawierajÈcÈ tylko jeden element) i nastÚpnie jÈ zwróciÊ. Metoda przedstawiona poniĝej bÚdzie najprawdopodobniej wyglÈdaïa tak samo dla kaĝdej klasy TreeContentProvider, którÈ kiedykolwiek napiszesz. public Object[] getElements(Object inputElement) { if (inputElement instanceof Object[]) { return (Object[]) inputElement; } else { return new Object[0]; } } 15. Po zakoñczeniu tworzenia odpowiednich klas dostawców danych przejdě do metody createPartControl() klasy TimeZoneTreeView, by poïÈczyÊ dostawców z obiektem widoku i ustaliÊ obiekt bÚdÈcy ěródïem danych. treeViewer.setLabelProvider(new TimeZoneLabelProvider()); treeViewer.setContentProvider(new TimeZoneContentProvider()); treeViewer.setInput(new Object[]{TimeZoneComparator.getTimeZones()}); 16. Uruchom testowÈ wersjÚ Eclipse i otwórz widok poleceniem Window/ShowView/ Other/¥ledzenie czasu/Widok drzewa stref czasowych, by zobaczyÊ efekt koñcowy. 87 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach Co siÚ staïo? Dane do TreeViewer przekazaliĂmy przy uĝyciu metody setInput(). Metoda prawie zawsze otrzymuje tablicÚ obiektów, nawet jeĂli jest to tylko jeden element. Aby zapewniÊ rozpakowanie struktury danych, interfejs ITreeContentProvider udostÚpnia dwie kluczowe metody — hasChildren() i getChildren(). UmoĝliwiajÈ one przechodzenie przez strukturÚ danych na ĝÈdanie, gdy uĝytkownik zwija lub rozwija gaïÚzie drzewa. Powodem istnienia dwóch metod jest fakt, iĝ obliczenia w metodzie getChildren() mogÈ byÊ bardzo kosztowne. Metoda hasChildren() sïuĝy do sprawdzenia, czy naleĝy wyĂwietliÊ ikonÚ rozwiniÚcia wÚzïa. Wywoïanie metody getChildren() jest opóěnione aĝ do momentu faktycznego otwarcia wÚzïa. W strukturach danych, które to zapewniajÈ, warto równieĝ zaimplementowaÊ metodÚ getParent(); umoĝliwia ona dostÚp do obiektu. JeĂli jest zaimplementowana, wywoïanie viewer.reveal(Object) powoduje rozwiniÚcie wÚzïów w hierarchii, by odsïoniÊ wskazany obiekt. Do wyĂwietlenia etykiet na drzewie sïuĝy klasa LabelProvider. Dostarcza ona etykietÚ (i opcjonalny obrazek) dla kaĝdego elementu. Dla kaĝdego typu obiektu moĝna uĝyÊ innej ikony. Z rozwiÈzania tego skorzystano w widoku Package z perspektywy Java, który wyĂwietla ikonÚ klasy dla klas, ikonÚ pakietu dla pakietów i tak dalej. Klasa LabelProvider moĝe wyĂwietlaÊ komunikaty na róĝne sposoby. Nic nie stoi na przeszkodzie, by dodaÊ do etykiety informacjÚ o przesuniÚciu czasowym (róĝnicÚ miÚdzy konkretnÈ strefÈ czasowÈ i czasem GMT). Kroki do wykonania — JFace i obrazy Klasa TimeZoneLabelProvider moĝe zwróciÊ obiekt Image bÚdÈcy standardowym widgetem SWT. ChoÊ obraz (obiekt Image) moĝna wczytaÊ w sposób podobny jak w poprzednim rozdziale, JFace oferuje rejestry zasobów sïuĝÈce do zarzÈdzania zestawami zasobów aplikacji. Rejestry obsïugujÈ klasy ImageRegistry, FontRegistry i ColorRegistry. Rejestr zasobów ma za zadanie przechowywaÊ listÚ obiektów Resource i zwalniaÊ je we wïaĂciwy sposób, ale tylko wtedy, gdy nie sÈ juĝ potrzebne. JFace posiada rejestry globalne, ale istniejÈ równieĝ rejestry bardziej szczegóïowe uĝywane przez IDE na przykïad do przechowywania list ikon folderów i plików. W rejestrze tego typu korzysta siÚ z deskryptorów do okreĂlania konkretnych zasobów, wiÚc po przekazaniu deskryptora otrzymuje siÚ odpowiadajÈcÈ mu instancjÚ zasobu. Zwróconym zasobem zarzÈdza rejestr, wiÚc kod, który go otrzyma, nie powinien go zwalniaÊ. 1. W TimeZoneLabelProvider dodaj metodÚ getImage(), w której uĝywa siÚ rejestru obrazów ImageRegistry, by pobraÊ ikonÚ folderu. Oto kod metody. 88 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace public Image getImage(Object element) { if(element instanceof Map.Entry) { return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); } else { return super.getImage(element); } } 2. Uruchom testowÈ wersjÚ Eclipse i otwórz Widok drzewa stref czasowych. Obok tekstu z nazwÈ regionu pojawi siÚ ikona folderu. Instancji Image nie trzeba niszczyÊ samodzielnie, poniewaĝ naleĝy do wtyczki PlatformUI (zasób obrazu zostanie zwolniony w momencie wyïÈczania PlatformUI). )E4: W Eclipse 4 instancjÚ ISharedImages moĝna otrzymaÊ poprzez wstrzykniÚcie. @Inject private ISharedImages images; images.getImage(ISharedImages.IMG_OBJ_FOLDER); 3. By otrzymaÊ inny obraz, uĝyj globalnych instancji ImageRegistry lub JFaceRegistry lub utwórz wïasnÈ kopiÚ. Zastosowanie globalnej wersji oznacza, ĝe obraz Image nigdy nie zostanie zniszczony, poniewaĝ JFaceRegistry istnieje przez caïy czas ĝycia instancji Eclipse. Zamiast tego utwórz obiekty LocalResourceManager i ImageRegistry powiÈzane z cyklem ĝycia kontrolki. Gdy kontrolka nadrzÚdna bÚdzie usuwana, automatycznie usuniÚte zostanÈ równieĝ obrazy. UmieĂÊ w metodzie CreatePartControl klasy TimeZoneTreeView poniĝszy kod. public void createPartControl(Composite parent) { ResourceManager rm = JFaceResources.getResources(); LocalResourceManager lrm = new LocalResourceManager(rm,parent); 4. UĝywajÈc obiektu LocalResourceManger, utwórz instancjÚ ImageRegistry i za pomocÈ metody createFromURL() dodaj obiekt ImageDescriptor na podstawie adresu URL. ImageRegistry ir = new ImageRegistry(lrm); URL sample = getClass().getResource("/icons/sample.gif"); ir.put("sample", ImageDescriptor.createFromURL(sample)); 89 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach 5. Po wypeïnieniu obiektu ImageRegistry trzeba go powiÈzaÊ z obiektem LabelProvider, by ten mógï uĝyÊ wïaĂciwego obrazu, jeĂli bÚdzie trzeba. Przekaĝ rejestr obrazów do konstruktora klasy TimeZoneLabelProvider. treeViewer.setLabelProvider(new TimeZoneLabelProvider()); treeViewer.setLabelProvider(new TimeZoneLabelProvider(ir)); 6. Zaimplementuj w TimeZoneLabelProvider konstruktor, który zapamiÚta obiekt ImageRegistry. NastÚpnie uĝyj go do pobrania obrazu w wywoïaniu getImage(). private final ImageRegistry ir; public TimeZoneLabelProvider(ImageRegistry ir) { this.ir = ir; } public Image getImage(Object element) { if(element instanceof Map.Entry) { return ir.get("sample"); } else if(element instanceof TimeZone) { return ir.get("sample"); } else { return super.getImage(element); } } 7. Ponownie uruchom testowÈ wersjÚ Eclipse. W drzewie pojawi siÚ przykïadowa ikona wtyczki. Co siÚ staïo? PoczÈtkowo uĝyliĂmy standardowych obrazów znajdujÈcych siÚ w obiekcie PlatformUI. Predefiniowane deskryptory pochodziïy z interfejsu ISharedImages. Nazwy deskryptorów zaczynajÈ siÚ od IMG; zastosowano w nich nastÚpujÈcy wzorzec: Q etool lub dtool — wïÈczone lub wyïÈczone ikony paska narzÚdziowego, Q elcl lub dlcl — wïÈczone lub wyïÈczone ikony lokalnego paska narzÚdziowego, Q dec — dekorator, Q obj i objs — obiekty (pliki, foldery i tym podobne). Inne wtyczki zawierajÈ wïasne zestawy obrazów, na przykïad interfejs JDT dodaje ikony zwiÈzane z pakietami, klasami, metodami i polami. 90 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace W celu uĝycia wïasnych obrazów utworzyliĂmy obiekt ImageRegistry obsïugiwany przez obiekt LocalResourceManager. JeĂli do konstruktora trafi obiekt Control, klasa rejestruje w nim obiekt DisposeListener. W ten sposób, gdy kontrola bÚdzie niszczona, podobnie stanie siÚ z powiÈzanymi z niÈ obrazami. DziÚki temu caïy kod jest bardziej przejrzysty, gdyĝ ImageRegistry moĝna bez wiÚkszych problemów przekazaÊ do klasy TimeZoneContentProvider. Obiekt ImageRegistry inicjalizujemy zestawem obiektów ImageDescriptor — w tym przypadku plikiem icons/sample.gif pochodzÈcym z kreatora wtyczek. Ten sam klucz sïuĝy do inicjalizacji i dostÚpu do obrazu. Niektóre projekty Eclipse trzymajÈ siÚ konwencji z interfejsem ISharedImages z zestawem staïych. Kroki do wykonania — style w dostawcy etykiet Interfejs IStyledLabelProvider sïuĝy do zmiany domyĂlnego stylu w widoku drzewa. Uĝyto go w widoku treĂci klas, który wyĂwietla typ zwracany przez metody, lub teĝ w dekoratorze zespoïów, który wyĂwietla informacjÚ o zmianach. 1. Dodaj interfejs IStyledLabelProvider do TimeZoneLabelProvider i utwórz metodÚ getStyledText(). JeĂli zaznaczonym elementem jest Map.Entry zawierajÈcy TimeZone, w nawiasach wskaĝ przesuniÚcie czasowe. public class TimeZoneLabelProvider extends LabelProvider implements IStyledLabelProvider { public StyledString getStyledText(Object element) { String text = getText(element); StyledString ss = new StyledString(text); if (element instanceof TimeZone) { int offset = -((TimeZone) element).getOffset(0); ss.append(" (" + offset / 3600000 + "h)", StyledString.DECORATIONS_ ´STYLER); } return ss; } } 2. By uĝyÊ dostawcy etykiet ze zmienionym stylem, trzeba go otoczyÊ klasÈ DelegatingStyledCellLabelProvider. Zmodyfikuj konstruktor wywoïywany w metodzie createPartControl() metody TimeZoneTreeView. treeViewer.setLabelProvider( new DelegatingStyledCellLabelProvider( new TimeZoneLabelProvider(ir))); 3. Uruchom testowÈ wersjÚ Eclipse i otwórz widok, by zobaczyÊ przesuniÚcia czasowe zapisane innym kolorem. 91 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach 4. By zmieniÊ czcionkÚ uĝywanÈ w widoku, klasa TimeZoneLabelProvider musi implementowaÊ interfejs IFontProvider. Klasa FontRegistry z JFace umoĝliwia pobranie domyĂlnej czcionki z wïÈczonÈ kursywÈ. Dodaj parametr FontRegistry do konstruktora TimeZoneLabelProvider i zaimplementuj metodÚ getFont(). public class TimeZoneLabelProvider extends LabelProviderimplements ´IStyledLabelProvider, IFontProvider { private final FontRegistry fr; public TimeZoneLabelProvider(ImageRegistry ir, FontRegistry fr){ this.ir = ir; this.fr = fr; } public Font getFont(Object element) { Font italic = fr.getItalic(JFaceResources.DEFAULT_FONT); return italic; } } 5. Zmodyfikuj klasÚ TimeZoneTreeView, by utworzyÊ i przekazaÊ globalny obiekt FontRegistry pobrany z klasy JFaceResources. FontRegistry fr = JFaceResources.getFontRegistry(); treeViewer.setLabelProvider( new DelegatingStyledCellLabelProvider( new TimeZoneLabelProvider(ir))); treeViewer.setLabelProvider( new DelegatingStyledCellLabelProvider( new TimeZoneLabelProvider(ir, fr))); 6. Ponownie uruchom testowÈ wersjÚ Eclipse, by przekonaÊ siÚ, ĝe strefy czasowe sÈ teraz pisane kursywÈ. Co siÚ staïo? ImplementujÈc interfejs IStyledLabelProvider i otaczajÈc go klasÈ DelegatingStyledCellLabelProvider, moĝna zmieniaÊ styl poszczególnych elementów drzewa, wïÈcznie ze zmianami czcionki i koloru. Klasa StyledText umoĝliwia wyĂwietlanie tekstu róĝnymi stylami. ChoÊ w przykïadzie pojawiïa siÚ klasa DecorationsStyler, dodatkowe style moĝna takĝe zdefiniowaÊ przy uĝyciu wywoïania StyledString.createColorRegistryStyler("czcionka", "tïo"), gdzie oba teksty to klucze w globalnym obiekcie ColorRegistry z JFace. 92 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace ChoÊ kolory moĝna zmieniaÊ dla poszczególnych znaków, czcionka (obiekt Font) jest jedna dla caïego tekstu. Wynika to z faktu, iĝ wyliczenia rozmiaru etykiety zakïadajÈ, ĝe caïy tekst jest pisany identycznÈ czcionkÈ. Jako dobrÈ praktykÚ uwaĝa siÚ uĝywanie przez dostawców treĂci i etykiet menedĝerów zasobów przekazywanych do konstruktorów. DziÚki temu kod ïatwo sprawdziÊ za pomocÈ testów automatycznych i pozorowanych zasobów. Niezaleĝnie od tego, czy stosuje siÚ model programistyczny Eclipse 3.x, czy Eclipse 4.x, oddzielenie uĝycia zasobów od miejsca ich tworzenia to klucz do wygodnego testowania. Quiz — podstawy JFace P1. Jakie metody zawiera LabelProvider? P2. Jaka jest róĝnica miÚdzy metodami hasChildren() i getChildren() z ContentProvider? P3. Do czego sïuĝy klasa ImageRegistry? P4. W jaki sposób zmieniÊ styl elementów widoku drzewa? Sprawdě siÚ — dodanie obrazów dla regionów Po poznaniu podstaw postaraj siÚ rozszerzyÊ przykïad o kilka elementów. Q Popraw klasÚ TimeZoneLabelProvider, by podawaïa przesuniÚcie w godzinach i minutach wzglÚdem GMT. Q Uaktualnij wtyczkÚ, dodajÈc ikony flag i tworzÈc wpisy w rejestrze obrazów (nazwa strefy czasowej moĝe byÊ kluczem, co uïatwi caïÈ obsïugÚ). Q WyĂwietl nazwÚ regionu kursywÈ, ale same nazwy stref czasowych pogrubionÈ czcionkÈ. Sortowanie i filtracja JednÈ z cech JFace jest to, ĝe za sortowanie danych moĝe odpowiadaÊ widok, co odciÈĝa strukturÚ danych od odpowiedzialnoĂci za wïaĂciwe przetwarzanie materiaïów. W ten sposób bardzo ïatwo utworzyÊ widoki z filtracjÈ, w których uĝytkownik szuka okreĂlonej frazy lub teĝ sortuje wyniki zgodnie ze swym zapotrzebowaniem. Filtry sÈ powszechnie uĝywane w IDE Eclipse. Przykïadem sÈ chociaĝby opcje Hide libraries from external lub Hide closed projects znajdujÈce siÚ w opcjach wielu widoków. 93 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach Kroki do wykonania — sortowanie elementów w widoku Widok drzewa wyĂwietla obecnie dane w sposób posortowany, ale za sortowanie nie odpowiada widok. Poniewaĝ dane znajdujÈ siÚ w obiekcie TreeMap, wykonuje on automatyczne sortowanie elementów na podstawie wartoĂci zwracanych przez metodÚ toString(). By uĝyÊ innego sposobu sortowania (na przykïad bazujÈcego na przesuniÚciu czasu), moĝna albo zmodyfikowaÊ obiekt TreeMap, dodajÈc nowy komparator i sortujÈc dane przy ich tworzeniu, albo sortowaÊ na poziomie widoku drzewa. Pierwszy wybór jest dobry tylko w sytuacji, gdy z danych korzysta jeden widok lub gdy dane pochodzÈ z duĝego, zewnÚtrznego magazynu danych, który przeprowadzi sortowanie zdecydowanie bardziej efektywnie (takiego jak na przykïad relacyjna baza danych). W mniejszych zbiorach danych sortowaniem moĝe zajÈÊ siÚ widok. 1. Widoki strukturyzowane JFace umoĝliwiajÈ sortowanie przy uĝyciu klasy ViewerComparator. Utwórz nowÈ klasÚ — TimeZoneViewerComparator — w pakiecie com.packtpub.e4.clock.ui.internal i zaimplementuj metodÚ compare(). public class TimeZoneViewerComparator extends ViewerComparator { public int compare(Viewer viewer, Object o1, Object o2) { int compare; if (o1 instanceof TimeZone && o2 instanceof TimeZone) { long time= System.currentTimeMillis(); compare=((TimeZone)o2).getOffset(time) - ((TimeZone)o1).getOffset(time); } else { compare = o1.toString().compareTo(o2.toString()); } return compare; } } 2. Podepnij nowÈ klasÚ porównywania do widoku. treeViewer.setComparator(new TimeZoneViewerComparator()); 3. Uruchom testowÈ wersjÚ Eclipse i otwórz Widok drzewa stref czasowych. Strefy czasowe powinny byÊ posortowane najpierw po przesuniÚciu czasu, a nastÚpnie alfabetycznie. 4. Aby dodaÊ sortowanie specyficzne dla widoku, zmodyfikuj metodÚ compare() z TimeZoneViewerComparator, by otrzymaÊ klucz REVERSE z danych widoku. Uĝyj go do odwrócenia sortowania wyników. 94 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace return compare; boolean reverse = Boolean.parseBoolean(String.valueOf(viewer.getData("REVERSE"))); return reverse ? -compare : compare; 5. Aby zobaczyÊ efekt dziaïania nowego sortowania, ustaw klucz REVERSE tuĝ przed wywoïaniem setComparator() na koñcu metody createPartControl() z TimeZoneTreeView. treeViewer.setData("REVERSE",Boolean.TRUE); treeViewer.setComparator(new TimeZoneViewerComparator()); 6. Ponownie uruchom testowÈ wersjÚ Eclipse, by przekonaÊ siÚ, ĝe wyniki posortowane sÈ odwrotnie niĝ poprzednio. Co siÚ staïo? DodajÈc obiekt ViewerComparator do obiektu Viewer, moĝemy okreĂliÊ sposób sortowania danych w konkretnym widoku. OczywiĂcie, najczÚĂciej bÚdzie to powiÈzane z wyborem odpowiedniej opcji w widoku — moĝe to byÊ opcja odwracajÈca sortowanie lub teĝ zmieniajÈca sortowanie miÚdzy nazwÈ i przesuniÚciem czasu. ImplementujÈc obiekt komparatora, warto upewniÊ siÚ, ĝe metoda bÚdzie obsïugiwaïa róĝne typy obiektów (wïÈczajÈc te, których siÚ nie oczekuje). Dane w widoku mogÈ siÚ zmieniaÊ lub byÊ inne w trakcie dziaïania aplikacji. Korzystaj z instanceof, by upewniÊ siÚ, ĝe typ jest wïaĂciwy. Aby zapamiÚtaÊ wïaĂciwoĂci specyficzne dla widoku, uĝyj metod setData() i getData() z widoku. DziÚki temu moĝna uĝyÊ ogólnego komparatora w wielu róĝnych widokach przy jednoczesnym respektowaniu ustawieñ filtracji i sortowania dla konkretnego widoku. Przedstawiony przykïad zawiera dane sortowania ustawione na staïe, co wymaga ponownego uruchomienia Eclipse, by zobaczyÊ efekt zmian. Po zmianie wïaĂciwoĂci widoku, które wpïywajÈ na sortowanie lub filtracjÚ, wywoïaj metodÚ refresh() widoku, by zaktualizowaÊ wyĂwietlane dane zgodnie z nowymi ustawieniami. Kroki do wykonania — filtrowanie elementów w widoku InnÈ, czÚsto wykorzystywanÈ w widokach funkcjÈ jest filtracja. Sïuĝy ona do rÚcznego wyszukiwania konkretnego elementu lub teĝ poszukiwania konkretnych elementów widoku. Bardzo czÚsto filtracjÚ wiÈĝe siÚ z menu widoku, czyli menu rozwijanym po klikniÚciu trójkÈta w prawym górnym rogu widoku. NajczÚĂciej stosuje siÚ nazwÚ Filters (filtry). Klasa ViewerFilter zawiera metodÚ dotyczÈcÈ filtracji nazywanÈ select(). (IstniejÈ metody filter(), ale sïuĝÈ one do filtracji caïej tablicy; metoda select() uĝywana jest do okreĂlenia, czy naleĝy wyĂwietliÊ konkretny element, czy teĝ go pominÈÊ). 95 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach 1. Utwórz klasÚ TimeZoneViewerFilter w pakiecie com.packtpub.e4.clock.ui.internal, która dziedziczy po klasie ViewerFilter. Konstruktor powinien przyjmowaÊ wzorzec typu String. Metoda select() musi zwracaÊ true, jeĂli element jest typu TimeZone i zawiera w swej nazwie wzorzec. public class TimeZoneViewerFilter extends ViewerFilter { private String pattern; public TimeZoneViewerFilter(String pattern) { this.pattern = pattern; } public boolean select(Viewer v, Object parent, Object element) { if(element instanceof TimeZone) { TimeZone zone = (TimeZone)element; return zone.getDisplayName().contains(pattern); } else { return true; } } } 2. Filtr ustawia siÚ na poziomie widoku. Poniewaĝ widoki mogÈ mieÊ kilka filtrów, przekazuje siÚ je do widoku jako tablicÚ. W tym przypadku wzorzec filtru ustawiamy w konstruktorze, ale w rzeczywistoĂci zostaïby pobrany od uĝytkownika. Zmodyfikuj klasÚ TimeZoneTreeView na koñcu metody createPartControl(). treeViewer.setFilters(new ViewerFilter[] { new TimeZoneViewerFilter("GMT")}); 3. Uruchom testowÈ wersjÚ Eclipse i otwórz widok. WyĂwietlane sÈ tylko strefy czasowe z regionu Etc. 4. Aby usunÈÊ ikony rozwijania wÚzïów przy pozostaïych elementach, moĝna wïÈczyÊ w widoku drzewa automatyczne wykonywanie testów rozwiniÚÊ wÚzïów. treeViewer.setExpandPreCheckFilters(true); 5. Ponownie uruchom testowÈ wersjÚ Eclipse i otwórz Widok drzewa stref czasowych. Zauwaĝ, ĝe puste grupy nadal sÈ wyĂwietlane, ale nie ma juĝ obok nich ikon rozwijania, bo po filtracji nie majÈ juĝ elementów potomnych. 96 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace Co siÚ staïo? Klasa TimeZoneViewerFilter powstaïa jako podklasa klasy ViewerFilter i jest przekazywana do klasy TreeViewer. W trakcie wyĂwietlania i filtracji danych filtr jest wywoïywany dla kaĝdego elementu drzewa (wïÈcznie z korzeniem). DomyĂlnie, gdy metoda hasChildren() zwróci wartoĂÊ true, pojawi siÚ ikona rozwiniÚcia gaïÚzi. Po klikniÚciu algorytm przejdzie przez wszystkie potomki i wykona dla nich operacjÚ filtracji. Jeĝeli okaĝe siÚ, ĝe po filtracji nie pozostaï ani jeden element, algorytm usunie ikonÚ rozwiniÚcia. WïÈczenie opcji setExpandPreCheckFilters(true) dla widoku spowoduje, ĝe widok juĝ na samym poczÈtku sprawdzi, czy po filtracji w gaïÚzi pozostanie choÊ jeden potomek. Opcja nie ma ĝadnych negatywnych konsekwencji, jeĂli w ogóle nie ustawiono w niej filtrów. JeĂli filtry sÈ ustawione, a danych w zbiorze jest duĝo, wykonanie operacji sprawdzenia moĝe zajÈÊ sporo czasu. Aby domyĂlnie wyĂwietliÊ wszystkie elementy drzewa lub teĝ zwinÈÊ je do pojedynczego elementu, uĝyj metod expandAll() i collapseAll(). NajczÚĂciej metody te wywoïuje siÚ z poziomu ikon typu [+] i [-] umieszczonych w lokalnym pasku narzÚdziowym widoku (patrz widoki Synchronize i Package Explorer). JeĂli dane majÈ strukturÚ drzewiastÈ, która domyĂlnie powinna wyĂwietliÊ tylko czÚĂÊ poziomów, warto zastosowaÊ metody expandToLevel() i collapseToLevel() przyjmujÈce wartoĂÊ caïkowitÈ i obiekt (uĝyj getRoot() dla korzenia, jeĂli obiekt nie jest jawnie okreĂlony). SpowodujÈ one rozwiniÚcie lub zwiniÚcie wszystkich elementów do zadanego poziomu. Metoda expandAll() to skrót wywoïujÈcy metodÚ expandToLevel(getRoot(), ALL_LEVELS). W odpowiedzi na zdarzenie wyboru, które zawiera ukryty obiekt, warto wykonaÊ wczeĂniej operacjÚ reveal(), by konkretny element staï siÚ widoczny. PamiÚtaj, ĝe reveal() dziaïa tylko wtedy, gdy metoda getParent() jest poprawnie zaimplementowana, co w prezentowanym przykïadzie nie ma miejsca. Quiz — sortowanie i filtracja P1. Jak posortowaÊ elementy drzewa w sposób inny niĝ domyĂlny? P2. Jaka metoda sïuĝy do filtracji elementów? P3. W jaki sposób poïÈczyÊ kilka filtrów? Sprawdě siÚ — rozwijanie gaïÚzi i filtracja Po poznaniu zasad dotyczÈcych sortowania i filtracji rozbuduj przykïad o kilka nowych elementów. Q Dodaj drugi filtr, który usuwa wszystkie strefy czasowe z ujemnym przesuniÚciem czasu. Q Po otwarciu widoku wykonaj operacjÚ expandAll(). 97 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach Q Zastosuj sortowanie, w którym regiony sÈ uïoĝone w odwrotnej kolejnoĂci alfabetycznej, ale strefy czasowe — w porzÈdku alfabetycznym. Q Dodaj okno dialogowe pozwalajÈce na zmianÚ wzorca filtru. Dodatkowo uĝyj pustego ciÈgu znaków jako wartoĂci stosowanej do usuniÚcia filtracji. Interakcje i wïaĂciwoĂci MoĝliwoĂÊ wyĂwietlenia danych to jedna rzecz, ale w wiÚkszoĂci widoków najwaĝniejsza jest interaktywnoĂÊ. Niezaleĝnie od tego, czy dotyczy to funkcjonalnoĂci sortowania i filtracji z wczeĂniejszej czÚĂci rozdziaïu, czy wyboru konkretnych elementów, widoki muszÈ byÊ elementami interaktywnymi, by moĝna ich uĝyÊ nie tylko do przeglÈdania danych, ale równieĝ do ich edycji. Kroki do wykonania — dodanie procedury obsïugi podwójnego klikniÚcia Widok drzewa najczÚĂciej sïuĝy do wyĂwietlania treĂci w sposób hierarchiczny. Niestety, drzewo nie jest odpowiedniÈ strukturÈ, by wyĂwietliÊ wszystkie szczegóïy obiektu. Po podwójnym klikniÚciu konkretnego elementu warto wyĂwietliÊ jego szczegóïy. 1. Na koñcu metody createPartControl() klasy TimeZoneTreeView zarejestruj anonimowÈ klasÚ wewnÚtrznÈ implementujÈcÈ interfejs IDoubleClickListener i dodaj jÈ metodÈ addDoubleClickListener() do obiektu treeViewer. Podobnie jak w rozdziale 1., otwórz okno dialogowe, by sprawdziÊ, czy wszystko zadziaïaïo prawidïowo. treeViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { Viewer viewer = event.getViewer(); Shell shell = viewer.getControl().getShell(); MessageDialog.openInformation(shell, "Podwójne klikniÚcie", "Wykryto ´podwójne klikniÚcie"); } }); 2. Uruchom testowÈ wersjÚ Eclipse i otwórz widok. Podwójnie kliknij drzewo, a pojawi siÚ komunikat Wykryto podwójne klikniÚcie. Okno jest typu modalnego, co zapobiega wybraniu innych elementów interfejsu aĝ do momentu zamkniÚcia okna. 3. By znaleěÊ wybrane obiekty, Eclipse udostÚpnia interfejs ISelection (który zapewnia jedynie metodÚ isEmpty()) oraz interfejs IStructuredSelection (zapewnia iterator i inne metody dostÚpowe). Istnieje równieĝ kilka wyspecjalizowanych podtypów, na przykïad ITreeSelection, który potrafi przeĂledziÊ ĂcieĝkÚ prowadzÈcÈ do aktualnie wybranego elementu drzewa. W metodzie dotyczÈcej podwójnego klikniÚcia znajdujÈcej siÚ w metodzie createPartControl() klasy TimeZoneTreeView zastÈp fragment MessageDialog poniĝszym kodem. 98 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace MessageDialog.openInformation(shell, Podwójne klikniÚcie", "Wykryto podwójne ´klikniÚcie"); ISelection sel = viewer.getSelection(); Object selectedValue; if (!(sel instanceof IStructuredSelection) || sel.isEmpty()) { selectedValue = null; } else { selectedValue = ((IStructuredSelection)sel).getFirstElement(); } if (selectedValue instanceof TimeZone) { TimeZone timeZone = (TimeZone)selectedValue; MessageDialog.openInformation(shell, timeZone.getID(), timeZone.toString()); } 4. Uruchom Eclipse i otwórz widok. Dwukrotnie kliknij element drzewa, a pojawi siÚ okno informacyjne z tekstem zawierajÈcym nazwÚ strefy czasowej. 5. Aby wyĂwietliÊ wiÚcej informacji na temat obiektu TimeZone, utwórz podklasÚ klasy MessageDialog o nazwie w TimeZoneDialog i umieĂÊ jÈ w pakiecie com.packtpub.e4.clock.ui.internal. Implementacja ma nastÚpujÈcÈ postaÊ. public class TimeZoneDialog extends MessageDialog { private TimeZone timeZone; public TimeZoneDialog(Shell parentShell, TimeZone timeZone) { super(parentShell, timeZone.getID(), null, "Strefa czasowa " + timeZone. ´getID(), INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); this.timeZone = timeZone; } } 6. TreĂÊ okna zapewnia metoda CustomArea() uĝywana do budowania zawartoĂci widoku. Dodaj do klasy TimeZoneDialog metodÚ createCustomArea(). protected Control createCustomArea(Composite parent) { ClockWidget clock = new ClockWidget(parent,SWT.NONE, new RGB(128,255,0)); clock.setOffset((TimeZone.getDefault().getOffset(System.currentTimeMillis()) ´- timeZone.getOffset(System.currentTimeMillis()))/3600000); return parent; } 7. Na koñcu zmodyfikuj wywoïanie MessageDialog.open() z klasy TimeZoneTreeView, by korzystaïo z nowej implementacji. if (selectedValue instanceof TimeZone) { TimeZone timeZone = (TimeZone) selectedValue; MessageDialog.openInformation(shell, timeZone.getID(), timeZone. ´toString()); new TimeZoneDialog(shell, timeZone).open(); } 99 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach 8. Uruchom testowÈ wersjÚ Eclipse i dwukrotnie kliknij strefÚ czasowÈ, by zobaczyÊ okno dialogowe. Co siÚ staïo? DodaliĂmy procedurÚ obsïugi podwójnego klikniÚcia i zarejestrowaliĂmy jÈ za pomocÈ metody addDoubleClickListener(). PoczÈtkowo wyĂwietlaliĂmy standardowe okno informacyjne, ale póěniej utworzyliĂmy wïasnÈ podklasÚ MessageDialog, która korzysta z klasy ClockWidget. By otrzymaÊ odpowiedniÈ strefÚ czasowÈ (obiekt TimeZone), pobraliĂmy aktualnie zaznaczony obiekt z TreeViewer. Za zaznaczanie odpowiada interfejs ISelection. Metoda getSelection() powinna zawsze zwróciÊ wartoĂÊ innÈ niĝ null, ale czasem uzyskana wartoĂÊ spowoduje zwrócenie true po uĝyciu jej w metodzie isEmpty(). IstniejÈ jednak dwa interesujÈce interfejsy pochodne — IStructuredSelection i ITreeSelection. Interfejs ITreeSelection jest podtypem IStructuredSelection i dodaje metody specyficzne dla drzew. Umoĝliwia otrzymanie informacji o aktualnie zaznaczonych elementach i ich elementach nadrzÚdnych (w strukturze drzewa). Interfejs IStructuredSelection jest chyba najczÚĂciej stosowanym interfejsem, gdy chodzi o systemy wyboru. JeĂli wybór nie jest pusty, praktycznie zawsze jest instancjÈ implementujÈcÈ IStructuredSelection. Z tego powodu bardzo czÚsto moĝna zobaczyÊ poniĝszy fragment kodu. ISelection sel = viewer.getSelection(); Object selectedValue; if (!(sel instanceof IStructuredSelection) || sel.isEmpty()) { selectedValue = null; } else { selectedValue = ((IStructuredSelection)sel).getFirstElement(); } Fragment pobiera zaznaczenie z widoku. JeĂli wynik nie jest instancjÈ IStructuredSelection lub jest pusty, przypisuje zmiennej selectedValue wartoĂÊ null. W pozostaïych sytuacjach rzutuje otrzymany obiekt na interfejs IStructuredSelection i wywoïuje metodÚ getFirstElement(), by pobraÊ pojedynczÈ wartoĂÊ zaznaczenia. 100 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace Zaznaczeniu mogïo ulec wiÚcej elementów, co oznacza, ĝe metoda getFirstElement() zwraca jedynie pierwszy z nich. Klasa implementujÈca IStructuredSelection musi zapewniÊ iterator umoĝliwiajÈcy pobranie wszystkich zaznaczonych obiektów. )E4: W Eclipse 4 zaznaczony obiekt moĝna wstrzyknÈÊ do metody za pomocÈ adnotacji. @Inject @Optional void setTZ(@Named(IServiceConstants.ACTIVE_SELECTION) TimeZone timeZone) { } Kroki do wykonania — wyĂwietlanie wïaĂciwoĂci IDE Eclipse, zamiast wymuszaÊ tworzenie coraz to nowych okien dialogowych dla kaĝdego obiektu, udostÚpnia ogólny widok wïaĂciwoĂci (znajdujÈcy siÚ we wtyczce org.eclipse.ui.views), który sïuĝy do wyĂwietlania informacji o aktualnie zaznaczonym obiekcie. WïaĂciwoĂci sÈ odkrywane w sposób uogólniony, a dostÚp do nich zapewnia interfejs IPropertySource. DziÚki temu obiekt moĝe wprowadziÊ abstrakcjÚ w kwestii wyliczania wartoĂci pól pokazywanych w oknie wïaĂciwoĂci. Najprostszym sposobem utworzenia ěródïa wïaĂciwoĂci jest zapewnienie, by obiekt sam zaimplementowaï interfejs IPropertySource. OczywiĂcie, jest to moĝliwe tylko w sytuacji, gdy kod ěródïowy moĝna zmieniÊ, ale w wielu sytuacjach (na przykïad w przypadku obiektu TimeZone lub Map.Entry zawierajÈcego klucz typu String i obiekt TimeZone) kod ěródïowy nie jest dostÚpny. 1. Otwórz plik MANIFEST/META-INF.MF i dodaj org.eclipse.ui.views jako zaleĝnoĂÊ w zakïadce Dependencies lub jako paczkÚ w Require-Bundle. W przeciwnym razie IPropertySource nie bÚdzie odnajdywane. 2. Utwórz w pakiecie com.packtpub.e4.clock.ui.internal klasÚ TimeZonePropertySource implementujÈcÈ interfejs IPropertySource. W konstruktorze przyjmij pojedynczÈ instancjÚ TimeZone. public class TimeZonePropertySource implements IPropertySource { private TimeZone timeZone; public TimeZonePropertySource(TimeZone timeZone) { this.timeZone = timeZone; } } 3. Jedynymi metodami, które trzeba zaimplementowaÊ, sÈ getPropertyValue() i getPropertyDescriptors(). (Pozostaïe metody, takie jak getEditableValue() i isPropertySet(), moĝna zignorowaÊ, bo uĝywa siÚ ich tylko w operacjach edycji. Powinny pozostaÊ puste lub zwracaÊ null albo false. Metody getPropertyValue() i isPropertySet() wywoïuje siÚ z identyfikatorem. Pozostaïe metody zwracajÈ tablice obiektów PropertyDescriptors ïÈczÈce identyfikator i nazwÚ wïaĂciwoĂci do wyĂwietlenia w interfejsie graficznym. Dodaj poniĝszy kod do klasy TimeZonePropertySource. 101 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach private static final Object ID = new Object(); private static final Object DAYLIGHT = new Object(); private static final Object NAME = new Object(); public IPropertyDescriptor[] getPropertyDescriptors() { return new IPropertyDescriptor[] { new PropertyDescriptor(ID, "Strefa czasowa"), new PropertyDescriptor(DAYLIGHT, "Czas letni"), new PropertyDescriptor(NAME, "Nazwa") }; } public Object getPropertyValue(Object id) { if (ID.equals(id)) { return timeZone.getID(); } else if(DAYLIGHT.equals(id)) { return timeZone.inDaylightTime(new Date()); } else if (NAME.equals(id)) { return timeZone.getDisplayName(); } else { return null; } } 4. PowiÈzanie ěródïa wïaĂciwoĂci z oknem wïaĂciwoĂci wymaga uĝycia adaptera. Moĝna go wskazaÊ za pomocÈ interfejsu IAdaptable, który umoĝliwia klasie wirtualnÈ implementacjÚ interfejsu. Poniewaĝ TimeZone nie moĝe zaimplementowaÊ IAdaptable w sposób bezpoĂredni, potrzebujemy IAdapterFactory. 5. Utwórz w pakiecie com.packtpub.e4.clock.ui.internal klasÚ TimeZoneAdapterFactory implementujÈcÈ interfejs IAdapterFactory. public class TimeZoneAdapterFactory implements IAdapterFactory { public Class[] getAdapterList() { return new Class[] { IPropertySource.class }; } public Object getAdapter(Object o, Class type) { if(type == IPropertySource.class && o instanceof TimeZone) { return new TimeZonePropertySource((TimeZone)o); } else { return null; } } } 6. Aby zarejestrowaÊ fabrykÚ adapterów w Eclipse, dodaj odpowiedni wpis w pliku plugin.xml. <extension point="org.eclipse.core.runtime.adapters"> <factory adaptableType="java.util.TimeZone" class="com.packtpub.e4.clock.ui.internal.TimeZoneAdapterFactory"> <adapter type="org.eclipse.ui.views.properties.IPropertySource"/> </factory> </extension> 102 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace 7. Uruchom testowÈ wersjÚ Eclipse, wybierz strefÚ czasowÈ w widoku drzewa i otwórz okno wïaĂciwoĂci poleceniem Window/Show View/Other/General/Properties z menu. Nie pojawiÈ siÚ ĝadne informacje. By mieÊ pewnoĂÊ, ĝe adapter jest podpiÚty prawidïowo, dodaj na koñcu metody createPartControl() z TimeZoneTreeView nastÚpujÈcy wpis. System.out.println("Adapterem jest " + Platform.getAdapterManager(). ´getAdapter(TimeZone.getDefault(),IPropertySource.class)); 8. Uruchom testowÈ wersjÚ Eclipse, otwórz Widok drzewa stref czasowych i sprawdě widok Console gïównego Eclipse. Konsola powinna zawieraÊ wpis podobny do poniĝszego. Adapterem jest com.packtpub.e4.clock.ui.internal.TimeZonePropertySource ´@7f8a6fb0 9. Czego wiÚc brakuje? Okazuje siÚ, ĝe okno Properties nie otrzymuje informacji o zmianie zaznaczenia. By rozwiÈzaÊ problem, dodaj w metodzie createPartControl() z TimeZoneTreeView nastÚpujÈcy wpis. System.out.println("Adapterem jest " + Platform.getAdapterManager(). ´getAdapter(TimeZone.getDefault(),IPropertySource.class)); getSite().setSelectionProvider(treeViewer); 10. Teraz zmiany zaznaczenia bÚdÈ przekazywane do IDE, by inne widoki mogïy zaktualizowaÊ swoje dane. Po wybraniu strefy czasowej okno Properties bÚdzie aktualizowaïo siÚ automatycznie. Uruchom testowÈ wersjÚ Eclipse, otwórz Widok drzewa stref czasowych, wybierz strefÚ czasowÈ i otwórz widok Properties. )E4: W celu powiÈzania widoku z dostawcÈ zaznaczania naleĝy uĝyÊ kodu podobnego do poniĝszego. @Inject ESelectionService selectionService; ISelectionChangedListener selectionListener; @PostConstruct public void postConstruct() { selectionListener = new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent e) { if (selectionService != null) selectionService.setSelection(e.getSelection()); } }; treeViewer.addSelectionChangedListener(selectionListener); 103 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach } @PreDestroy public void preDestroy() { if(selectionListener != null) treeViewer.removeSelectionChangedListener(selectionListener); selectionListener = null; } Co siÚ staïo? Aby zaktualizowaÊ stan zaznaczenia IDE, musieliĂmy powiÈzaÊ dostawcÚ zaznaczenia widoku z tym, który dotyczy IDE (metoda getSite()). Gdy zmieni siÚ zaznaczenie elementu w widoku, widok wyĂle komunikat do wszystkich nasïuchujÈcych obiektów, by te mogïy odpowiednio zaktualizowaÊ swoje dane. )E4: ProcedurÚ obsïugi zaznaczenia trzeba zarejestrowaÊ (i wyrejestrowaÊ) rÚcznie, by zapewniÊ wïaĂciwe powiÈzanie miÚdzy widokiem i usïugÈ zaznaczenia. Zamiast ISelectionService uĝywa siÚ ESelectionService. Interfejs jest nieco inny, poniewaĝ ISelectionService jest powiÈzany z klasÈ IWorkbenchPart, a ESelectionService nie posiada podobnego powiÈzania. W celu zapewnienia informacji dla widoku Properties utworzyliĂmy dla TimeZone klasÚ bazujÈcÈ na interfejsie IPropertySource i powiÈzaliĂmy jÈ z IAdapterManager obiektu Platform poprzez deklaracjÚ w pliku plugin.xml. PowiÈzania znacznie wygodniej tworzyÊ w sposób deklaratywny w pliku plugin.xml, bo nie trzeba stosowaÊ metod aktywacyjnych start() i stop(). Wynika to z faktu, iĝ metoda startowa z Activator nie moĝe zostaÊ wywoïana aĝ do momentu wczytania pierwszej klasy z paczki; w przypadku adaptera rejestracja deklaratywna zapewnia odpowiedniÈ informacjÚ niezaleĝnie od kolejnoĂci wczytywania. Fabryka adapterów zapewnia metodÚ getAdapter(), która odpowiada za otoczenie lub konwersjÚ przekazanego obiektu na obiekt poĝÈdanego typu. JeĂli obiekt jest juĝ instancjÈ docelowego typu, zostanie po prostu zwrócony — w przeciwnym razie metoda zwraca POJO, poĂrednika lub otoczkÚ implementujÈcÈ poĝÈdany interfejs. CzÚsto zdarza siÚ, ĝe posiadamy klasÚ (na przykïad TimeZonePropertySupport), której jedynym zadaniem jest implementacja poĝÈdanego interfejsu. Klasa tego typu stanowi otoczkÚ dla obiektu (TimeZone) w celu zapewnienia wymaganej funkcjonalnoĂci. Interfejs IPropertySupport zapewnia podstawowe metody do pobierania wïaĂciwoĂci obiektu. Do identyfikacji wïaĂciwoĂci uĝywa identyfikatorów. Identyfikator moĝe byÊ obiektem dowolnego typu. W prezentowanym przykïadzie byïy to instancje new Object. ChoÊ moĝna uĝyÊ obiektów typu String (co moĝna zobaczyÊ w wielu przykïadach), nie jest to podejĂcie zalecane, poniewaĝ wartoĂÊ obiektu String nie ma znaczenia, ale zajmuje miejsce w przestrzeni PermGen pamiÚci maszyny wirtualnej. Co wiÚcej, obiekt Object umoĝliwia porównywanie instancji za 104 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace pomocÈ operacji == bez naraĝania siÚ na ostrzeĝenia automatycznych testów stylu lub pytania przy ocenie kodu. (Inne przykïady stosujÈ metodÚ equals(), by zachÚciÊ do jej uĝycia, gdy nie sÈ stosowane obiekty Object, ale dobry JIT i tak wykona optymalizacjÚ, szczególnie wtedy, gdy kod wysyïa wiadomoĂÊ do instancji typu static final). Quiz — dziaïanie wïaĂciwoĂci P1. Jak instancje TableViewer mogÈ reagowaÊ na klikniÚcie? P2. Dlaczego tworzy siÚ podklasy klasy Dialog? P3. Czym sÈ deskryptory wïaĂciwoĂci? P4. Jak wyĂwietliÊ wïaĂciwoĂci w widoku Properties? Dane tabelaryczne Widok drzewa pojawia siÚ w Eclipse bardzo czÚsto, ale czasem trzeba wyĂwietliÊ dodatkowe informacje zwiÈzane z pojedynczym elementem. JFace zapewnia klasÚ TableViewer podobnÈ do TreeViewer, ale zamiast pojedynczych etykiet moĝna wyĂwietlaÊ wiele kolumn z danymi. Istnieje równieĝ klasa TableTreeViewer, która ïÈczy funkcjonalnoĂÊ obu klas. Kroki do wykonania — przeglÈdanie stref czasowych w tabeli Aby wyĂwietlaÊ strefy czasowe w postaci tabelarycznej, utworzymy nowy widok o nazwie Widok tabeli stref czasowych. 1. Kliknij prawym przyciskiem myszy projekt com.packtpub.e4.clock.ui i wybierz polecenie Plug-in Tools/Open Manifest. Otwórz zakïadkÚ Extensions, kliknij prawym przyciskiem myszy org.eclipse.ui.views i wybierz New/View. Wypeïnij pola w nastÚpujÈcy sposób. Q W polu ID wpisz com.packtpub.e4.clock.ui.views.TimeZoneTableView. Q W polu Name wpisz Widok tabeli stref czasowych. Q W polu Class wpisz com.packtpub.e4.clock.ui.views.TimeZoneTableView. Q W polu Category wpisz com.packtpub.e4.clock.ui. Q W polu Icon wpisz icons/sample.gif. 2. Plik plugin.xml powinien po tej operacji zawieraÊ nastÚpujÈcy fragment. <view category="com.packtpub.e4.clock.ui" class="com.packtpub.e4.clock.ui.views.TimeZoneTableView" 105 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach icon="icons/sample.gif" id="com.packtpub.e4.clock.ui.views.TimeZoneTableView" name="Widok tabeli stref czasowych" restorable="true"> </view> 3. Utwórz nowÈ klasÚ TimeZoneTableView rozszerzajÈcÈ ViewPart na podstawie skrótu z edytora lub skorzystaj z nowego kreatora klas. Po utworzeniu widoku dodaj pusty obiekt TableViewer i uĝyj klasy ArrayContentProvider z listÈ dostÚpnych stref czasowych. public class TimeZoneTableView extends ViewPart { private TableViewer tableViewer; public void createPartControl(Composite parent) { tableViewer=new TableViewer(parent,SWT.H_SCROLL|SWT.V_SCROLL); tableViewer.getTable().setHeaderVisible(true); tableViewer.setContentProvider(ArrayContentProvider.getInstance()); tableViewer.setInput(TimeZone.getAvailableIDs()); } public void setFocus() { tableViewer.getControl().setFocus(); } } )E4: TworzÈc czÚĂÊ aplikacji dla Eclipse 4, trzeba pamiÚtaÊ o dodaniu adnotacji @Inject dla konstruktora i adnotacji @Focus dla metody setFocus(). 4. Uruchom testowÈ wersjÚ Eclipse, a w widoku o nazwie Widok listy stref czasowych pojawi siÚ jednowymiarowa lista wszystkich stref czasowych. 5. Skonwertuj tablicÚ obiektów String na tablicÚ obiektów TimeZone i ustaw jÈ jako dane wejĂciowe. tableViewer.setInput(TimeZone.getAvailableIDs()); String[] ids = TimeZone.getAvailableIDs(); TimeZone[] timeZones = new TimeZone[ids.length]; for(int i=0;i<ids.length;i++) { timeZones[i] = TimeZone.getTimeZone(ids[i]); } tableViewer.setInput(timeZones); getSite().setSelectionProvider(tableViewer); 106 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace 6. Dostawca zaznaczenia zostaï wskazany w ten sam sposób jak w przykïadzie z klasÈ TimeZoneTreeView. Zaznacz element tabeli i sprawdě zawartoĂÊ widoku Properties. 7. Tabela zawiera listÚ obiektów ZoneInfo. Wynika to z faktu, iĝ brakuje obiektu LabelProvider, wiÚc do wyĂwietlania elementów widok uĝywa wartoĂci zwróconej przez toString(). Poniewaĝ tabela ma wiele kolumn, obiekt TableViewer wykorzystuje wiele instancji TableViewerColumn. Kaĝda z nich reprezentuje kolumnÚ tabeli i posiada wïasny rozmiar, tytuï i dostawcÚ opisów. Tworzenie nowej kolumny oznacza najczÚĂciej ustalenie standardowego wyglÈdu (na przykïad szerokoĂci) i wskazanie danych do wyĂwietlenia. By uïatwiÊ wielokrotne uĝycie kodu, utwórz abstrakcyjnÈ podklasÚ ColumnLabelProvider o nazwie TimeZoneColumn (w pakiecie com.packtpub.e4.clock.ui.internal) z abstrakcyjnymi metodami getText() i getTitle() oraz konkretnÈ metodÈ getWidth(). public abstract class TimeZoneColumn extends ColumnLabelProvider { public abstract String getText(Object element); public abstract String getTitle(); public int getWidth() { return 250; } } 8. Dodaj do klasy TimeZoneColumn metodÚ pomocniczÈ, która uïatwi doïÈczanie klasy do widoku. public TableViewerColumn addColumnTo(TableViewer viewer) { TableViewerColumn tableViewerColumn = new TableViewerColumn(viewer,SWT.NONE); TableColumn column = tableViewerColumn.getColumn(); column.setMoveable(true); column.setResizable(true); column.setText(getTitle()); column.setWidth(getWidth()); tableViewerColumn.setLabelProvider(this); return tableViewerColumn; } 9. Utwórz w tym samym pakiecie podklasÚ TimeZoneIDColumn rozszerzajÈcÈ TimeZoneColumn i zwracajÈcÈ kolumnÚ identyfikatora. public class TimeZoneIDColumn extends TimeZoneColumn { public String getText(Object element) { if (element instanceof TimeZone) { 107 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach return ((TimeZone) element).getID(); } else { return ""; } } public String getTitle() { return "ID"; } } 10. Zmodyfikuj klasÚ TimeZoneTableView — na koñcu metody createPartControl() utwórz obiekt kolumny i wywoïaj metodÚ addColumnTo() przed uĝyciem metody setInput(). new TimeZoneIDColumn().addColumnTo(tableViewer); tableViewer.setInput(timeZones); PamiÚtaj, ĝe kolumny trzeba utworzyÊ przed wywoïaniem metody setInput(). W przeciwnym razie nie wyĂwietlÈ siÚ poprawnie. 11. Uruchom testowÈ wersjÚ Eclipse i otwórz Widok tabeli stref czasowych. Kolumna ID powinna byÊ jedynÈ wyĂwietlanÈ kolumnÈ. 12. Aby dodaÊ kolejne kolumny, skopiuj klasÚ TimeZoneIDColumn, a nastÚpnie zmieñ tytuï i zwracanÈ wïaĂciwoĂÊ obiektu TimeZone. Przykïadowo utwórz kopiÚ TimeZoneIDColumn o nazwie TimeZoneDisplayNameColumn. Zmodyfikuj tytuï i pobieranÈ metodÚ get. return return return return ((TimeZone) element).getID(); ((TimeZone) element).getDisplayName(); "ID"; "WyĂwietlana nazwa"; 13. Opcjonalnie wykonaj te same zadania dla innych wïaĂciwoĂci TimeZone, na przykïad przesuniÚcia czasu (metoda getOffset()) lub uĝycia czasu letniego (useDaylightTime()). Kolumny moĝna nastÚpnie dodaÊ do tabeli. new TimeZoneOffsetColumn().addColumnTo(tableViewer); new TimeZoneDisplayNameColumn().addColumnTo(tableViewer); new TimeZoneSummerTimeColumn().addColumnTo(tableViewer); 14. Uruchom instancjÚ Eclipse i przejdě do widoku, by zobaczyÊ dodatkowe kolumny. 108 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace Co siÚ staïo? UtworzyliĂmy obiekt TableViewer, a nastÚpnie dodaliĂmy do niego wiele obiektów ColumnLabelProvider, by wyĂwietliÊ poszczególne kolumny. Tworzenie podklas ColumnLabelProvider zapobiega uciekaniu siÚ do anonimowych klas wewnÚtrznych i uïatwia wykonanie metody pomocniczej. Podklasy uïatwiajÈ tworzenie i podpinanie kolumn (o okreĂlonym tytule i szerokoĂci) przy jednoczesnym pamiÚtaniu konkretnych podklas, takich jak TimeZoneIDColumn. W ten sposób unika siÚ Ăledzenia kolumn za pomocÈ identyfikatorów. By dostosowaÊ kolumny do wïasnych potrzeb, uĝywamy klasy Column z SWT, wïÈczajÈc takie wïaĂciwoĂci jak przesuwanie kolumn (setMovable(true)) lub zmianÚ ich rozmiaru (setResizable(true)). Dopuszczalne sÈ równieĝ operacje zwiÈzane z tabelÈ (klasa Table z SWT), takie jak wyĂwietlenie nagïówka (setHeaderVisible(true)). Warto pamiÚtaÊ, ĝe kolumny widoku tabeli sÈ obliczane w momencie wywoïania metody setInput(), wiÚc kolumny dodane po tym wywoïaniu mogÈ nie wyĂwietlaÊ siÚ prawidïowo. Najlepiej wywoïaÊ metodÚ setInput() po zakoñczeniu innych prac zwiÈzanych z tabelÈ. Nic nie stoi na przeszkodzie, by przenieĂÊ do widoku funkcjonalnoĂci zaimplementowane w widoku drzewa. Przykïadowo podpiÚcie logiki wyboru umoĝliwia wyĂwietlanie w widoku Properties wïaĂciwoĂci wybranej strefy czasowej. Kroki do wykonania — synchronizacja wyboru Widoki TimeZoneTableView i TimeZoneTreeView mogÈ przekazywaÊ wybór widokowi Properties. Reakcja na wybór zapewnia poczucie jednolitoĂci, choÊ widoki sÈ niezaleĝnymi bytami. Moĝliwe jest dodatkowe powiÈzanie widoków, by strefa czasowa (TimeZone) wybrana w jednym z nich automatycznie zostaïa podĂwietlona w drugim. W tym celu trzeba dodaÊ nasïuchiwanie zdarzenia wyboru i jeĂli wybrany zostanie obiekt TimeZone, wyĂwietliÊ go w widoku (przy uĝyciu metod reveal() i setSelection()). 1. Utwórz w pakiecie com.packtpub.e4.clock.ui.internal klasÚ TimeZoneSelectionListener implementujÈcÈ interfejs ISelectionListener. Konstruktor przyjmie widok i obiekt czÚĂci IDE. Trzeba teĝ dodaÊ metodÚ selectionChanged(). public class TimeZoneSelectionListener implements ISelectionListener { private Viewer viewer; private IWorkbenchPart part; public TimeZoneSelectionListener(Viewer v, IWorkbenchPart p) { this.viewer = v; this.part = p; } public void selectionChanged(IWorkbenchPart p, ISelection sel) { } } 109 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach 2. Metoda selectionChanged() wykonuje kilka zadañ. Oto one. Q Q Q Ignorowanie zdarzenia, jeĂli zostaïo wysïane przez tÚ samÈ czÚĂÊ IDE. Pobranie zaznaczonego obiektu ze zdarzenia i porównanie go z aktualnym zaznaczeniem. Uaktualnienie widoku, jeĂli obiekty sÈ róĝne i zaznaczonym obiektem jest TimeZone. 3. Implementacja ma nastÚpujÈcÈ postaÊ. public void selectionChanged(IWorkbenchPart p, ISelection sel) { if (p != this.part) { IStructuredSelection selected = ((IStructuredSelection)sel). ´getFirstElement(); Object current = ((IStructuredSelection)viewer.getSelection()). ´getFirstElement(); if(selected != current && selected instanceof TimeZone) { viewer.setSelection(sel); if(viewer instanceof StructuredViewer) { ((StructuredViewer) viewer).reveal(selected); } } } } 4. Obiekt nasïuchiwania wyboru trzeba zarejestrowaÊ w widokach. Otwórz klasÚ TimeZoneTableView i na dole metody createPartControl() dodaj nastÚpujÈcy kod. selectionListener = new TimeZoneSelectionListener(tableViewer, ´getSite().getPart()); getSite().getWorkbenchWindow().getSelectionService().addSelectionListener ´(selectionListener); 5. Obiekt selectionListener trzeba dodaÊ jako pole, poniewaĝ niezbÚdne jest jego usuniÚcie z listy procedur nasïuchiwania w momencie usuwania widoku. private TimeZoneSelectionListener selectionListener; public void dispose() { if (selectionListener != null) { getSite().getWorkbenchWindow().getSelectionService() .removeSelectionListener(selectionListener); selectionListener = null; } super.dispose(); } 6. Bardzo podobnÈ zmianÚ (inna jest tylko nazwa zmiennej widoku) wykonaj w klasie TimeZoneTreeView. selectionListener = new TimeZoneSelectionListener(treeViewer, ´getSite().getPart()); getSite().getWorkbenchWindow().getSelectionService().addSelectionListener ´(selectionListener); 110 Kup książkę Poleć książkę Rozdziaá 3. • Tworzenie widoków w JFace 7. Metoda dispose() w klasie TimeZoneTreeView powinna byÊ taka sama jak w klasie TimeZoneTableView. 8. Uruchom instancjÚ Eclipse, wybierz strefÚ czasowÈ w widoku o nazwie Widok tabeli stref czasowych, a w widoku nazywanym Widok drzewa stref czasowych pojawi siÚ ten sam wybór. Tym razem zmieñ zaznaczenie w widoku o nazwie Widok drzewa stref czasowych, by zobaczyÊ, czy w widoku nazwanym Widok tabeli stref czasowych pojawi siÚ ten sam wpis. Co siÚ staïo? Zdarzenia wyboru sÈ w Eclipse zgïaszane bardzo czÚsto, wiÚc warto zatroszczyÊ siÚ, by kod nasïuchiwania wyboru dziaïaï wydajnie. FiltrujÈc zdarzenia pochodzÈce z tej samej czÚĂci lub nieistotne typy, uzyskujemy wiÚkszÈ wydajnoĂÊ. W przedstawionym kodzie sprawdzamy, czy zaznaczenie skïada siÚ z przynajmniej jednego elementu typu TimeZone, zanim poprosimy o aktualizacjÚ UI. Wybór widoku moĝna zsynchronizowaÊ z wywoïaniem setSelection(). W ten sposób oszczÚdzamy na nowym obiekcie zaznaczenia i ustawiamy dane we wïaĂciwy sposób. Samo ustawienie wyboru nie wystarcza — wywoïanie metody reveal() jest niezbÚdne do wïaĂciwego podĂwietlenia zaznaczonego elementu. W sytuacji, gdy zaznaczono wiele elementów, podĂwietli tylko pierwszy z nich. Metoda reveal() dostÚpna jest jedynie dla StructuredViewers, wiÚc trzeba rzutowaÊ obiekt wyboru na IStructuredSelection w przypadku obiektów typu StructuredViewers. Na koñcu rejestrujemy procedury obsïugi zdarzeñ w momencie tworzenia widoku i usuwamy je w momencie niszczenia widoku. W tym celu pobieramy obiekt typu ISelectionService z czÚĂci IDE i wywoïujemy metodÚ addSelectionListener(), by dodaÊ procedurÚ obsïugi, lub metodÚ removeSelectionListener(), by jÈ usunÈÊ. )E4: W Eclipse 4 zamiast ISelectionService stosuje siÚ ESelectionService. To podobny, ale nie identyczny interfejs, poniewaĝ nie zapewnia przekazania obiektu WorkbenchPart. NajczÚĂciej ESelectionService wstrzykuje siÚ do widoku, a procedura obsïugi jest dodawana w @PostConstruct i usuwana w @PreDestroy. Quiz — dziaïanie tabel P1. W jaki sposób wïÈczyÊ obsïugÚ kolumn w TableViewer? P2. Do czego sïuĝy TableViewerColumn? P3. W jaki sposób synchronizowaÊ wybór elementu miÚdzy dwoma widokami? 111 Kup książkę Poleć książkę Eclipse 4. Programowanie wtyczek na przykáadach Podsumowanie W tym rozdziale opisaliĂmy uĝycie JFace do tworzenia widoków dla ustrukturyzowanych danych. PrzedstawiliĂmy zarówno widoki bazujÈce na drzewach (klasa TreeViewer), jak i widoki bazujÈce na tabelach (klasa TableViewer). PrzedstawiliĂmy równieĝ kilka wbudowanych w JFace funkcjonalnoĂci zwiÈzanych z czcionkami i obrazami. By synchronizowaÊ dane miÚdzy widokami Eclipse, uĝyliĂmy obiektów ISelectionService (w Eclipse 4 uĝywa siÚ obiektów ESelectionService). Umoĝliwienie widokom zgïaszania i odbierania zdarzeñ wyboru zapewnia wizualnÈ spójnoĂÊ IDE nawet wtedy, kiedy widoki znajdujÈ siÚ w róĝnych wtyczkach. 112 Kup książkę Poleć książkę Skorowidz A adnotacja @PostConstruct, 157 @PreDestroy, 157 @Test, 253 JUnit @BeforeClass, 260 akcje, 113–116 aktualizacja kodu w debuggerze, 34–35 aplikacja Eclipse, 241 a produkt Eclipse, 248 archiwa, 282 arkusz stylów, 194 automatyczne testy wtyczek, 251–265 B budowanie funkcjonalnoĂci za pomocÈ Tycho, 275–276 inkrementacyjne, 172 peïne, 172 produktu za pomocÈ Tycho, 278–282 witryny aktualizacji za pomocÈ Tycho, 276–278 wtyczki za pomocÈ Tycho, 270–273 C charakter projektu, 175–178 czÚĂci, 190, 193 Kup książkę D dane tabelaryczne w JFace, 105–111 debugowanie wtyczki, 31–35 z filtrami kroków, 35 dodanie elementów do zasobnika w SWT, 71–73 logowania do dziennika zdarzeñ w Eclipse 4, 199–201 menu kontekstowego, 114–115 poleceñ do menu kontekstowego, 124–126 procedury obsïugi podwójnego klikniÚcia w JFace, 98–101 Drop to Frame, 34 E Eclipse 4, informacje ogólne, 183–184 Eclipse Marketplace, 292 Eclipse, informacje ogólne, 21–22 edytor EMF, 186 element Direct MenuItem, 219 locationURI, 117 F FillLayout, 60 filtracja w JFace, 93–97 filtrowanie elementów w widoku w JFace, 95–97 kroków, 31–35 Poleć książkę Skorowidz funkcjonalnoĂci, 228–241 a Tycho, 275–276 eksport, 230–232 instalacja w Eclipse, 232–234 tworzenie, 228–230 tworzenie oznaczeñ, 239–241 zaleĝnoĂci, 237–239 G GridLayout, 60 grupowanie wtyczek, 228–241 grupy i zakïadki w SWT, 76–81 I identyfikator funkcjonalnoĂci, 230 polecenia, 116 IMemento dodanie IMemento do widoku stref czasowych, 156 implementacja budowania inkrementacyjnego, 172 instalacja Maven, 268–269 narzÚdzi Eclipse 4, 184–186 instancja FieldEditor, 146 IPreferenceStore, 144 interakcja z interfejsem uĝytkownika w Eclipse 4, 211–212 z uĝytkownikiem, 113–142 w SWT, 67–70 interaktywnoĂÊ w JFace, 98–105 interfejs EMenuService, 222 ESelectionService, 104, 111 IContextFunction, 207 IEclipseContext, 208 IEclipsePreferences, 154 IMemento, 155, 157 IPreferenceStore, 154 IProjectNature, 175 IPropertySupport, 104 ISelection, 98 IStructuredSelection, 100 IStyledLabelProvider, 91–92 ITreeSelection, 100 MContext, 202 iteracja przez zasoby, 168–170 J jarsigner, 289 JFace a obrazy, 88–91 JFace, informacje ogólne, 83–84 JUnit, 251–254 K kategoryzacja witryny aktualizacji, 234–237 keytool, 289 klasa Canvas, 51 ColorRegistry, 88 ComboFieldEditor, 147 ContributionManager, 114 DialogSettings, 155, 157–158 Display, 55 FontRegistry, 88 ImageRegistry, 88 Job, 127, 129 ustawianie wïaĂciwoĂci, 135–137 LabelProvider, 88 MenuManager, 114 MessageDialogWithToggle, 158 MinimarkNature, 178 MultiStatus, 141 Path, 171 Resource, 62 RowLayout, 59 StatusManager, 140 StatusReporter, 141 SubMonitor, 134 TableTreeViewer, 105 TableViewer, 105 UISynchronize, 211–212 ViewerComparator, 94 ViewerFilter, 95 klawisz M1, 118 klawisze, 118 klucz prywatny, 288–289 publiczny, 288 QualifiedName, 137 306 Kup książkę Poleć książkę Skorowidz konfiguracja Ărodowiska Eclipse SDK, 22–25 uruchomieniowa, 29–31 kontekst, 119–120 w Eclipse 4, 204 kreator tworzenia wtyczek, 25–28 M M1, 220 M2, 220 M3, 220 M4, 220 magazyn kluczy, 289 maszyna wirtualna Hotspot, 35 Matcher, 261 Maven, 267–269 menedĝer tematów w Eclipse 4, 199 ukïadu graficznego, 60 menu, 114–126 metaznaki, 220 metoda addSelectionListener(), 70 asyncExec(), 55 build(), 166 collapseAll(), 97 collapseToLevel(), 97 computeSize(), 57 convert(), 134 createPartControl(), 51 CustomArea(), 99 dispose(), 62, 66 drawArc(), 50 exists(), 171 expandAll(), 97 expandToLevel(), 97 filter(), 95 finalize(), 62 getAdapter(), 104 getChildren(), 88 getData(), 95 getParent(), 88 getPreferenceStore(), 144 hasChildren(), 88 isCancelled(), 131 openError(), 138, 141 paintControl(), 52 redraw(), 54 reveal(), 97 select(), 95 selectionChanged(), 110 setData(), 95 setFocus(), 68 setInput(), 88 setWorkRemaining(), 135 syncExec(), 55 viewByTitle(), 261 metody nasïuchujÈce, 73 modele w Eclipse 4, 201 monitor postÚpu prac, 130 monitory i podmonitory typu null, 133–135 N nazewnictwo projektów wtyczek Eclipse, 26–27 numeracja wersji Maven, 287 O obiekt Action, 115 Color, 63 Composite, 60 Event, 206 IPath, 170 Platform, 122 Status, 141 TrayIcon, 73 obiekty modalne w SWT, 74–76 obliczanie wartoĂci na ĝÈdanie w Eclipse 4, 207–209 obserwacja wyraĝeñ, 43–44 obsïuga usuniÚcia pliku, 172–174 widgetów, 52 obstylowanie interfejsu uĝytkownika za pomocÈ CSS w Eclipse 4, 194–198 okna pïywajÈce, 76 opcja setExpandPreCheckFilters(true), 97 operacje dziaïajÈce w tle, 127–129 P PDE, 22 plik Application.e4xmi, 220 artifacts.jar, 236–237 build.properties, 27 307 Kup książkę Poleć książkę Skorowidz plik content.jar, 236–237 feature.xml, 237 manifestu, 49–50 META-INF/MANIFEST.MF, 27 plugin.properties, 155 plugin.xml, 27, 50 pom.xml, 271–272 pliki wtyczki Eclipse, 27–28 Plug-in Development Environment (PDE), 22 pobranie okna w Eclipse 4, 201–202 podklasa AbstractUIPlugin, 144–145 podpisywanie witryn aktualizacji, 288–292 wtyczek, 290–292 podzadania, 131–133 POJO, 222–224 polecenia, 115–26 w Eclipse 4, 215 powiÈzanie menu z poleceniem i procedurÈ obsïugi w Eclipse 4, 213–215 poleceñ ze skrótami klawiaturowymi, 117–118 preferencja uĝytkownika, 143 dodanie siatki, 149 dodanie sïów kluczowych, 153 lokalizacja strony preferencji, 150–151 tworzenie komunikatów ostrzeĝeñ i bïÚdów, 146–147 utworzenie strony preferencji, 145–146 uĝycie innych edytorów pól, 151–152 wybór elementu z listy, 147–149 zapisywanie i wczytywanie, 144–145 preferencje w Eclipse 4, 209–211 procedury obsïugi, 115–126 produkt a Tycho, 278 produkt Eclipse, 241, 245, 248 przekazywanie parametrów polecenia w Eclipse 4, 215–217 przestrzeñ nazw Eclipse, 26–27 przestrzeñ robocza, 161 przypadki testowe, 251 pseudoselektor, 196 publikowanie witryny aktualizacji na serwerze, 292 punkty rozszerzeñ, 50 punkty wstrzymania dla metod, 37–38 warunkowe, 38–40 wstrzymanie dziaïania po wystÈpieniu wyjÈtku, 40–44 R raportowanie postÚpu prac, 129–130 reakcja na akcje uĝytkownika w SWT, 73–74 rejestr zasobów, 88 rejestracja rodzaju znacznika, 180–181 repozytorium p2, 282 RowLayout, 60 Run, 29–31 Run/Step into Selection, 34 rysowanie wïasnego widoku w SWT, 50–60 S selektor stylów, 194–196 sïowa kluczowe, 153 sortowanie w JFace, 93–97 sprawdzanie anulowania zadania, 131 Step Filtering, 37 Step Into, 34 Step Over, 34 Step Return, 34, 38 styl FLAT, 149 style w dostawcy etykiet w JFace, 91–93 Suspend on caught exceptions, 42 Suspend on uncaught exceptions, 42 SWT a obsïuga wÈtków, 55 SWT, informacje ogólne, 47, 52 SWT.NO_TRIM, 76 SWT.ON_TOP, 76 SWTBot, 254–260 interakcja z interfejsem uĝytkownika, 262–265 korzystanie z widoków, 260–262 synchronizacja wyboru widoku w JFace, 109 systemy budujÈce, 165 szpieg CSS, 185 ¥ Ăledzenie w SWT, 64–65 T testy automatyczne, 283–286 interfejsu graficznego, 254–260 wtyczek, 251–265 308 Kup książkę Poleć książkę Skorowidz tïumaczenie na inne jÚzyki, 155 tworzenie akcji, 113–115 aplikacji bez interfejsu uĝytkownika, 242–245 bezpoĂredniego menu i skrótów klawiszowych w Eclipse 4, 218–220 charakteru projektu, 175–178 czÚĂci w Eclipse 4, 190–193 edytora, 162–164 funkcjonalnoĂci, 228–230 menu kontekstowego i menu widoku w Eclipse 4, 220–222 obiektu TreeViewer w JFace, 84–88 parsera, 164–165 poleceñ i procedur obsïugi, 115–117 produktu Eclipse, 245–249 projektu nadrzÚdnego, 273–275 przykïadowej aplikacji Eclipse 4, 186–190 systemu budujÈcego, 165–168 usïugi w Eclipse 4, 222–223 widgetu wielokrotnego uĝytku w SWT, 56–58 widoków TreeViewer w JFace, 84–93 widoku w SWT, 48–50 wïasnych klas do wstrzykiwania w Eclipse 4, 222–224 wtyczki za pomocÈ kreatora, 25–28 zasobów, 170–171 Tycho, 268 U UIJob, 127 ukïad graficzny widoku w SWT, 58–60 ukrywanie ekranu powitalnego, 258–259 uruchomienie w wÈtku interfejsu uĝytkownika w SWT, 55–56 wtyczki, 28–31 usïuga OSGi, 199 OSGi EventAdmin, 204, 206 uzyskanie zaznaczenia w Eclipse 4, 202–204 W wersjonowanie semantyczne, 287 widgety w SWT, 47–82 widok Variables, 43–44 widoki w SWT, 47–82 wielokrotne uĝycie wyraĝeñ, 123–124 witryna aktualizacji, 292 a Tycho, 276–278 kategoryzacja, 234–237 podpisywanie, 288–292 wïaĂciwoĂci stylów, 197–198 wïÈczanie i wyïÈczanie elementów menu, 121–122 wstrzykiwanie podtypów w Eclipse 4, 223–224 wtyczka zgodnoĂci, 225 wycieki zasobów, 63–67 wyïapywanie wyjÈtków, 40–42 wyraĝenie visibleWhen, 121–122 wyĂwietlanie wïaĂciwoĂci w JFace, 101–105 wywoïanie isDisposed(), 62 Z zadania, 54, 127–138 zakres kontekstu, 119 zarzÈdzanie zasobami w SWT, 61–67 zasobnik systemowy, 71 zasoby, 161–182 zatykanie wycieku, 65–67 zdarzenia w Eclipse 4, 204–207 wyboru, 111 zestawy testów, 251 zgïaszanie bïÚdów, 138–141 zmiana kontekstu, 119–121 numeru wersji, 286–288 zmienna style, 52 zmienne w Workbench Core Expressions, 122 znaczniki, 178–181 znajdowanie wycieku, 63–65 V Variables, 43–44 309 Kup książkę Poleć książkę Skorowidz 310 Kup książkę Poleć książkę