När du arbetar med en verktygsuppsättning för gränssnittskontroller är det viktigt att du förstår den underliggande trådmodellen som används för läsning och vidarebefordran av plattformens händelser i det grafiska användargränssnittet. Implementationen av användargränssnittstråden påverkar de regler som måste följas i tillämpningarna när Java-trådar används i koden.
Under alla tillämpningar med grafiskt användargränssnitt, oavsett språk och verktygsuppsättning för användargränssnitt, upptäcker operativsystemet händelser i det grafiska användargränssnittet och placerar dem i tillämpningens händelseköer. Även om tillvägagångssättet skiljer sig lite mellan olika operativsystem är grunderna desamma. När användaren klickar medmusen, skriver tecken eller öppnar fönster, genererar operativsystemet händelser i grafiskt användargränssnitt, t.ex. musklickning, tangenttryckning eller fönsteruppritning. Det avgörs vilket fönster och vilken tillämpning som ska ta emot varje händelse. Den placeras i tillämpningens händelsekö.
Den underliggande strukturen för tillämpningar med grafiskt användargränssnitt är en händelseloop. Tillämpningar initierar och startar därefter en loop som helt enkelt läser händelserna i grafiskt användargränssnitt från kön och reagerar på dem. Allt arbete som görs vid hantering av en av dessa händelser måste ske snabbt för att hålla det grafiska användargränssnittssystemets svarstider gentemot användaren.
Långa åtgärder, som utlösts av händelser i användargränssnittet, ska utföras i en separat tråd så att händelselooptråden snabbt kan återgå och hämta nästa händelse i tillämpningens kö. Access till gränssnittskontrollerna och plattforms-APIt från andra trådar måste däremot kontrolleras med uttrycklig låsning och serialisering. En tillämpning som inte följer reglerna kan orsaka att operativsystemanrop misslyckas eller kan, vilket är ännu värre, låsa hela det grafiska användargränssnittssystemet.
SWT följer den trådmodell som stöds direkt av plattformarna. I tillämpningen körs händelseloopen i sin huvudtråd och vidarebefordrar händelser direkt från den här tråden. Användargränssnittstråden är den tråd där Display skapades. Alla andra gränssnittskontroller måste skapas i användargränssnittstråden.
Eftersom all händelskod utlöses från tillämpningens användargränssnittstråd kan tillämpningskod, som hanterar händelser, fritt accessa gränssnittskontrollen och göra grafikanrop utan någon speciell teknik. Tillämpningen är emellertid ansvarig för att förgrena beräkningstrådar vid utförande av långa åtgärder som svar på en händelse.
Obs! SWT utlöser en SWTException för de anrop som måste göras från användargränssnittstråden, men som görs från en annan tråd.
Huvudtråden, inklusive händelseloopen, för en SWT-tillämpning har följande struktur:
public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); shell.open (); // starta händelseloopen. Vi stopar när användaren har gjort // något för att ta bort vårt fönster. while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); }
När gränssnittskontroller skapas och skalet öppnas, läser och vidarebefordrar tillämpningen händelser från operativsystemkön tills skalfönstret tas bort. Om det inte finns några händelser för oss i kön, placeras skärmen i viloläge så att andra tillämpningar får en chans att köra.
SWT tillhandahåller speciella accessmetoder för anrop av gränssnittskontroller och grafikkod från en bakgrundstråd.
Tillämpningar som vill anropa användargränssnittskoden från en annan typ av tråd måste ange en Runnable som anropar användargränssnittskoden. Metoderna syncExec(Runnable) och asyncExec(Runnable) i klassen Display används för att köra dessa körbara tillämpningar i användargränssnittstråden under händelseloopen.
I följande kodstycke visas mönstret för användning av de här metoderna:
// utför tidsintensiva beräkningar ... // uppdatera nu användargränssnittet. Vi är inte beroende av resultatet // så kör asynkront. display.asyncExec (new Runnable () { public void run () { if (!myWindow.isDisposed()) myWindow.redraw (); } }); // gör nu fler beräkningar ...
Det är en god vana att kontrollera om gränssnittskontrollen tas bort inifrån tillämpningen när du använder asyncExec. Eftersom andra saker kan inträffa i användargränssnittstråden mellan anropet till asyncExec
och körningen av tillämpningen kan du aldrig vara säker på vilket läge gränssnittskontrollen är i när tillämpningen bearbetas.
Trådreglerna är mycket tydliga när du implementerar en SWT-tillämpning från grunden eftersom du kontrollerar skapandet av händelseloopen och beslutet att förgrena beräkningstrådar i tillämpningen.
Saker och ting blir lite mer komplicerade när du bidrar till arbetsmiljön med insticksprogramkod. Följande regler kan anses vara "engagemangsregler" när du använder plattformens användargränssnittsklasser, även om reglerna kan skilja sig något mellan olika releaser.