Asystent treści pól

Użytkownik często powinien wprowadzić informacje tekstowe w prostym polu, takim jak pole tekstowe lub okno złożone. Chociaż kod aplikacji, która wymaga wypełnienia takich pól, jest zazwyczaj znacznie prostszy, niż kod wymagany do wypełnienia złożonych widgetów, takich jak tabele lub drzewa, "proste" pola zazwyczaj wymagają więcej pracy od użytkownika. Użytkownik musi bowiem zorientować się, które pola wymagają treści, czy pole zawiera poprawną treść i jakich wyborów należy dokonać. Obsługa asystenta treści pól JFace udostępnia klasy, które pomagają użytkownikowi we wprowadzaniu danych.

Pakiet org.eclipse.jface.fieldassist udostępnia dwa rodzaje asysty. Obsługa pól udekorowanych umożliwia dołożenie dekoracji w postaci obrazków informujących użytkownika o stanie konkretnego pola. Obsługa propozycji treści pozwala udostępnić element wywoływany asystenta, który zawiera treści do wyboru przez użytkownika.

Pola udekorowane

Pola udekorowane umożliwiają umieszczenie dekoracji w postaci obrazków obok pól zdefiniowanych w oknie zwykłym lub dialogowym. Dekoracje można umieścić przy jednym z czterech rogów pola. Podobnie jak przeglądarki, pola udekorowane mają rozszerzać funkcjonalność elementu sterującego SWT przy jednoczesnym zachowaniu dostępu do pola bazowego. Interfejs API do klasy DecoratedField umożliwia dodawanie, ukrywanie i wyświetlanie dekoracji obok pola. Dostęp do bazowego elementu sterującego zostaje zachowany, aby możliwe było korzystanie z istniejącego interfejsu API SWT do obsługi tego pola, np. ustawianie jego treści, koloru lub czcionki.

Tworzenie pola udekorowanego

Pole udekorowane zachowuje się z zewnętrznego punktu widzenia jak pojedynczy element sterujący. Jednak z wewnętrznego punktu widzenia jest to pole złożone, umożliwiające zarządzanie układem pola oraz jego dekoracjami. W większości przypadków nie ma to znaczenia dla aplikacji klienckiej. Oznacza to jednak, że pole udekorowane musi faktycznie tworzyć element sterujący. Jako przykład niech posłuży ten fragment kodu, w którym aplikacja tworzy tekstowy element sterujący w jednym z okien dialogowych:

...
// Tworzenie pola tekstowego
Text text = new Text(parent, SWT.BORDER);
text.setText("jakiś tekst"); 
...

Aby udekorować to pole, musi zostać ono utworzone w następujący sposób:

...
// Tworzenie pola udekorowanego dla tekstowego elementu sterującego
DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("jakiś tekst");
...

Do utworzenia pola udekorowanego wykorzystywane są te same bity elementu nadrzędnego i stylu, które byłyby używane do utworzenia bazowego elementu sterującego. Podstawowa różnica w kodzie polega jednak na tym, że udostępniona zostaje instancja klasy IControlCreator, która tworzy specyficzny rodzaj elementu sterującego potrzebnego w tym polu. W przypadku pól tekstowych do utworzenia elementu sterującego można użyć klasy TextControlCreator. Można jednak zaimplementować IControlCreator, aby móc tworzyć dowolny inny rodzaj elementu sterującego w polu, na przykład okno złożone lub pole przewijane.

Korzystanie z dekoracji

Po utworzeniu pola udekorowanego można do niego dodać dekoracje w jednym z czterech miejsc. Do określenia miejsca, w którym ma być umieszczona dekoracja, wykorzystywane są stałe położeń SWT. Aby dodać dekorację, należy określić wartość parametru FieldDecoration, który definiuje obrazek stosowany jako dekoracja, a opcjonalnie można wprowadzić tekst opisowy, który będzie wyświetlany, gdy użytkownik najedzie kursorem myszy na dekorację.

...
// Tworzenie dekoracji i dodawanie jej do pola
Image image = JFaceResources.getImage("myplugin.specialimage");
FieldDecoration mySpecialDecoration = new FieldDecoration(image, "To jest specjalne pole");
field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false);
...

Do określenia, czy dekoracja powinna być wyświetlana tylko przy obiektach aktywnych, czy cały czas, służy parametr będący wyrażeniem boolowskim. W tym przypadku dekoracja ma być wyświetlana cały czas. Mogą jednak wystąpić przypadki, gdy dekoracje powinny pozostać ukryte lub wyświetlone. Poniższy fragment kodu ukrywa utworzoną wcześniej dekorację.

...
// Wystąpiła sytuacja, w której dekoracja powinna zostać ukryta
field.hideDecoration(mySpecialDecoration);
...

Jeśli obrazek lub opis dekoracji zostaną zaktualizowane, informacja ta powinna zostać przekazana do pola, aby dekoracja została wyświetlona ponownie.

...
// Wystąpiła sytuacja, w której należy zmienić opis pola
mySpecialDecoration.setDescription("To jest bardzo specjalne pole");
field.updateDecoration(mySpecialDecoration);
...

Układanie pól udekorowanych i nieudekorowanych

Przy układaniu pól udekorowanych w oknie dialogowym lub zwykłym układany powinien być element sterujący układu pola, a nie prosty bazowy element sterujący. Przyjrzyjmy się jeszcze raz fragmentowi kodu do tworzenia tekstowego elementu sterującego. Przy układaniu tekstowego elementu sterującego aplikacja konfiguruje dane układu w elemencie sterującym.

...
// Tworzenie pola tekstowego
Text text = new Text(parent, SWT.BORDER);
text.setText("jakiś tekst");
// Ustawienie danych układu
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
text.setLayoutData(data); 
...

Przy układaniu pola udekorowanego aplikacja powinna ustawiać dane układu w elemencie sterującym układu pola. W zależności od oczekiwanego układu może być konieczne dopasowanie rozmiaru pola do wielkości dekoracji.

...
// Tworzenie pola udekorowanego dla tekstowego elementu sterującego
DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("jakiś tekst");
// Ustawienie danych układu
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH + 
   FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT);
field.getLayoutControl().setLayoutData(data); 
...

Obsługa asystenta treści pól nie zakłada ani nie wymaga, aby w danym oknie zwykłym lub dialogowym stosowane były tylko pola udekorowane. Układ okna może jednak stać się bardziej skomplikowany, jeśli pola udekorowane będą mieszane z prostymi elementami sterującymi. Aby wyrównać pola udekorowane i nieudekorowane, należy bowiem wziąć pod uwagę wcięcie powodowane przez szerokość dekoracji. Szerokość dekoracji to po prostu szerokość obrazka. Sytuacja może stać się jednak bardziej skomplikowana, jeśli używane są dekoracje o różnych szerokościach. W takim przypadku można uprościć pracę, rejestrując wszystkie dekoracje w rejestrze FieldDecorationRegistry.

Rejestr dekoracji pól

Rejestr dekoracji pól pozwala zarejestrować dekoracje pól i uzyskać do nich dostęp przy użyciu identyfikatora w postaci łańcucha. Jest to wygodny sposób odwoływania się do dekoracji wykorzystywanych w całej aplikacji. Jeśli dekoracje mają być dostępne w innych wtyczkach, można zdefiniować interfejs API, który udostępnia identyfikatory dekoracji. Należy zauważyć, że zarejestrowanie dekoracji nie obejmuje zarządzania cyklem życia obrazków w dekoracjach. O tym, jak zarządzać tymi obrazkami, może decydować aplikacja. Do rejestrowania cyklu życia obrazków i zarządzania nim może być wykorzystany na przykład rejestr obrazków JFace. Aplikacja może też tworzyć obrazek na żądanie i usuwać go, gdy nie jest już potrzebny. W dokumentacji Javadoc metod rejestracji w rejestrze FieldDecorationRegistry wyjaśniono różne sposoby, które można wykorzystać do określenia obrazków przy rejestrowaniu dekoracji.

Rejestrowanie dekoracji w rejestrze dekoracji pól może też uprościć proces projektowania układu przy jednoczesnym użyciu pól udekorowanych i nieudekorowanych. Domyślnie pole udekorowane pobiera z rejestru dekoracji pól informacje niezbędne do określenia maksymalnej szerokości dekoracji i zapewnienia, że wszystkie dekoracje mają tę samą szerokość. Oznacza to, że wszystkie pola udekorowane będą wyrównywane poprawnie, niezależnie od szerokości poszczególnych dekoracji. Aby wyrównać pola nieudekorowane, można użyć protokołu FieldDecorationRegistry i pobrać szerokość najszerszej dekoracji do utworzenia odpowiedniego wcięcia.

...
// Tworzenie pola tekstowego
Text text = new Text(parent, SWT.BORDER);
text.setText("jakiś tekst");
// Ustawienie danych układu
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
text.setLayoutData(data); 
...

Chociaż obsługa asystenta treści pól nie narzuca sposobu użycia dekoracji, rejestr definiuje także standardowe dekoracje, których można użyć w aplikacji w celu wyświetlenia pewnych stanów pól. Poniższy przykładowy fragment kodu wykorzystuje standardową dekorację dla pól wymaganych:

...
// Tworzenie pola udekorowanego z dekoracją oznaczającą pole wymagane.
DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator());
FieldDecoration requiredFieldIndicator = FieldDecorationRegistry.getDefault().
   getFieldDecoration(FieldDecorationRegistry.DEC_REQUIRED);
field.addDecoratedField(requiredFieldIndicator, SWT.BOTTOM | SWT.LEFT, false);
...

Propozycje treści

Oprócz adnotacji do pól z dekoracjami, aplikacje mogą też udostępniać asystenta propozycji treści, który wywołuje element zawierający propozycje treści pola. Aby udostępnić tę funkcję, można zainstalować adapter ContentProposalAdapter na dowolnym elemencie sterującym. Poniższy fragment kodu powoduje instalację adaptera propozycji treści na tekstowym elemencie sterującym. Należy zauważyć, że to pole tekstowe może być polem utworzonym bezpośrednio przez aplikację lub uzyskanym z pola udekorowanego.

...
autoActivationCharacters = new char[] { '#', '(' };
keyStroke = KeyStroke.getInstance("Ctrl+Space");
// zakładamy, że element sterujący myTextControl został już utworzony
ContentProposalAdapter adapter = new ContentProposalAdapter(
	myTextControl, new TextContentAdapter(), 
	new SimpleContentProposalProvider(new String [] {"PropozycjaPierwsza", "PropozycjaDruga", "PropozycjaTrzecia"}),
	keyStroke, autoActivationCharacters);

Aby uzyskać lub ustawić treść elementu sterującego w chwili wybrania propozycji z elementu wywoływanego, należy zastosować instancję adaptera IControlContentAdapter, który może pobierać i ustawiać treść danego rodzaju elementu sterującego. W przypadku pól tekstowych można użyć klasy TextContentAdapter. Można też zaimplementować IControlContentAdapter tak, aby użyć adaptera propozycji treści z dowolnym innym rodzajem elementu sterującego.

Przy tworzeniu adaptera propozycji treści należy też określić instancję dostawcy IContentProposalProvider, z którego pobierane są propozycje. Dostawca ten zwraca tablicę propozycji treści. Same propozycje są określone jako instancje klasy IContentProposal, z której można pobrać etykietę i treść propozycji, a także inne informacje, takie jak szczegółowy opis propozycji.

W powyższym przykładzie wykorzystany został dostawca SimpleContentProposalProvider. Ten dostawca jest definiowany przez podanie prostej tablicy łańcuchów będących propozycjami treści. Prosty dostawca implementuje protokół niezbędny do odwzorowania każdego łańcucha na oczekiwaną propozycję IContentProposal. Elastyczność dostawcy IContentProposalProvider pozwala zaimplementować dostawcę propozycji z zaawansowanymi cechami. Może on filtrować propozycje w zależności od treści elementu sterującego, wywoływać etykiety objaśniające propozycję zamiast wyświetlania treści propozycji, która zostanie wstawiona, a także określać oczekiwaną pozycję kursora po wstawieniu propozycji. Aby dowiedzieć się, jak korzystać z zaawansowanych cech, patrz Przykład asystenta treści pól i wyszukaj elementy implementujące dostawcę IContentProposalProvider.

Konfigurowanie adaptera propozycji treści

Zostało już wyjaśnione, że podstawowa definicja adaptera propozycji treści zawiera element sterujący, dla którego udostępniane są propozycje, adapter treści używany do zmiany treści elementu sterującego oraz dostawcę propozycji, który określa listę propozycji w elemencie wywoływanym. Oprócz tego istnieje wiele sposobów konfigurowania adaptera propozycji treści:

Przykład asystenta treści pól pozwala skonfigurować podane opcje przy użyciu preferencji przykładowych i spróbować różnych kombinacji. Adapter można na przykład skonfigurować tak, aby był jawnie wywoływany kombinacją klawiszy i wstawiał treść propozycji do elementu sterującego. Będzie wtedy funkcjonował podobnie do asystenta treści w edytorze tekstu. Można go też skonfigurować bez jawnej kombinacji klawiszy, znaków aktywujących i zastępowania treści. Wtedy będzie on funkcjonować podobnie do mechanizmu autouzupełniania wykorzystywanego w przeglądarkach lub polach wyszukiwania. Więcej informacji o każdej z tych metod i ich wzajemnej interakcji zawiera dokumentacja Javadoc.

Asystent treści pól w środowisku roboczym

Obsługa asystenta treści na poziomie JFace powoduje, że aplikacje mogą być tworzone w bardzo elastyczny sposób, przy wykorzystaniu różnych sposobów dekorowania pól i wyświetlania propozycji ich treści. Jest to użyteczne w przypadku autonomicznych aplikacji JFace lub autonomicznych aplikacji pełnego klienta. Jeśli jednak aplikacja ma być zintegrowana z innymi wtyczkami, takimi jak pakiet SDK Eclipse lub wtyczki innych firm, najprawdopodobniej konieczne będzie wykorzystanie asystenta treści pól w sposób spójny z innymi wtyczkami. Środowisko robocze definiuje klasy narzędziowe, które używają asystenta treści pól w konkretnych rodzajach interakcji.

Na przykład klasa ContentAssistField tworzy pole udekorowane przy użyciu obrazka symbolizującego żarówkę, co sugeruje użytkownikowi, że dostępny jest asystent treści. Konfiguruje także adapter propozycji treści tak, że jego obsługa przypomina asystenta treści. Udostępnia też procedurę obsługi komendy asystenta treści na poziomie środowiska roboczego, tak aby element wywoływany z propozycjami treści był otwierany po naciśnięciu takiej samej kombinacji klawiszy, jak ta określona w przypisaniach klawiszy środowiska roboczego. Więcej informacji na temat tych klas narzędziowych zawiera pakiet org.eclipse.ui.fieldassist.

Ten pakiet będzie się rozwijać wraz z rozszerzaniem zakresu użycia asystenta treści w środowisku roboczym i wraz ze standaryzacją dekoracji symbolizujących określone stany pól.