Help bij velden

Vaak wordt van een gebruiker verwacht dat deze tekstinformatie opgeeft in een eenvoudig veld, zoals een tekstveld of een keuzelijst met invoerveld. Hoewel de toepassingscode waarmee deze velden wordt gevuld doorgaans veel eenvoudiger is dan code waarmee een complexe widget zoals een tabel of boomstructuur wordt gevuld, zijn deze "eenvoudige" velden toch vaak lastig voor de gebruiker. De gebruiker moet bepalen welke velden content vereisen, of een veld geldige content bevat en welke selecties worden verwacht. De veldondersteuning van JFace biedt klassen die de gebruiker helpen om deze invoertaken uit te voeren.

Het org.eclipse.jface.fieldassist-pakket biedt op twee manieren ondersteuning. Met de ondersteuning voor gedecoreerde velden kunt u afbeeldingsdecoraties opnemen die de gebruiker aanwijzingen geven over de status van een bepaald veld. Met ondersteuning voor contentsuggestie kunt u een voorgrondvenster met contenthulp bieden dat de gebruiker contentkeuzes biedt.

Gedecoreerde velden

Met gedecoreerde velden kunt u afbeeldingsdecoraties naast velden plaatsen die in een venster of dialoogvenster zijn gedefinieerd. Decoraties kunnen naast een van de vier hoeken van een veld worden geplaatst. Gedecoreerde velden zijn, net zoals viewers, bestemd om functionaliteit aan een softwarebesturing te geven, terwijl nog steeds toegang wordt geboden tot de onderliggende besturing. Met de API voor DecoratedField kunt u decoraties naast een veld toevoegen, verbergen en weergeven. Er wordt toegang geboden tot de onderliggende besturing, zodat u de bestaande SWT-API kunt gebruiken om de onderliggende besturing te bewerken, bijvoorbeeld de content, kleur of het lettertype ervan in te stellen.

Een gedecoreerd veld maken

Van buiten gezien gedraagt een gedecoreerd veld zich als een enkele besturing. Intern maken gedecoreerde velden gebruik van een samengestelde besturing om de opmaak van het veld en de decoraties ervan te beheren. Voor het grootste gedeelte heeft dit geen invloed op de clienttoepassing. Het betekent echter wel dat het gedecoreerde veld het maken van de besturing moet uitvoeren. Bekijk bijvoorbeeld deze snippet, waarin een toepassing een tekstbesturing in een van de dialoogvensters maakt:

...
// Een tekstveld maken
Text text = new Text(parent, SWT.BORDER);
text.setText("tekst");
...

Om dit veld te decoreren, moet het veld op de volgende manier worden gemaakt:

...
// Een gedecoreerd veld maken voor een tekstbesturing
DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("tekst");
...

Dezelfde bovenliggende item- en stijlonderdelen die worden gebruikt om de basisbesturing te maken, worden ook gebruikt om een gedecoreerd veld te maken. Het primaire verschil in de code is dat in een instance van IControlCreator wordt geboden, die het specifieke soort besturing maakt dat in het veld gewenst is. Voor tekstvelden kunt u de klasse TextControlCreator gebruiken. Ook beschikt u over de flexibiliteit om IControlCreator te implementeren om een ander soort besturing binnen het veld te maken, zoals een keuzelijst met invoerveld of een ringveldknop.

Decoraties gebruiken

Nadat een gedecoreerd veld is gemaakt, kunnen er decoraties aan worden toegevoegd, op een van vier locaties. Er worden SWT-locatieconstanten gebruikt om aan te geven waar de decoratie moet worden geplaatst. Om een decoratie toe te voegen, moet u een FieldDecoration opgeven, die de afbeelding voor de decoratie definieert en (optioneel) beschrijvende tekst die kan worden weergegeven wanneer de gebruiker zijn muis over de decoratie beweegt.

...
// Een velddecoratie maken en toevoegen aan het veld
Image image = JFaceResources.getImage("myplugin.specialimage");
FieldDecoration mySpecialDecoration = new FieldDecoration(image, "Dit veld is speciaal");
field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false);
...

De booleaanse parameter wordt gebruikt om aan te geven of de decoratie alleen moet worden weergegeven als de focus op de besturing is gericht of altijd moet worden weergegeven. In dit geval wordt de decoratie altijd weergegeven. Het kan echter gebeuren dat de decoratie soms moet worden verborgen en soms moet worden verborgen. De volgende snippet verbergt een decoratie die al is gemaakt.

...
// Er is iets gebeurd waardoor ik wil dat de decoratie wordt verborgen
field.hideDecoration(mySpecialDecoration);
...

Als de afbeelding of beschrijving voor een decoratie wordt bijgewerkt, moet het veld hiervan op de hoogte worden gesteld, zodat de decoratie opnieuw kan worden getekend.

...
// Iets heeft het veld extra speciaal gemaakt
mySpecialDecoration.setDescription("Dit veld is extra speciaal");
field.updateDecoration(mySpecialDecoration);
...

Gedecoreerde en niet gedecoreerde velden opmaken

Wanneer u een gedecoreerd veld opmaakt binnen een dialoogvenster of venster, moet u de opmaakbesturing opmaken, en niet de onderliggende eenvoudige besturing. Bekijk nogmaals de code voor het maken van een eenvoudige tekstbesturing. Bij het opmaken van een tekstbesturing, stelt de toepassing opmaakgegevens in de besturing in.

...
// Een tekstveld maken
Text text = new Text(parent, SWT.BORDER);
text.setText("tekst");
// De opmaakgegevens instellen
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
text.setLayoutData(data);
...

Wanneer u een gedecoreerd veld opmaakt, moet de toepassing de opmaakgegevens in de opmaakbesturing van het veld laten. Afhankelijk van de gewenste opmaak moet de grootte van het veld mogelijk worden aangepast aan de grootte van de decoratie.

...
// Een gedecoreerd veld maken voor een tekstbesturing
DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("tekst");
// De opmaakgegevens instellen
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH +
   FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT);
field.getLayoutControl().setLayoutData(data);
...

De veldondersteuning vereist niet en neemt niet aan dat u alleen gedecoreerde velden binnen een bepaald dialoogvenster of venster gebruikt. De opmaak van uw venster kan echter iets complexer worden wanneer gedecoreerde velden worden gecombineerd met eenvoudige besturingen. Voor het uitlijnen van gedecoreerde velden met niet-gedecoreerde velden, moet u rekening houden met de inspringing die door de breedte van de decoratie wordt veroorzaakt. De breedte van een decoratie is de breedte van de afbeelding ervan. Het wordt echter ingewikkelder als u decoraties met verschillende breedtes gebruikt. Als dit het geval is, kunt u het eenvoudiger maken door al uw decoraties te registreren in de FieldDecorationRegistry.

Velddecoratieregister

In het velddecoratieregister kunt u uw velddecoraties registreren en openen met behulp van een tekenreeks-ID. Dit biedt u een handige manier om decoraties te raadplegen die overal in uw toepassing worden gebruikt. U kunt ervoor kiezen een API te definiëren die uw decoratie-ID's afbeeldt als u ze beschikbaar wilt maken voor andere plugins. Als u een decoratie registreert, wordt de levensduur van de afbeeldingen binnen de desbetreffende decoratie niet beheerd. Uw toepassing kan beslissen hoe de afbeeldingen moeten worden beheerd. Het JFace-afbeeldingsregister kan bijvoorbeeld worden gebruikt om de afbeelding te registreren en de levenscyclus ervan te beheren. Uw toepassing kan er ook voor kiezen om de afbeelding op verzoek te maken en deze te verwijderen wanneer de afbeelding niet meer nodig is. In de Javadoc voor de registratiemethoden in FieldDecorationRegistry worden de verschillende manieren uitgelegd waarop afbeeldingen kunnen worden opgegeven bij het registreren van een decoratie.

Het registreren van uw decoraties in het velddecoratieregister kan ook het opmaakproces vereenvoudigen wanneer u gedecoreerde (en niet gedecoreerde) velden combineert. Standaard raadpleegt een gedecoreerd veld het velddecoratieregister om de maximumbreedte van een decoratie vast te stellen, en ervoor te zorgen dat alle decoraties deze breedte gebruiken. Dit betekent dat alle gedecoreerde velden op de juiste wijze worden uitgelijnd, ongeacht de breedte van welke willekeurige decoratie dan ook. Voor het uitlijnen van niet-gedecoreerde velden kunt u het FieldDecorationRegistry-protocol gebruiken om de breedte van de grootste decoratie te bekijken en de noodzakelijke inspringing in te stellen.

...
// Een tekstveld maken
Text text = new Text(parent, SWT.BORDER);
text.setText("tekst");
// De opmaakgegevens instellen
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
text.setLayoutData(data);
...

Hoewel de veldondersteuning niet verplicht stelt hoe decoraties moeten worden gebruikt, definieert het register ook standaarddecoraties die door toepassingen kunnen worden gebruikt om bepaalde statuswaarden voor een veld weer te geven. De volgende snippet gebruikt bijvoorbeeld een standaarddecoratie voor verplichte velden:

...
// Een gedecoreerd veld maken met een verplichte velddecoratie.
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);
...

Contentsuggesties

Naast het annoteren van velden met decoraties bieden toepassingen mogelijk ondersteuning voor contentsuggestie, waarmee een suggestievenster voor een veld wordt geactiveerd. U kunt een ContentProposalAdapter in een willekeurige besturing installeren om deze functionaliteit te bieden. De volgende snippet installeert een contentsuggestieadapter in een tekstbesturing. Deze tekstbesturing kan een besturing zijn die direct door de toepassing is gemaakt of een die uit een gedecoreerd veld is opgehaald.

...
autoActivationCharacters = new char[] { '#', '(' };
keyStroke = KeyStroke.getInstance("Ctrl+Space");
// aannemen dat myTextControl al op de een of andere manier is gemaakt
ContentProposalAdapter adapter = new ContentProposalAdapter(
	myTextControl, nieuwe TextContentAdapter(),
	new SimpleContentProposalProvider(new String [] {"ProposalOne", "ProposalTwo",
"ProposalThree"}),
	keyStroke, autoActivationCharacters);

Om de content van de besturing op te halen en in te stellen wanneer de gebruiker een suggestie in het voorgrondvenster kiest, moet de adapter worden voorzien van een instance van IControlContentAdapter, waarmee de content van een bepaalde soort besturing kan worden opgehaald en ingesteld. Voor tekstvelden kunt u de klasse TextContentAdapter gebruiken. U beschikt echter over de flexibiliteit om IControlContentAdapter te installeren om de contentsuggestieadapter met een willekeurig soort besturing te gebruiken.

Wanneer u een contentsuggestieadapter maakt, moet u ook een instance van IContentProposalProvider opgeven, waaruit de suggesties zelf worden opgehaald. Deze provider is verantwoordelijk voor het retourneren van een array contentsuggesties. De suggesties zelf zijn opgegeven als instances van IContentProposal, waaruit het label en de content van de suggestie kunnen worden verkregen, in aanvulling op andere informatie, zoals een gedetailleerde beschrijving van de suggestie.

In het bovenstaande voorbeeld wordt de SimpleContentProposalProvider gebruikt. Deze provider wordt gedefinieerd door een eenvoudige array met tekenreeksen als de contentsuggesties op te geven. De eenvoudige provider implementeert het noodzakelijke protocol om elke tekenreeks toe te wijzen aan de verwachte IContentProposal. Dankzij de flexibiliteit van IContentProposalProvider kunt u een suggestieprovider implementeren met geavanceerde features, zoals het filteren van de suggesties op basis van de content van de besturing, het aanbieden van labels met een uitleg in plaats van de werkelijke content die zal worden ingevoegd, en de verwachte cursorpositie nadat een suggestie is ingevoegd. Zie het Voorbeeld van veldondersteuning en zoek naar implementoren van IContentProposalProvider voor geavanceerd gebruik.

Een contentsuggestieadapter configureren

We hebben gezien dat de basisdefinitie voor een contentsuggestieadapter de besturing omvat waarvoor de suggesties worden verstrekt, de contentadapter die wordt gebruikt om de content van de besturing te wijzigen en de suggestieprovider die de lijst met suggesties in het voorgrondvenster definieert. Naast deze drie basisdefinities zijn er verschillende manieren waarop de contentsuggestieadapter kan worden geconfigureerd:

Met het Voorbeeld van veldondersteuning kunt u deze verschillende opties configureren in de voorbeeldvoorkeuren en de verschillende combinaties uitproberen. De adapter kan bijvoorbeeld worden geconfigureerd zodat deze expliciet wordt opgeroepen met een toetsaanslag en de suggestiecontent in de besturing wordt ingevoegd, zodat deze zich gedraagt op een manier die veel lijkt op die van de teksteditorcontentondersteuning. Ook kan deze worden geconfigureerd zonder expliciete toetsaanslag, automatische activering en contentvervanging, zodat deze qua gedrag meer lijkt op de tekenaanvullingsstijl die in URL's van webbrowsers of in zoekvelden wordt gebruikt. Zie de Javadoc voor meer informatie over deze twee methoden en hoe ze met elkaar samenwerken.

Workbenchveldondersteuning

Veldondersteuning op het JFace-niveau geeft uw toepassing veel flexibiliteit bij het bepalen hoe velden moeten worden gedecoreerd en toont suggesties voor veldcontent. Dit is wenselijk voor zelfstandige JFace-toepassingen of zelfstandige Rich Client-toepassingen. Als uw toepassing echter bestemd is om met andere plugins te worden geïntegreerd, zoals de Eclipse SDK of plugins van derden, wilt u de veldondersteuning waarschijnlijk gebruiken op een manier die consistent is met andere plugins. De workbench definieert functieklassen die veldondersteuning gebruiken voor specifieke soorten interactie.

De klasse ContentAssistField maakt bijvoorbeeld een veld dat een decoratie van een lampje bevat om de gebruiker erop te wijzen dat er contentondersteuning beschikbaar is. Ook configureert de klasse een contentsuggestieadapter voor het invoegen van contentondersteuning. Ten slotte biedt deze een afhandelingsroutine voor de contentondersteuningsopdracht op workbenchniveau, zodat het contentondersteuningsvoorgrondvenster wordt geopend wanneer de gebruiker toetsaanslag of activeringsreeks gebruikt die is opgegeven in de toetskoppelingen van de workbench. Zie het org.eclipse.ui.fieldassist-pakket voor meer informatie over deze functieklassen.

Er wordt verwacht dat dit pakket zich verder ontwikkelt naarmate de workbench het gebruik van veldondersteuning uitbreidt en het gebruik van decoraties voor bepaalde veldstatuswaarden wordt gestandaardiseerd.