Dekoracje

W module dodatkowym można użyć dekoracji do opisywania obrazów zasobów i innych obiektów wyświetlanych w widokach w środowisku roboczym.  Dekoracje przydają się, gdy utworzony moduł dodatkowy dodaje funkcjonalność do istniejących już typów zasobów.  Wiele standardowych widoków środowiska roboczego obsługuje wyświetlanie dekoracji.  

Na przykład środowisko PDE dodaje dekoracje, które umożliwiają rozróżnienie projektów binarnych od projektów źródłowych.

Widok eksploratora pakietów z dekoracjami PDE

Projekt com.example.helloworld  to jedyny projekt źródłowy wyświetlany w nawigatorze.  Wszystkie pozostałe projekty binarne są oznaczone dekoracją w lewym górnym rogu ikony projektu Java.  Dekoracja ta jest wnoszona przez środowisko PDE przy użyciu punktu rozszerzenia org.eclipse.ui.decorators.

   <extension
         point="org.eclipse.ui.decorators">
    <decorator
            lightweight="true"
            quadrant="TOP_LEFT"
            adaptable="true"
            label="%decorator.label"
            icon="icons/full/ovr16/binary_co.png"
            state="false"
            id="org.eclipse.pde.ui.binaryProjectDecorator">
         <description>
            %decorator.desc
         </description>
         <enablement>
            ...
         </enablement>
    </decorator>
 </extension>

Istnieje kilka różnych sposobów dodawania implementacji dekoracji.  Przedstawiony kod w języku znaczników korzysta z najprostszego z nich, nazywanego dekoracją prostą deklaracyjną.  Po zdefiniowaniu dekoracji prostej deklaracyjnej język znaczników zawiera pełny opis ikony dekoracji, jej położenie oraz warunki włączenia.  Dekoracje deklaracyjne są przydatne, gdy do dekorowania etykiety używane są tylko ikony.  Moduł dodatkowy musi tylko określić kwadrant, w którym dekoracja powinna być nałożona na zwykłą ikonę, oraz ikonę, na którą należy nałożyć dekorację.  Tak jak pokazano to na ilustracji, ikona projektu binarnego środowiska PDE jest nakładana w górnym lewym kwadrancie ikony pakietu.

Gdy oprócz ikony dany moduł dodatkowy ma modyfikować także tekst etykiety lub gdy typ ikony jest określany dynamicznie, można użyć prostej dekoracji niedeklaracyjnej.  W tym przypadku musi być zdefiniowana klasa implementacji, która definiuje interfejs ILightweightLabelDecorator.  Wyznaczona klasa jest odpowiedzialna za dostarczenie w czasie wykonywania przedrostka, przyrostka i nakładanego obrazu, które zostaną zastosowane do etykiety.  Łączenie przedrostka i przyrostka z tekstem etykiety oraz nakładanie obrazu jest obsługiwane przez kod środowiska roboczego w wątku działającym w tle.  Tym samym wszelka praca wykonywana przez dany moduł dodatkowy w jego implementacji interfejsu ILightweightLabelDecorator musi odbywać się w chronionym wątku interfejsu użytkownika.  Więcej szczegółów na ten temat zawiera sekcja Wykonywanie kodu z wątku innego niż wątek interfejsu użytkownika.

  Poniższy kod w języku znaczników przedstawia sposób definiowania dekoracji przez klienta CVS przy użyciu tej techniki:

   <extension
         point="org.eclipse.ui.decorators">
    <decorator
            objectClass="org.eclipse.core.resources.IResource"
            adaptable="true"
            label="%DecoratorStandard.name"
            state="false"
            lightweight= "true"
            quadrant = "BOTTOM_RIGHT"
            class="org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator"
            id="org.eclipse.team.cvs.ui.decorator">
         <description>
            %DecoratorStandard.desc
         </description>
    </decorator>
 </extension>

Dekoracje są kontrolowane przez użytkowników przy użyciu strony preferencji Dekoracje etykiet w środowisku roboczym.  Poszczególne dekoracje można włączać i wyłączać.  Pomimo tego warto zaprojektować własne dekoracje w taki sposób, aby nie nakładały się one ani nie wchodziły w konflikt z istniejącymi dekoracjami pakietu SDK platformy. Gdy wiele modułów dodatkowych wniesie dekoracje proste do tego samego kwadrantu, konflikty są rozwiązywane w sposób niedeterministyczny.  

Moduł dodatkowy może także kompleksowo zarządzać obrazem i etykietą.   W takiej sytuacji atrybutowi lightweight należy nadać wartość false, a atrybut class powinien wskazywać nazwę klasy, która implementuje interfejs ILabelDecorator.  Klasa ta umożliwi dekorowanie oryginalnego obrazu etykiety oraz dodawanie do tekstu własnych adnotacji.  Zapewnia ona większą elastyczność, ponieważ wykracza poza ograniczenie do przedrostków, przyrostków i prostych nakładek w kwadrantach.

Inne atrybuty dekoracji są niezależne od konkretnego stylu implementacji.  Atrybuty label i description pozwalają określić nazwę i opis dekoracji wyświetlane w oknie dialogowym preferencji. Atrybut objectClass określa nazwę klasy, do której ma być stosowana dekoracja.  Atrybut enablement umożliwia opis warunków, po spełnieniu których obiekt powinien być dekorowany.   Flaga adaptable wskazuje, czy obiekt dostosowywany do interfejsu IResource powinien być także dekorowany.  Flaga state decyduje, czy dekoracja jest domyślnie widoczna.

Gdy dekoracje obejmują informacje, które wymagają intensywnych obliczeń lub mogą rozpraszać, można wnieść swoje własne preferencje, które umożliwią użytkownikowi dostosowanie dekoracji po jej włączeniu.  Ta technika jest używana przez klienta CVS.

Strona preferencji dekoracji CVS

 

Cykl aktualizacji dekoracji

Dekorowanie jest inicjowane przez odświeżenie dostawców etykiet korzystających z klasy DecoratorManager do udostępniania dekoracji. Przetwarzanie dekoracji jest wykonywane w tle, dlatego od momentu wystąpienia żądania etykiety do momentu wystąpienia zdarzenia labelProviderChanged upływa pewien czas, w którym są przeprowadzane obliczenia dotyczące dekoracji. W tym czasie dekoracja obiektu klasy Object jest obliczana tylko raz ze względu na wydajność. Jeśli dekoracja zmieni się w tym czasie, możliwe jest rozgłoszenie nieaktualnego wyniku, ponieważ do zakończenia obliczeń kolejne żądania o dekorację są ignorowane.

Dostarczyciele dekoracji powinni unikać sytuacji, w których usiłują zmienić dekorację w czasie, gdy jest ona przetwarzana. Jeśli nie jest to możliwe, po przetworzeniu zdarzenia labelProviderChanged należy po raz kolejny zażądać zmiany dekoracji odpowiedniego elementu.