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: helion@helion.pl
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.
Spis treĂci
Przedmowa
15
Rozdziaï 1. Tworzenie pierwszej wtyczki
21
Przygotowanie Ărodowiska
21
Kroki do wykonania — konfiguracja Ărodowiska Eclipse SDK
22
Tworzenie pierwszej wtyczki
25
Kroki do wykonania — tworzenie wtyczki
25
Quiz — przestrzenie nazw i wtyczki Eclipse
28
Uruchomienie wtyczki
28
Kroki do wykonania — uruchomienie Eclipse z poziomu Eclipse
28
Quiz — uruchamianie Eclipse
31
Sprawdě siÚ — modyfikacja wtyczki
31
Debugowanie wtyczki
31
Kroki do wykonania — debugowanie wtyczki
31
Kroki do wykonania — aktualizacja kodu w debuggerze
34
Debugowanie z filtrami kroków
35
Kroki do wykonania — ustawienie filtru kroków
35
Korzystanie z róĝnych rodzajów punktów wstrzymania
37
Kroki do wykonania — wstrzymanie przy wejĂciu do metody lub wyjĂciu z niej
37
Warunkowe punkty wstrzymania
38
Kroki do wykonania — ustawienie warunkowego punktu wstrzymania
39
Wstrzymanie dziaïania po wystÈpieniu wyjÈtku
40
Kroki do wykonania — wyïapywanie wyjÈtków
40
Kroki do wykonania — obserwacja zmiennych i wyraĝeñ
43
Quiz — debugowanie
45
Sprawdě siÚ — korzystanie z punktów wstrzymania
45
Podsumowanie
46
Rozdziaï 2. Tworzenie widoków w SWT
47
Tworzenie widoków i widgetów
48
Kroki do wykonania — tworzenie widoku
48
Kroki do wykonania — rysowanie wïasnego widoku
50
Kroki do wykonania — rysowanie wskazówki sekund
53
Spis
treĞci
4
Kroki do wykonania — animacja wskazówki sekund
54
Kroki do wykonania — uruchomienie w wÈtku interfejsu uĝytkownika
55
Kroki do wykonania — tworzenie widgetu wielokrotnego uĝytku
56
Kroki do wykonania — korzystanie z ukïadu graficznego widoku
58
Quiz — dziaïanie widoków
61
Sprawdě siÚ — wskazówki minut i godzin
61
ZarzÈdzanie zasobami
61
Kroki do wykonania — wiÚcej kolorów
62
Kroki do wykonania — znajdowanie wycieku
63
Kroki do wykonania — zatykanie wycieku
65
Quiz — dziaïanie zasobów
67
Sprawdě siÚ — rozbudowa widgetu zegara
67
Interakcja z uĝytkownikiem
67
Kroki do wykonania — uzyskiwanie aktywnoĂci
67
Kroki do wykonania — reakcja na dziaïania uĝytkownika
69
Quiz — dziaïanie widgetów
70
Sprawdě siÚ — aktualizacja widgetu zegara
70
Korzystanie z innych widgetów SWT
71
Kroki do wykonania — dodanie elementów do zasobnika
71
Kroki do wykonania — reakcja na akcje uĝytkownika
73
Kroki do wykonania — obiekty modalne i inne efekty
74
Kroki do wykonania — grupy i zakïadki
76
Quiz — korzystanie z SWT
82
Sprawdě siÚ — rozbudowa widoku stref czasowych
82
Podsumowanie
82
Rozdziaï 3. Tworzenie widoków w JFace
83
Dlaczego JFace?
83
Tworzenie widoków TreeViewer
84
Kroki do wykonania — tworzenie obiektu TreeViewer
84
Kroki do wykonania — JFace i obrazy
88
Kroki do wykonania — style w dostawcy etykiet
91
Quiz — podstawy JFace
93
Sprawdě siÚ — dodanie obrazów dla regionów
93
Sortowanie i filtracja
93
Kroki do wykonania — sortowanie elementów w widoku
94
Kroki do wykonania — filtrowanie elementów w widoku
95
Quiz — sortowanie i filtracja
97
Sprawdě siÚ — rozwijanie gaïÚzi i filtracja
97
Interakcje i wïaĂciwoĂci
98
Kroki do wykonania — dodanie procedury obsïugi podwójnego klikniÚcia
98
Kroki do wykonania — wyĂwietlanie wïaĂciwoĂci
101
Quiz — dziaïanie wïaĂciwoĂci
105
Dane tabelaryczne
105
Kroki do wykonania — przeglÈdanie stref czasowych w tabeli
105
Kroki do wykonania — synchronizacja wyboru
109
Quiz — dziaïanie tabel
111
Podsumowanie
112
Spis treĞci
5
Rozdziaï 4. Interakcja z uĝytkownikiem
113
Tworzenie akcji, poleceñ i procedur obsïugi
113
Kroki do wykonania — dodanie menu kontekstowego
114
Kroki do wykonania — tworzenie poleceñ i procedur obsïugi
115
Kroki do wykonania — powiÈzanie poleceñ ze skrótami
117
Kroki do wykonania — zmiana kontekstu
119
Kroki do wykonania — wïÈczanie i wyïÈczanie elementów menu
121
Kroki do wykonania — wielokrotne uĝycie wyraĝeñ
123
Kroki do wykonania — dodanie poleceñ do menu kontekstowego
124
Sprawdě siÚ — wykorzystanie menu i pasków narzÚdziowych
126
Quiz — dziaïanie menu
127
Zadania i paski postÚpu
127
Kroki do wykonania — uruchamianie operacji dziaïajÈcych w tle
127
Sprawdě siÚ — uĝycie zadania UIJob
129
Kroki do wykonania — raportowanie postÚpu prac
129
Kroki do wykonania — sprawdzanie anulowania zadania
131
Kroki do wykonania — podzadania i ich monitorowanie
131
Kroki do wykonania — uĝycie monitorów i podmonitorów typu null
133
Kroki do wykonania — ustawienie wïaĂciwoĂci klasy Job
135
Sprawdě siÚ — wyĂwietlanie zadania w pasku systemowym
138
Quiz — korzystanie z zadañ
138
Zgïaszanie bïÚdów
138
Kroki do wykonania — wyĂwietlanie bïÚdów
138
Quiz — zgïaszanie bïÚdów
141
Podsumowanie
142
Rozdziaï 5. Przechowywanie preferencji i ustawieñ
143
Przechowywanie preferencji
143
Kroki do wykonania — trwaïoĂÊ wartoĂci
144
Kroki do wykonania — utworzenie strony preferencji
145
Kroki do wykonania — tworzenie komunikatów ostrzeĝeñ i bïÚdów
146
Kroki do wykonania — wybór elementu z listy
147
Kroki do wykonania — dodanie siatki
149
Kroki do wykonania — lokalizacja strony preferencji
150
Kroki do wykonania — uĝycie innych edytorów pól
151
Kroki do wykonania — dodanie sïów kluczowych
153
Kroki do wykonania — uĝycie IEclipsePreferences
154
Sprawdě siÚ — tïumaczenie na inne jÚzyki
155
Uĝycie IMemento i DialogSettings
155
Kroki do wykonania — dodanie IMemento do widoku stref czasowych
156
Kroki do wykonania — uĝycie DialogSettings
157
Quiz — dziaïanie preferencji
159
Podsumowanie
159
Spis
treĞci
6
Rozdziaï 6. Korzystanie z zasobów
161
Korzystanie z przestrzeni roboczych i zasobów
161
Kroki do wykonania — tworzenie edytora
162
Kroki do wykonania — tworzenie parsera
164
Kroki do wykonania — tworzenie systemu budujÈcego
165
Kroki do wykonania — iteracja przez zasoby
168
Kroki do wykonania — tworzenie zasobów
170
Kroki do wykonania — implementacja budowania inkrementacyjnego
172
Kroki do wykonania — obsïuga usuniÚcia
172
Sprawdě siÚ — rozbudowa mechanizmu budowania
174
Uĝycie charakterów projektu
175
Kroki do wykonania — tworzenie charakteru projektu
175
Sprawdě siÚ — ukrywanie charakteru
178
Uĝycie znaczników
178
Kroki do wykonania — znacznik bïÚdu, gdy plik jest pusty
179
Kroki do wykonania — rejestracja rodzaju znacznika
180
Sprawdě siÚ — prawidïowe dziaïanie, gdy plik jest naprawdÚ pusty
181
Quiz — obsïuga zasobów, procesu budowania i znaczników
182
Podsumowanie
182
Rozdziaï 7. Model Eclipse 4
183
Korzystanie z modelu Eclipse 4
183
Kroki do wykonania — instalacja narzÚdzi Eclipse 4
184
Kroki do wykonania — tworzenie aplikacji Eclipse 4
186
Kroki do wykonania — tworzenie czÚĂci
190
Kroki do wykonania — obstylowanie interfejsu uĝytkownika za pomocÈ CSS
194
Sprawdě siÚ — uĝycie menedĝera tematów
199
Usïugi i konteksty
199
Kroki do wykonania — dodanie logowania do dziennika zdarzeñ
199
Kroki do wykonania — pobranie okna
201
Kroki do wykonania — uzyskanie zaznaczenia
202
Kroki do wykonania — korzystanie ze zdarzeñ
204
Kroki do wykonania — obliczanie wartoĂci na ĝÈdanie
207
Kroki do wykonania — uĝycie preferencji
209
Kroki do wykonania — interakcja z interfejsem uĝytkownika
211
Korzystanie z poleceñ, procedur obsïugi i elementów menu
213
Kroki do wykonania — powiÈzanie menu z poleceniem i procedurÈ obsïugi
213
Kroki do wykonania — przekazywanie parametrów polecenia
215
Kroki do wykonania — utworzenie bezpoĂredniego menu i skrótów klawiszowych
218
Kroki do wykonania — utworzenie menu kontekstowego i menu widoku
220
Tworzenie wïasnych klas do wstrzykiwania
222
Kroki do wykonania — tworzenie prostej usïugi
222
Kroki do wykonania — wstrzykiwanie podtypów
223
Sprawdě siÚ — uĝycie mostka narzÚdziowego
224
Quiz — dziaïanie Eclipse 4
224
Podsumowanie
225
Spis treĞci
7
Rozdziaï 8. Tworzenie funkcjonalnoĂci, witryn aktualizacji, aplikacji i produktów
227
Grupowanie wtyczek jako funkcjonalnoĂci
228
Kroki do wykonania — tworzenie funkcjonalnoĂci
228
Kroki do wykonania — eksport funkcjonalnoĂci
230
Kroki do wykonania — instalacja funkcjonalnoĂci
232
Kroki do wykonania — kategoryzacja witryny aktualizacji
234
Kroki do wykonania — zaleĝnoĂÊ od innych funkcjonalnoĂci
237
Kroki do wykonania — tworzenie oznaczeñ funkcjonalnoĂci
239
Sprawdě siÚ — zdalna publikacja zawartoĂci
241
Budowanie aplikacji i produktów
241
Kroki do wykonania — wykonanie aplikacji bez interfejsu uĝytkownika
242
Kroki do wykonania — tworzenie produktu
245
Sprawdě siÚ — tworzenie produktu bazujÈcego na funkcjonalnoĂci
249
Quiz — sposób dziaïania funkcjonalnoĂci, aplikacji i produktów
249
Podsumowanie
249
Rozdziaï 9. Automatyczne testy wtyczek
251
Uĝycie frameworku JUnit do testów zautomatyzowanych
251
Kroki do wykonania — wykonanie prostego przypadku testowego JUnit
252
Kroki do wykonania — wykonanie testu wtyczki
253
Wykorzystanie SWTBot do testów interfejsu graficznego
254
Kroki do wykonania — tworzenie testów SWTBot
254
Kroki do wykonania — korzystanie z menu
256
Sprawdě siÚ — korzystanie z zasobów
258
Korzystanie z SWTBot
258
Kroki do wykonania — ukrywanie ekranu powitalnego
258
Kroki do wykonania — unikanie bïÚdów wykonania z SWTBot
259
Korzystanie z widoków
260
Kroki do wykonania — wyĂwietlenie widoków
260
Kroki do wykonania — przesïuchiwanie widoków
261
Interakcja z interfejsem uĝytkownika
262
Kroki do wykonania — pobranie wartoĂci z interfejsu uĝytkownika
262
Kroki do wykonania — oczekiwanie na warunek
263
Sprawdě siÚ — sterowanie kreatorem nowej klasy
265
Quiz — dziaïanie SWTBot
265
Podsumowanie
265
Rozdziaï 10. Automatyczne budowanie przy uĝyciu Tycho
267
Wykorzystanie Maven i Tycho do budowania wtyczek Eclipse
267
Kroki do wykonania — instalacja Maven
268
Kroki do wykonania — budowanie za pomocÈ Tycho
270
Sprawdě siÚ — korzystanie z platform docelowych
272
Budowanie funkcjonalnoĂci i witryn aktualizacji za pomocÈ Tycho
273
Kroki do wykonania — tworzenie projektu nadrzÚdnego
273
Kroki do wykonania — budowanie funkcjonalnoĂci
275
Kroki do wykonania — budowanie witryny aktualizacji
276
Spis
treĞci
8
Kroki do wykonania — budowanie produktu
278
Sprawdě siÚ — zaleĝnoĂÊ od komponentów Maven
282
Testy i publikacja
283
Kroki do wykonania — uruchomienie testów automatycznych
283
Kroki do wykonania — zmiana numeru wersji
286
Sprawdě siÚ — wïÈczenie budowania dla pozostaïych wtyczek
288
Podpisywanie witryn aktualizacji
288
Kroki do wykonania — tworzenie certyfikatu podpisanego przez samego siebie
288
Kroki do wykonania — podpisywanie wtyczek
290
Kroki do wykonania — serwer z witrynÈ aktualizacji
292
Quiz — automatyczne budowanie i witryny aktualizacji
293
Podsumowanie
293
Dodatek A Odpowiedzi do quizów
295
Rozdziaï 1. Tworzenie pierwszej wtyczki
295
Rozdziaï 2. Tworzenie widoków w SWT
296
Rozdziaï 3. Tworzenie widoków w JFace
298
Rozdziaï 4. Interakcja z uĝytkownikiem
299
Rozdziaï 5. Przechowywanie preferencji i ustawieñ
300
Rozdziaï 6. Korzystanie z zasobów
301
Rozdziaï 7. Model Eclipse 4
301
Rozdziaï 8. Tworzenie funkcjonalnoĂci, witryn aktualizacji, aplikacji i produktów
303
Rozdziaï 9. Automatyczne testy wtyczek
303
Rozdziaï 10. Automatyczne budowanie przy uĝyciu Tycho
304
Skorowidz
305
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Úp-
nia 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.
Eclipse 4. Programowanie wtyczek na przykáadach
84
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
Detailed-
ProgressViewer
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
utwo-
rzymy 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>
Rozdziaá 3. • Tworzenie widoków w JFace
85
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";
Eclipse 4. Programowanie wtyczek na przykáadach
86
} else if (element instanceof Map.Entry) {
return ((Map.Entry) element).getKey().toString();
} else if (element instanceof TimeZone) {
return ((TimeZone) element).getID().split("/")[1];
} else {
return "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();
Rozdziaá 3. • Tworzenie widoków w JFace
87
} else if (parentElement instanceof Map.Entry) {
return getChildren(((Map.Entry)parentElement).getValue());
} else if (parentElement instanceof Collection) {
return ((Collection) parentElement).toArray();
} else {
return 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.
Eclipse 4. Programowanie wtyczek na przykáadach
88
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Ú rozwi-
niÚ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 prze-
szkodzie, 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ïu-
gujÈ klasy
ImageRegistry
,
FontRegistry
i
ColorRegistry
. Rejestr zasobów ma za zadanie prze-
chowywaÊ 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 de-
skryptora 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.
Rozdziaá 3. • Tworzenie widoków w JFace
89
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));
Eclipse 4. Programowanie wtyczek na przykáadach
90
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
. Predefi-
niowane 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.
Rozdziaá 3. • Tworzenie widoków w JFace
91
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 po-
wiÈ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 przypad-
ku plikiem icons/sample.gif pochodzÈcym z kreatora wtyczek. Ten sam klucz sïuĝy do inicja-
lizacji 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 ze-
spoïó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.
Eclipse 4. Programowanie wtyczek na przykáadach
92
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 zdefi-
niowaÊ przy uĝyciu wywoïania
StyledString.createColorRegistryStyler("czcionka", "tïo")
,
gdzie oba teksty to klucze w globalnym obiekcie
ColorRegistry
z JFace.
Rozdziaá 3. • Tworzenie widoków w JFace
93
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 zaso-
bó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 pro-
gramistyczny 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.
Eclipse 4. Programowanie wtyczek na przykáadach
94
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 spo-
sobu 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 prze-
prowadzi 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.
Rozdziaá 3. • Tworzenie widoków w JFace
95
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 da-
nych w konkretnym widoku. OczywiĂcie, najczÚĂciej bÚdzie to powiÈzane z wyborem odpo-
wiedniej 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 wi-
doku. DziÚki temu moĝna uĝyÊ ogólnego komparatora w wielu róĝnych widokach przy jedno-
czesnym 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ïy-
wajÈ na sortowanie lub filtracjÚ, wywoïaj metodÚ
refresh()
widoku, by zaktualizowaÊ wyĂwie-
tlane 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 wyszu-
kiwania 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 fil-
tracji caïej tablicy; metoda
select()
uĝywana jest do okreĂlenia, czy naleĝy wyĂwietliÊ kon-
kretny element, czy teĝ go pominÈÊ).
Eclipse 4. Programowanie wtyczek na przykáadach
96
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.
Rozdziaá 3. • Tworzenie widoków w JFace
97
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 po-
ziomu ikon typu [+] i [-] umieszczonych w lokalnym pasku narzÚdziowym widoku (patrz wi-
doki 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()
.
Eclipse 4. Programowanie wtyczek na przykáadach
98
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Ê ele-
mentami 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 klik-
niÚ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.
Rozdziaá 3. • Tworzenie widoków w JFace
99
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();
}
Eclipse 4. Programowanie wtyczek na przykáadach
100
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È meto-
dy
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 ele-
mentach 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 rzu-
tuje otrzymany obiekt na interfejs
IStructuredSelection
i wywoïuje metodÚ
getFirstElement()
,
by pobraÊ pojedynczÈ wartoĂÊ zaznaczenia.
Rozdziaá 3. • Tworzenie widoków w JFace
101
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È od-
krywane 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 za-
implementowaï 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
.
Eclipse 4. Programowanie wtyczek na przykáadach
102
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>
Rozdziaá 3. • Tworzenie widoków w JFace
103
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);
Eclipse 4. Programowanie wtyczek na przykáadach
104
}@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 kon-
wersjÚ przekazanego obiektu na obiekt poĝÈdanego typu. JeĂli obiekt jest juĝ instancjÈ doce-
lowego 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 zapew-
nienia 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 do-
wolnego 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
Rozdziaá 3. • Tworzenie widoków w JFace
105
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"
Eclipse 4. Programowanie wtyczek na przykáadach
106
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 kon-
struktora 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);
Rozdziaá 3. • Tworzenie widoków w JFace
107
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) {
Eclipse 4. Programowanie wtyczek na przykáadach
108
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 ((TimeZone) element).getID();
return ((TimeZone) element).getDisplayName();
return "ID";
return "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.
Rozdziaá 3. • Tworzenie widoków w JFace
109
Co siÚ staïo?
UtworzyliĂmy obiekt
TableViewer
, a nastÚpnie dodaliĂmy do niego wiele obiektów
ColumnLa-
belProvider
, 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 szero-
koĂ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) {
}
}
Eclipse 4. Programowanie wtyczek na przykáadach
110
2. Metoda
selectionChanged()
wykonuje kilka zadañ. Oto one.
Q
Ignorowanie zdarzenia, jeĂli zostaïo wysïane przez tÚ samÈ czÚĂÊ IDE.
Q
Pobranie zaznaczonego obiektu ze zdarzenia i porównanie go z aktualnym
zaznaczeniem.
Q
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);
Rozdziaá 3. • Tworzenie widoków w JFace
111
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ïu-
chiwania 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Ăwie-
tlenia 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?
Eclipse 4. Programowanie wtyczek na przykáadach
112
Podsumowanie
W tym rozdziale opisaliĂmy uĝycie JFace do tworzenia widoków dla ustrukturyzowanych da-
nych. 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 od-
bierania zdarzeñ wyboru zapewnia wizualnÈ spójnoĂÊ IDE nawet wtedy, kiedy widoki znaj-
dujÈ siÚ w róĝnych wtyczkach.
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
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
Skorowidz
306
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
Skorowidz
307
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
Skorowidz
308
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
Skorowidz
309
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
V
Variables, 43–44
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