Specialeffekter och spelutveckling
i Java(TM) - Att
fånga muspekaren
av Anibal Wainstein
5.0
Att fånga muspekarens beteende
Interaktion
är ett fint ord som benämner användarens möjligheter
att kunna påverka och styra ett program. I applets sker
detta oftast med muspekaren. Operativsystemet fungerar så
att när du gör olika saker med muspekaren så
skickar det ett meddelande till Java appleten om vad du gör.
Det kan t.ex. vara att du rör på muspekaren, klickar,
drar den m.m. Alla dessa meddelanden skickas bara om du pekar
inom appletskärmen. Men hur går det till egentligen
och hur ser dessa meddelanden ut? I Java 1.02 så används
följande funktioner för att fånga musmeddelanden:
mouseEnter() |
Anropas
när användaren går in i appletskärmen |
mouseExit() |
Anropas
när användaren går ut ur appletskärmen |
mouseMove() |
Anropas
när användaren flyttar på musen. |
mouseDrag() |
Anropas
när användaren har klickat och samtidigt flyttar
på musen. |
mouseDown() |
Anropas
när användaren klickar och håller ner
musknappen. |
mouseUp() |
Anropas
när användaren släpper musknappen. |
Funktionerna
ovan läggs in av programmeraren i sin Java applet. När
något händer med musen så anropas dessa funktioner
automatiskt av operativsystemet. I dessa funktioner kan du
lägga in vilken kod som helst. Dock måste argumenten
och namnen på funktionerna vara korrekta för att
operativsystemet skall känna igen dem. Meddelanden i
Java 1.02 är egentligen ett speciellt objekt som skapas
av Java motorn och skickas till appleten. Objektet bygger
på Event-klassen som kan fyllas med information om nästan
vad som helst som händer med operativsystemet. Event
betyder händelse på engelska. En händelse
kan t.ex. vara när du klickar på musknappen, trycker
på en tangent eller minimerar ett fönster. Jag
kommer dock bara att gå igenom meddelanden relaterade
till muspekaren i det här kapitlet.
5.0.1
Hur din applet vet när muspekaren går in och ut
ur appletområdet (mouseEnter() och mouseExit())
Det
är två metoder som detekterar när du flyttar
in muspekaren över appletområdet eller appletskärmen.
Metoderna existerar redan i Applet-klassen men innehåller
ingen kod. Genom att skriva över dem så kan du
lägga in funktionalitet som aktiveras av dessa händelser:
public boolean mouseEnter(Event e, int x, int y)
{
//Här lägger du in kod som du vill att appleten
//skall exekvera när muspekaren går in i appletområdet.
return true;
}
public boolean mouseExit(Event e, int x, int y)
{
//Här lägger du in kod som du vill att appleten
//skall exekvera när muspekaren går ut ur appletområdet.
return true;
}
Båda
funktionerna returnerar ett boolskt värde. Värdet
skall alltid vara sant om du behandlar händelsen i koden.
Detta spelar inte så stor roll i Java applets, men i
andra Java objekt kan det vara mycket viktigt att Java motorn
får reda på om en metod har behandlat händelsen
eller inte. Event-objektet som skickas med innehåller
bl.a. när händelsen inträffade. Positionsvariablerna
"x" och "y" säger var muspekaren
gick in. Nu ska vi ta ett exempel. Vi ska göra en applet
med en bild som reagerar när du flyttar muspekaren över
det. Vi börjar med att skriva init() metoden och deklarera
variablerna:
//Variabeln "currentimage" pekar på den bild som visas just nu.
Image currentimage;
//Variabeln "normalimage" pekar på bilden som visas när
//muspekaren är utanför appletskärmen.
Image normalimage;
//Variabeln "mouseoverimage" pekar på bilden som visas när
//muspekaren är inom appletskärmen.
Image mouseoverimage;
public void init()
{
//Vi måste alltid ha vanan att använda spåraren.
//Den snyggar upp appleten.
MediaTracker tracker=new MediaTracker(this);
normalimage=getImage(getDocumentBase(),"normal.jpg");
//"normalimage" blir nummer ett i spårarens
//inladdningslista.
tracker.addImage(normalimage,0);
mouseoverimage=getImage(getDocumentBase(),"mouseover.jpg");
tracker.addImage(mouseoverimage,1);
//"currentimage" sätts till "normalimage" i början
//senare i paint() kommer "currentimage" att användas
//för att rita ut bilden.
currentimage=normalimage;
//Slutligen så ser vi till att spåraren
//laddar in bilderna.
try {tracker.waitForAll();}
catch(InterruptedException e)
{
System.out.println("Någonting stoppade inladdningen...");
}
}
public void paint(Graphics g)
{
//Rita ut den "nuvarande" bilden.
g.drawImage(currentimage,0,0,this);
}
Bilderna
laddas in i init() metoden. Det finns tre pekare, "currentimage",
"normalimage" och "mouseoverimage". Den
första pekar på den bild som ska ritas ut i paint()
metoden. De två sistnämnda används för
att ladda in och lagra de två bilderna som skall visas.
Pekaren "currentimage" kommer i början att
peka på den normala bilden som ser ut så här:
Bilden
"normal.jpg" som visas när muspekaren är
utanför appletskärmen.
Det
betyder att vi antar att muspekaren är utanför appletområdet
när appleten startar. Observera att den här gången
har vi inte skrivit "synchronized" på paint()
metoden. Det behövs inte när vi inte använder
trådar. Titta nu på följande metoder:
public boolean mouseEnter(Event e, int x, int y)
{
//Om muspekaren går in i appleten så sätter
//vi "currentimage" till "mouseoverimage" så
//att nästa gång paint() anropas så ritas
//mouseoverbilden ut istället för
//normalbilden.
currentimage=mouseoverimage;
//Skärmen kommer inte att uppdatera sig själv
//bara för att muspekaren gick in i
//appletområdet.
//Så vi måste se till att den gör det
//med update() metoden.
update(getGraphics());
return true;
}
public boolean mouseExit(Event e, int x, int y)
{
//När muspekaren går ut ur området igen
//så återställer vi "currentimage" så att
//den pekar på "normalimage" igen.
currentimage=normalimage;
update(getGraphics());
return true;
}
När
muspekaren går in i appletområdet så anropas
mouseEnter() och "currentimage" sätts att peka
på "mouseoverimage". Skärmen uppdateras
med update() metoden och följande bild visas:
Bilden "mouseover.jpg"
som visas när muspekaren är innanför appletskärmen.
När
muspekaren går ut ur appletskärmen så anropas
mouseExit() och den gamla bilden kommer fram igen. Klicka
här för att se exemplet. Du undrar kanske varför
vi inte använde dubbelbuffring i appleten? "Animationen"
i det här fallet ledde inte till flimmer så det
behövdes inte.
Nästa sida >>
|