7
Mest om metoder…










Javas klassbibliotek
Allmänt om metoder
Metoderna i klassen Math
Trigonometriska övningar
Experiment med slumptal
Förvandla sträng till decimaltal
Antal decimaler i utskrift
Metoder i en applet
Metoder som returnerar värde
Egna klassmetoder
Kap 7: Sid 2
Här återkommer vi till Javas klassbibliotek, och du får lära dig hur man söker i den dokumentation som bifogas
JDK/SDK. Viktigt!
Efter detta följer en repetition av de begrepp som förekommer i samband med metoder (du har tidigare mött
begreppen i kapitel 2). Passa på att repetera!
Därefter presenteras klassen Math. Klassens metoder för matematiska beräkningar exemplifieras i flera
övningar.
Vidare lär du dig metoder för att utföra avrundning av tal. Användbart!
I ett avsnitt behandlas (återigen) de speciella metoder som ingår i en applet.
Här lär du dig en teknik för att rita om en applet samtidigt som den gamla bilden ligger kvar.
Vissa metoder returnerar värde (funktioner). Dessa exemplifieras i övningar om värdetabeller och
funktionskurvor.
Slutligen genomgås hur man skriver egna klassmetoder och skapar egna paket.
Alla bör göra de flesta övningarna t.o.m sidan 25.
Några av dessa (Klocka, Tärning) ligger som grund för kommande övningar i senare kapitel.
Övningarna om värdetabeller och kurvor rekommenderas. Du lär dig tekniken för att överföra x- och ykoordinater i en graf till en skärmbild.
Gör övningarna om klassmetoder och paket om du har speciellt intresse.
265338508
© Ove Lundgren
2
Kap 7: Sid 3
Javas klassbibliotek
Arv
När du skapar en klass, MinApplet, ärver du från en redan befintlig klass Applet.
Den befintliga klassen Applet ärver i sin tur från en annan befintlig klass som heter Panel.
Denna ärver i sin tur från en klass som heter Container, som ärver från en klass vid namn Component,
vilken (slutligen) ärver från ”ur-klassen” Object. Så här alltså:
Object
Component
Container
Panel
Applet
java.lang
java.awt
java.applet
MinApplet
Alla klasser ärver från klassen Object.
För exempelvis klasserna Button, Label och TextField ser hierarkin ut så här:
Object
Component
Button
Label
TextComponent
TextField
265338508
© Ove Lundgren
3
Kap 7: Sid 4
Klassbiblioteket, Java API (= Java Application Programming Interface)
De "färdiga" java-klasserna följer med JDK och är lagrade i "paket" (packages):
Klassen Applet ovan finns i paketet java.applet
När man skriver klassens namn tar man ofta med paketets namn också, t ex java.applet.Applet
Klassen Object ovan finns i paketet java.lang så klassens "fullständiga" namn är java.lang.Object
Övriga klasser ovan finns i paketet java.awt (awt = Abstract Window Toolkit)
Exempelvis skrivs alltså klassen Button med "paket-tillhörighet" så här: java.awt.Button
Alla klasser måste importeras - utom de klasser som tillhör paketet java.lang
Utöver klasserna i JDK finns "färdiga klasser" från andra leverantörer.
Övning: Dokumentation
Alla JDK:s klasser med tillhörande fält och metoder finns beskrivna i html-dokument som levereras med JDK.
I mappen
...\jdk...\docs\api\ finns filen packages.html
 Öppna den i en webläsare! (Se till att du öppnar rätt fil. Det finns många med liknande namn.)
En lista över alla paket visas
 Klicka på package java.applet
Innehållet i paketet java.applet visas. Vi känner igen klassen Applet
(Vi har också använt interfacet Audioclip )
 Klicka Applet
En hierarki med alla superklasserna till klassen Applet visas, med klassernas namn och "paket"-tillhörighet.
 Rulla ned sidan till Method index
Vi känner igen ett antal metoder som vi använt, bland andra init()och showStatus()
 Klicka på showStatus
En beskrivning av metoden visas…

Återvänd till början av Class java.applet.Applet-sidan
(Övningen fortsätter på nästa sida… )
265338508
© Ove Lundgren
4
Kap 7: Sid 5
En applet har, som bekant, metoden paint() Varför hittar vi inte den? Jo den är ärvd från en av
superklasserna.
På föregående sidan återvände du till java.applet.Applet
 Klicka nu på superklasserna, det vill säga java.awt.Panel, java.awt.Container osv och ta reda
på vilken klass som, "från början", äger metoden paint()
Vi hittar paint() i klassen Container
 Klicka på paint() och läs om den metoden.
 Återvänd sedan till sidan Java API Packages: Klicka All Packages högst upp till vänster
 Klicka nu package java.awt
 Rulla ner till Class index
Du känner igen många klasser: Button, Color, Font, Image, Label, TextField med flera
 Klicka på några kända klasser. Leta upp metoder som vi använt (Under Method index)
Ibland hittar man inte en metod. Då får man leta i superklasserna…
 I klasserna Color och Font känner du igen en del av innehållet i Field index
 Studera också "Constructor index" för några klasser, t ex TextField och Color.
När ett nytt objekt skapas (med new, du vet…) så anropas ju konstruktorn som skapar objektet.
Man kan ofta välja mellan olika konstruktorer.
Det som står efter new kan se lite olika ut beroende på vilken konstruktor vi väljer när vi skapar objektet.
Constructor index är en sammanställning över möjliga konstruktorer.
Exempel:
När vi skapade textfält använde vi t ex konstruktorn TextField(int) - så här:
TextField inruta;
inruta = new TextField(10);
(Detta ger ett textfält som rymmer 10 tecken.)
Men ett textfält kan också skapas t ex med konstruktorn TextField(String)
- så här:
TextField inruta;
inruta = new TextField("Kalle");
(Då skapas fältet med texten "Kalle" inlagd och i detta fall 5 tecken brett )
 Återvänd till sidan Java API Packages
 Undersök paketet java.lang. Har vi använt någon klass i det paketet?
(Du bör hitta String, Integer, Object)
Högst upp på alla sidor i API-dokumentationen finns länken Class Hierarchy
 Klicka denna.
 Studera hur sidan Class Hierarchy är uppbyggd.
Leta t ex upp klassen Applet och följ dess superklasser ända upp till klassen Object
Högst upp på alla sidor i API-dokumentationen finns länken Index
 Klicka denna.
Sidan Index of all Fields and Methods visas (Det kan ta lite tid att ladda in denna sida…)
Här finns alla fält och metoder i bokstavsordning…
I fortsättningen:
Ta som vana att gå in i API-dokumentationen när du stöter på en ny klass eller metod och "forska":
I vilket paket finns klassen? Vilka klasser är dess superklasser? Vilken klass tillhör metoden?
265338508
© Ove Lundgren
5
Kap 7: Sid 6
Allmänt om metoder
Vi repeterar olika typer av metoder, vad som menas med överlagring och överskuggning och vad en klassmetod
är. Begreppen har behandlats i tidigare kapitel.
Metoder av typen void, utan parametrar
Metoden utför något - men den är void, den lämnar inte något värde.
Metoden är definierad utan parametrar. Den kräver alltså inga argument vid anropet.
Exempel:
Metoden rulla() definieras i en klass så här:
public void rulla()
{
// beskrivning vad som ska göras...
}
Ett objekt (t ex bollen) som skapas utifrån klassen äger förstås metoden.
Metoden anropas med bollen.rulla();
Exempel:
Metoden show() är definierad i klassen Frame
public void show()
{
// definierad av java-konstruktörerna hos Sun
}
Om vi har ett Frame-objekt med referensen f så visas objektet med anropet
f.show();
Exempel:
Metoden init() definieras i en klass (en applet) så här:
public void init()
{
inruta = new TextField(10);
roed = new Color(255,0,0);
// etc ...
}
Metoden anropas automatiskt av webbläsaren när appleten startar …
(Om vi tänker oss att webbläsaren kallar appletobjektet för x så utförs alltså satsen
automatiskt vid start…)
265338508
© Ove Lundgren
x.init();
6
Kap 7: Sid 7
Metoder av typen void, med parametrar
Metoden utför något - men den är void, den lämnar inte något värde
Metoden är definierad med parametrar. Den kräver alltså ett eller fler argument vid anropet
Exempel:
Metoden rulla() definieras i en klass så här:
public void rulla (int n)
{
// beskrivning vad som ska göras...
}
parameter
argument
Ett objekt (t ex olle) som skapas utifrån klassen äger metoden.
Metoden anropas med argument, t ex:
bollen.rulla(12);
Exempel:
Metoden paint() definieras i en klass (en applet) så här:
public void paint(Graphics g)
{
g.drawString("Hej",50,100);
// etc ...
}
Metoden paint(grafobj); anropas automatiskt då applet skapas.
grafobj är det Graphics-objekt som är knutet till appleten
Exempel:
Metoden drawOval() definieras i klassen Graphics
public void drawOval( int x, int y, int b, int h )
{
// definierad av java-konstruktörerna hos Sun
}
4 parametrar
Om g är ett Graphics-objekt kan metoden anropas med t ex:
g.drawOval(50,100,150,150);
4 argument
Exempel:
Metoden setBackground()
definieras i klassen Component (och ärvs sedan av klassen Applet)
public void setBackground(Color c )
{
// definierad av java-konstruktörerna hos Sun
}
Metoden kan anropas med:
this.setBackground(farg) där farg är ett Color-objekt
När ett objekt anropar en egen metod sätter man this framför punkten.
( Ordet this kan utelämnas - det är då underförstått att det är en egen metod som anropas. )
265338508
© Ove Lundgren
7
Kap 7: Sid 8
Icke-void-metoder
En icke-void-metod kan vara definierad med eller utan parametrar.
En icke-void-metod returnerar alltid ett värde.
Icke-void-metoder kallas ofta funktioner.
Exempel:
Metoden (funktionen) volym() definieras i en klass t ex så här:
public double volym(int n)
// i detta fall returneras ett flyttal
{
// beskrivning vad som ska göras...
return v;
}
Ett objekt (t ex bollen) som skapas utifrån klassen äger metoden.
Metoden anropas t ex så här:
vol = bollen.volym(12);
eller
System.out.println( bollen.volym(12));
Exempel:
Metoden (funktionen) getText() definieras i klassen TextComponent (och ärvs av TextField)
public String getText()
{
// definierad av java-konstruktörerna hos Sun
return s; // Sträng s är innehållet i det aktuella TextField-objektet
}
Om vi har skapat ett TextField-objekt inruta, och namn är ett String-objekt, så kan metoden anropas:
namn = inruta.getText();
Överskuggning av metoder
När vi skriver en applet så ärver vi från klassen Applet.
Detta innebär att ett antal metoder redan finns, som paint(), init() med flera
Vad händer då om vi definierar en metod paint() i vår applet, så här:
public void paint(Graphics g)
{
g.drawOval(12,20,30,40);
// och så vidare
}
Jo den ursprungliga paint()-metoden ersätts av den nya...
Detta kallas överskuggning (override, omdefiniera...)
Överlagring av metoder
Metoder med samma namn men med olika antal och/eller typ av parametrar kallas överlagrade metoder.
265338508
© Ove Lundgren
8
Kap 7: Sid 9
Klassmetoder
Normalt anropar vi en metod via ett objekt, exempelvis
inruta.getText();
Här har vi ett TextField-objekt, inruta, och vi använder metoden getText() som är definierad i den
klassen (eller, som i detta fall, i någon av dess superklasser)
En klassmetod (ibland kallad statisk metod) är en metod som kan användas direkt, utan att man först har skapat
ett objekt. Vi har redan använt några sådana metoder:
Integer.parseInt( ... )
Prompt.heltal( ... )
Vi behöver inte skapa ett Integer-objekt eller Prompt-objekt för att använda metoderna...
Man skriver helt enkelt klassens namn följt av metodnamnet (med en punkt emellan)
Man kan säga att en klassmetod tillhör klassen som helhet – inte de enskilda objekten.
Integer är en klass som innehåller en rad metoder för hantering av heltal
Prompt är en klass med metoder för inmatning av tal i konsolprogram (Tillhör detta läromedel, ej JDK)
En metod blir en klassmetod om den deklareras med nyckelordet static
Vi har definierat en statisk metod, main, vid flera tillfällen - när vi skrivit javaprogram:
class KonsolProg
{
public static void main( String args[] )
{
...
}
}
Metoden KonsolProg.main( ) anropas (av tolken java.exe ) vilket innebär att konsolprogrammet
startar.
265338508
© Ove Lundgren
9
Kap 7: Sid 10
Metoderna i klassen Math
Det finns en javaklass som heter Math. Den tillhör java.lang-paketet
(Fullständiga klassnamnet är alltså: java.lang.Math) (Klassen behöver således inte importeras.)
Denna klass innehåller en rad metoder (funktioner) för matematik.
Alla metoder är klassmetoder (vi behöver inte skapa Math-objekt först...)
Klassen har också två statiska fält (konstanter) för de intressanta talen  och e
I sammanställningen nedan är x och y flyttal / decimaltal (double), medan i och j är heltal (int)
Du bör kunna använda Math.PI nedan samt de fyra därpå följande metoderna.
Lär dig de övriga om du känner till motsvarande begrepp i matematiken.
Metod / Fält
Math.PI
Returnerar
talet  (3.14159...)
Returtyp
double
Exempel
y = Math.PI*x*x;
y är arean hos en cirkel med radien x
Math.sqrt(x)
Kvadratroten ur talet x
double
y = Math.sqrt(25.0);
y får värdet 5.0
Math.pow(x,y)
”x upphöjt till y”,
double
y = Math.pow(2.0 , 3.0);
y får värdet 23 = 8.0
Math.random()
ett slumptal mellan 0 och 1
(egentligen 0  slump < 1)
double
Math.exp(x)
”e upphöjt till x” ,
j = (int)(Math.random()*6 ) + 1;
j blir här ett av talen 1, 2, 3, 4, 5 eller 6
(En "tärning" alltså! Se avsnitten om slumptal!)
y = Math.exp(2.0);
y får värdet e2 ( 7,389....)
Math.E
talet e
(2,718...)
double
y = Math.E;
y får värdet e (2,718…)
Math.log(x)
naturlig logaritm för x, ln x
double
y = Math.log(5.0);
y = ln 5
(1,609...)
Math.sin(v)
sinusvärdet,
sin v
double
y = Math.sin(2.0):
y = sin 2
(0,909...)
OBS! argumentet i radianer!
Math.cos(v)
cosinusvärdet cos v
double
Math.tan(v)
tangens
tan v
double
Math.atan(x)
arctangens
arctan v
double
xy
double
ex
(omvändning till tangens)
Math.abs(x)
absolutbeloppet
|x|
double
Math.abs(i)
absolutbeloppet
|i|
int
y = Math.arctan(1.0)
y = arctan 1
(y blir  / 4 rad = 0,785 rad, dvs 45o)
Vinkeln  / 4 har ju tangensvärdet 1
y=Math.abs(-1.75);
y får värdet 1,75
i = Math.abs(7);
i får värdet 7
Bra att minnas i sammanhanget:
Avhuggning till heltal får vi genom att göra en cast:
i = (int)x;
Gör om en sträng till heltal:
t = Integer.parseInt(s) ;
Gör om tal till sträng:
s
265338508
© Ove Lundgren
= t + ”” ;
10
Kap 7: Sid 11
Övning: Testa Math
// Se till att Prompt.class finns i samma mapp
class Mattetest
{
public static void main( String args[] )
{
double r, x, y, z, rot,area ;
int tarning, i, j;
System.out.println("Testar pi:");
r = Prompt.decimaltal("Skriv radien ");
area= Math.PI*r*r;
System.out.println("Arean är " + area);
System.out.println();
System.out.println("Testar roten ur:");
x = Prompt.decimaltal("Mata in ett tal ");
rot= Math.sqrt(x);
System.out.println("Kvadratroten är " + rot);
System.out.println();
System.out.println("Testar upphöjt till:");
x = Prompt.decimaltal("Vilken bas? ");
y = Prompt.decimaltal("Vilken exponent?");
z = Math.pow(x,y);
System.out.println(x +" upphöjt till " + y + " är " + z);
System.out.println();
System.out.println("Testar avhuggning till heltal:");
x = Prompt.decimaltal("Skriv ett tal med decimaler ");
i = (int)x ; // här görs en cast
System.out.println("Närmast mindre heltal är " + i);
System.out.println();
System.out.println("Testar talet e:");
System.out.println("Talet e " + Math.E);
x = Prompt.decimaltal("Till vilken exponent ska e upphöjas? ");
System.out.println("e upphöjt till "+ x + " är " + Math.exp(x) );
System.out.println();
System.out.println("Testar naturliga logaritmen:");
x = Prompt.decimaltal("Skriv ett tal ");
System.out.println("Naturl. log. för " + x + " är " + Math.log(x));
System.out.println();
System.out.println("Testar trigonometri:");
x = Prompt.decimaltal("Skriv en vinkel i radianer ");
System.out.println("Sinusvärdet är " + Math.sin(x));
System.out.println("Cosinusvärdet är " + Math.cos(x));
System.out.println("Tangensvärdet är " + Math.tan(x));
System.out.println();
System.out.println("Testar absolutbelopp:");
x = Prompt.decimaltal("Skriv ett tal (gärna negativt) ");
System.out.println("Talets absolutbelopp är " + Math.abs(x));
i = Prompt.heltal("Skriv ett heltal (gärna negativt)");
System.out.println("Talets absolutbelopp är " + Math.abs(i));
}
}
Kopiera (eller skriv av) ovanstående kod. (Ett enkelt konsolprogram för att testa…)
Spara som Mattetest.java i mappen X\java\Javagrunder
Kompilera och kör.
Testkör några gånger.
Kom ihåg att använda punkt (och inte komma) som decimaltecken när du skriver in decimaltal.
265338508
© Ove Lundgren
11
Kap 7: Sid 12
Övning: Math i API
Leta upp klassen Math i API-dokumentationen
Läs om ovan nämnda metoder och fält
Övning: Rot-tabell
Gör en applet som visar kvadratroten ur talen 1 – 10.
Spara som RotTabell i mappen X\java\RotTabell
Försök själv. Kika nedan om du kör fast….
import java.applet.*;
import java.awt.*;
public class RotTabell extends Applet
{
double y;
public void paint(Graphics g)
{
g.drawString("x" , 50, 50);
g.drawString( "Roten ur x" , 100,50);
g.drawLine(50,55,200,55);
for(int x = 1 ; x <= 10; x++)
{
g.drawString(x + "" , 50 , 50 + 20 * x );
y = (double) x;
g.drawString(Math.sqrt( y ) + "" , 100, 50 + 20 * x );
}
}
}
En kommentar till satsen g.drawString(x
+ "" , 50 , 50 + 20 * x );
Första x-värdet (x=1) kommer att skrivas i position (50, 70)
Nästa x-värde (x=2) kommer att skrivas i position (50, 90)
och så vidare…
265338508
(eftersom 50 + 20 * 1 =70)
(eftersom 50 +20 *2 =90)
© Ove Lundgren
12
Kap 7: Sid 13
Trigonometriska övningar
Övning: Klassen Klocka
I nedanstående applet, VisaKlocka, instansieras ett objekt av klassen Klocka
Klockan instansieras med mittpunkten (150,150) och diametern 100 pixels.
Metoden setTid(0) sätter tiden till 0 (noll) sekunder.
Metoden visa(g) ritar klockan i appleten.
import java.awt.*;
import java.applet.Applet;
public class VisaKlocka extends Applet
{
Klocka k;
public void init()
{
k = new Klocka(100, 150,150 );
k.setTid(0);}
public void paint(Graphics g)
{
k.visa(g);
}
}
Klockan har alltså bara en visare (visar sekunder)
(som en kronometer)
Skriv klassen Klocka.
Instansvariabler: diam, x, y, sek
Konstruktorn ger värden på x och y (klockans mittpunkt) samt diam (dess diameer)
Med metoden setTid(int s) sätts det antal sekunder som klockan ska visa.
Med metoden visa(Graphics g) ska klockan ritas.
Se figur:
Om klockans medelpunkt är (x ,y) och visarens längd är r så får
(i matematiken) punkten P koordinaterna:
px = x + r * cos v
py = y + r * sin v
Vinkeln v beror på antalet sekunder.
En sekund motsvarar ju 360o/60
P
r
v
eller
2/60
(x,y)
Försök skriva klassen Klocka på egen hand
(Du får nog ”trixa” lite för att få klockan att gå rätt…)
På nästa sida finns ett lösningsförslag…
265338508
© Ove Lundgren
13
Kap 7: Sid 14
import java.awt.*;
public class Klocka
{
private int diam, x, y, sek;
public Klocka(int d, int a, int b)
{
diam = d;
x = a;
y = b;
}
public void setTid(int s)
{
sek = s;
}
public void visa(Graphics g)
{
g.drawOval(x-diam/2,y-diam/2,diam,diam); // klockans periferi
g.fillOval(x-2,y-2,4,4);
// mittpunkten
double v = - sek*2*Math.PI/60 + Math.PI/2; // se nedan
int r = diam/2-3;
// visarens längd
int px =x + (int)(r*Math.cos(v)); // x-koordinat för punkten P
int py =y - (int)(r*Math.sin(v)); // se nedan
g.drawLine(x,y,px,py);
}
}
Satsen
double v = - sek*2*Math.PI/60 + Math.PI/2;
Minustecken här, annars går klockan baklänges!
En vridning medurs ger ju en negativ vinkel i
matematiken…
Vi lägger till Math.PI/2, det vill
säga 90o, så att klockan pekar på
”norr” vid tiden noll sekunder…
Satsen int py = y - (int)(r*Math.sin(v));
beräknar y-koordinaten för punkten P
Minustecken här eftersom y-koordinater växer nedåt i datagrafiksammanhang…
Spara filerna VisaKlocka.java och Klocka.java i mappen X\java\Klocka
Kompliera.
Skriv en html-fil och provkör! (Klockan visas, men står stilla…)
Övning: Klockan tickar
Lägg till en knapp. Varje gång du trycker på knappen ska klockan ticka fram fem sekunder.
265338508
© Ove Lundgren
14
Kap 7: Sid 15
Övning: En Stjärn-klass
Studera denna applet:
import java.awt.*;
import java.applet.*;
public class VisaStar extends Applet
{
Star s1, s2;
public void init()
{
s1 = new Star(50, 12);
// Diameter 50, 12 ”uddar”
s2 = new Star(100, 24); // Diameter 100, 24 ”uddar”
s1.setPos(50,50);
// Stjärnans placering
s2.setPos(150,150);
// Stjärnans placering
}
public void paint(Graphics g)
{
s1.visa(g);
// Stjärna visas
s2.visa(g);
// Stjärna visas
}
}
Appleten instansierar och visar två objekt av klassen Star, så här:
Den lilla stjärnan har ”diametern” 50 pixel och visar 12 ”uddar”
Den stora stjärnan har ”diametern” 100 pixel och visar 24 ”uddar”
Skriv klassen Star.java
P
r
Använd en loop.
Låt vinkeln v öka för varje varv.
Rita linje från medelpunkten till punkten P varje varv.
P.s koordinater är ( r * cos v , r*sin v )
där r är halva diametern
265338508
© Ove Lundgren
v
15
Kap 7: Sid 16
Lösningsförslag:
import java.awt.*;
public class Star
{
private int diam, x, y, antal;
public Star(int d, int a)
{
diam = d;
antal= a;
}
public void setPos(int x, int y)
{
this.x = x;
this.y = y;
}
public void visa(Graphics g)
{
for(double v = 0.0; v < 2*Math.PI; v = v + 2 * Math.PI/antal)
{
int a = (int)(diam/2*Math.cos(v));
int b = (int)(diam/2*Math.sin(v));
g.drawLine(x,y, x+a,y-b );
}
}
}
Skriv in, spara och kompilera klasserna Visastar och Star.
Spara i mappen X\java\Star
Exekvera!
Testa olika storlekar och antal ”uddar” på stjärnorna…
265338508
© Ove Lundgren
16
Kap 7: Sid 17
Experiment med slumptal
Övning: Konsolprogram som visar slumptal
Skriv in denna kod. Spara som SlumpTest.java i mappen X\java\Slump Kompilera och kör.
class SlumpTest
{
public static void main( String args[] )
{
double slump ;
int i;
for(i=1;i<=12;i++)
{
slump= Math.random();
System.out.println("Slumptal nummer " + i + ":
}
" + slump);
}
}
Funktionen Math.random() slumpar ett flyttal.
Variabeln slump tilldelas detta flyttal.
0  slump < 1
Satserna ingår i en for-loop. Det hela upprepas 12 gånger.
Övning: Tipsrad
Ändra koden för klassen SlumpTest.
Kalla klassen class Tipsrad. Spara som Tipsrad.java
Skriv om koden inne i loopen så att
om slump < 0,4 så skrivs strängen "1
annars om slump < 0,8 så skrivs " X "
annars skrivs " 2"
"
Gör så att loopen körs 13 gånger.
Spara igen. Kompilera. Kör. Resultatet blir en tipsrad.
Experimentera: Ändra t ex så att sannolikheten för bortavinst (2:a) ökar
Övning: Applet med tipsrad
Bygg en applet som har en knapp. När du trycker på knappen ska en ny tipsrad visas.
265338508
© Ove Lundgren
17
Kap 7: Sid 18
Slumpa heltal
Betrakta satserna nedan: ( slump är double,
t är int )
slump = Math.random();
ger ett tal i intervallet 0.0 till 0,999999999999…
slump = 6 * Math.random();
ger ett tal i intervallet 0.0 till 5,99999999…
t = (int)(6 * Math.random());
ger ett heltal i intervallet fr o m 0 t o m 5
t = (int)(6 * Math.random()) + 1;
ger ett heltal i intervallet fr o m 1 t o m 6
Den sista satsen ger alltså ett heltal som är 1, 2, 3, 4, 5 eller 6. En tärning med andra ord!!
Allmänt gäller formeln
t = (int)(n * Math.random() ) + a;
n = antalet tänkbara slumptal
a = det minsta tänkbara slumpade talet
Exempel:
Slumpa ett tal i intervallet fr o m 0 t o m 255 (det vill säga 256 stycken tänkbara tal). Formel:
t = (int)(256 * Math.random() ) ;
Övning: Konsolprogram som slumpar heltal
Ändra koden för klassen SlumpTest.
Kalla klassen class SlumpaHeltal. Spara som SlumpaHeltal.java
Deklarera heltalsvariablen t
Skriv om koden inne i loopen så att tolv tal i intervallet 0 – 255 visas
Spara igen. Kompilera. Kör.
Övning: Slumpa färg
Skriv en applet, Slumpfarg, som har en knapp med tillhörande händelsehantering.
I actionPerformed-metoden slumpas tre heltal i intervallet 0 - 255
Sen skapas ett Color-objekt med de tre heltalen som RGB-komponenter
Så sätts den nya färgen till bakgrundsfärg.
När man trycker på knappen så byter alltså appleten färg!
Spara som Slumpfarg.java i mappen X\java\Slumpfarg
Övning: Konsolprogram som visar tärning
Ändra koden för klassen SlumpTest.
Kalla klassen class KonsolTarning. Spara som KonsolTarning.java
Deklarera heltalsvariablen t
Skriv om koden inne i loopen så att tolv "tärningskast" (tal i intervallet 1 - 6 ) visas.
Spara igen. Kompilera. Kör.
265338508
© Ove Lundgren
18
Kap 7: Sid 19
Övning: Applet som visar en tärning
En applet, KastaTarning, har en knapp.
När man trycker på knappen visas en tärning, t ex:
Appleten instanierar ett objekt av typen Tarning med referensen t
Tarningsobjektets metod kasta() slumpar och returnerar ett tal i intervallet 1 – 6
Metoden visa(Graphics) visar tärningen med rätt antal prickar…
Studera appleten och skriva av (eller kopiera) och spara koden.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class KastaTarning extends Applet implements ActionListener
{
Tarning t;
Button butt;
int k;
public void init()
{
t = new Tarning(40,40); // tärning i position 40,40
k = t.kasta();
butt = new Button("Kasta!");
butt.addActionListener(this);
add(butt);
}
public void paint(Graphics g)
{
t.visa(g);
g.drawString(”Tärningen visar: ” + k, 40, 110 );
}
public void actionPerformed(ActionEvent e)
{
k = t.kasta();
repaint();
}
}
Skriv nu klassen Tarning
Försök lösa uppgiften på engen hand
(På nästa sida finns ett lösningsförslag..)
Spara KastaTarning.java och Tarning.java i mappen X\java\Tarning
265338508
© Ove Lundgren
19
Kap 7: Sid 20
import java.awt.*;
public class Tarning
{
private Color farg = Color.blue;
private Color prickfarg = Color.yellow;
private int a, b;
private int p = 5; // prickstorlek
private int t; // antal prickar
public Tarning(int a1, int b1)
{
a = a1;
b = b1;
}
public int kasta()
{
t = (int)(6 * Math.random()) + 1;
return t;
}
public void visa(Graphics g)
{
g.setColor(farg);
g.fillRect(a,b,45,45);
g.setColor(prickfarg);
switch (t)
{
case 1:
g.fillOval(a+20,b+20,p,p);
break;
case 2:
g.fillOval(a+10,b+10,p,p);
g.fillOval(a+30,b+30,p,p);
break;
case 3:
g.fillOval(a+10,b+10,p,p);
g.fillOval(a+30,b+30,p,p);
break;
case 4:
g.fillOval(a+10,b+10,p,p);
g.fillOval(a+10,b+30,p,p);
break;
case 5:
g.fillOval(a+10,b+10,p,p);
g.fillOval(a+20,b+20,p,p);
g.fillOval(a+30,b+30,p,p);
break;
case 6:
g.fillOval(a+10,b+10,p,p);
g.fillOval(a+30,b+10,p,p);
g.fillOval(a+20,b+30,p,p);
break;
}
g.fillOval(a+20,b+20,p,p);
g.fillOval(a+30,b+10,p,p);
g.fillOval(a+30,b+30,p,p);
g.fillOval(a+30,b+10,p,p);
g.fillOval(a+10,b+30,p,p);
g.fillOval(a+20,b+10,p,p);
g.fillOval(a+10,b+30,p,p);
g.fillOval(a+30,b+30,p,p);
}
}
265338508
© Ove Lundgren
20
Kap 7: Sid 21
Förvandla sträng till decimaltal
I ett tidigare kapitel byggde vi applets där man kunde skriva in tal i textfält (TextFields)
I ett textfält är ju allt strängar, så vi fick lov att omvandla en inmatad sträng (t ex "123") till ett heltal (123)
Vi använde då metoden Integer.parseInt( )
I en övning gällde det att mata i en cirkels radie i textfältet inruta för att sedan överföra värdet till
heltalsvariabeln radie. Satsen kunde se ut så här:
radie = Integer.parseInt( inruta.getText() );
( java.lang.Integer är en klass som innehåller en rad metoder för hantering av heltal )
Vi vill nu kunna mata in en sträng, t ex "123.55" i textfältet inruta och få strängen omvandlad till ett
decimaltal (ett flyttal) (123.55) som sedan tilldelas double-variabeln r
I Java2 finns en metod för detta. Vi kan vi skriva så här:
r = Double.parseDouble( inruta.getText() );
I Java 1.1 får vi sätta samman fler metoder för samma sak. Vi kan vi skriva så här:
r = Double.valueOf(inruta.getText().trim().replace(',','.')).doubleValue();
(Här har vi dessutom utnyttjat metoden replace som byter ut ett tecken mot ett annat:
Om man råkar skriva ett kommatecken som decimalttecken så byts det ut mot en punkt.
Java kräver ju punkt som decimaltecken)
För dig som vill fördjupa dig i satsen följer här en "dissektion". Vi börjar ”inifrån”:
inruta är ett TextField-objekt
TextField-objekt har en metod (en funktion) getText() som "fångar" det som står i textfältet och
returnerar det som en sträng, ett String-objekt. Så inruta.getText() är ett String-objekt.
String-objekt har en metod (en funktion) trim() som "hugger av" eventuella blanktecken i början och slutet
av strängen och returnerar en "trimmad" sträng. Så inruta.getText().trim() är ett String-objekt.
String-objekt har en metod (en funktion) replace(t1,t2) som byter ut eventuella förekomster av tecknet
t1 i strängen mot tecknet t2 och returnerar denna nya variant av strängen.
Så inruta.getText().trim().replace(',','.') är ett String-objekt där alla eventuella
komma-tecken bytts ut mot punkter.
Det finns en klass som heter Double. (Det är inte den primitiva variabeltypen double utan en klass Double)
I klassen finns en rad metoder för flyttalshantering. (I klassen Integer finns motsvarande för heltal)
Klassen Double har en metod (en funktion) valueOf(String)
Den funktionen tar ett String-objekt som argument och returnerar ett objekt tillhörigt klassen Double.
Så Double.valueOf(inruta.getText().trim().replace(',','.')) är ett Double-objekt.
Double-objekt har en metod (en funktion) doubleValue(). Denna returnerar värdet hos Double-objektet
och detta är – äntligen - vårt eftersökta flyttal av den primitiva datatypen double (puh!)
Talet tilldelas variabeln r och kan användas i beräkningar…
Övning: Cirkel - igen
Ta fram filen Cirkel.java (kap 5) Deklarera radie som double i stället för int
Använd någon av ovan beskrivan metoder för att ta hand om den radie som matas in i textfältet
(Byt alltså ut parseInt-metoden)
Du använde förut talet pi = 3.14159
265338508
Byt ut mot Math.PI
© Ove Lundgren
21
Kap 7: Sid 22
Antal decimaler i utskrift
Talformat
Vi har hittills fått lov att stå ut med att flyttalen i våra program visat onödigt många decimaler.
Det är på tiden att vi själva kan bestämma antal decimaler som ska visas. Dags att införa talformat!
Gör så här:
Importera:
import java.text.DecimalFormat; // ett nytt paket!
Deklarera objekt:
DecimalFormat d2, d3, m3;
Skapa objekt:
d2 = new DecimalFormat("0.00");
// ger 2 decimaler
d3 = new DecimalFormat("0.000"); // ger 3 decimaler
m3 = new DecimalFormat("0.###"); // ger max 3 decimaler
// Ev. nollor på slutet
// visas ej...
Objekt av klassen DecimalFormat har en metod (en funktion), format(tal)
Argumentet (tal) är av typ double
Funktionsvärdet blir en sträng som innehåller talet med önskat antal decimaler.
Exempel:
g.drawString("Arean är " + d2.format(area) , 10,90 );
g.drawString("Omkretsen är " + d3.format(omkrets) , 10,90 );
System.out.println("Slumptal nr " + i + ":
Övning: RotTabell - igen
Ändra koden i RotTabell.java
" + m3.format(slump));
så att talen visas avrundade till två decimaler:
import java.text.*;
import java.applet.*;
import java.awt.*;
public class RotTabell extends Applet
{double y;
DecimalFormat d2;
public void init()
{
d2 = new DecimalFormat("0.00"); // ger 2 decimaler
}
public void paint(Graphics g)
{
g.drawString("x" , 50, 50); g.drawString( "Roten ur x" , 100,50);
g.drawLine(50,55,200,55);
for(int x = 1 ; x <= 10; x++)
{
g.drawString(x + "" , 50 , 50 + 20 * x );
y = (double) x;
g.drawString(d2.format( Math.sqrt( y )) + "" , 100, 50 + 20 * x );
}
}
}
265338508
© Ove Lundgren
22
Kap 7: Sid 23
Metoder i en applet
Metoder som körs automatiskt
När vi skriver en applet (t ex MinApplet) så ärvs ett antal metoder från klassen Applet.
Flera av dessa metoder körs automatiskt vid olika tillfällen under en applets "liv".
I kapitel 4 beskrev vi dessa metoder ungefär så här:
init()
Körs med automatik när en applet laddas.
Här lägger man kod för initialvärden av olika slag.
start()
Körs automatiskt då en applet visas
Här skrivs kod som får appleten att göra något.
Appletens init-metod körs första gången appleten visas.
Appletens start-metod körs första gången samt varje gång du återvänder till sidan med appleten.
paint(Graphics g)
Metoden exekveras automatiskt varje gång en applet visas.
Metoden har en parameter, en referens till ett Graphics-objekt.
Då metoden anropas blir argumentet referensen till appletens egna
grafikobjekt
stop()
Körs automatiskt då man lämnar webb-sidan med appleten
destroy()
Exekveras automatiskt när man slutar sitt surfpass.
I respektive metod skriver man kod för sådant som man vill ska utföras vid respektive tidpunkt.
Hittills har du mest omdefinierat init() – och paint()-metoderna.
Snart kommer exempel där även övriga metoder överskuggas…
paint()-metoden anropas med automatk då appleten visas. Ibland behöver man anropa paint() på nytt för
att rita om appletytan. Du har redan sett att man då använder en metod som heter repaint().
Nästa avsnitt handlar just om metoderna paint() och repaint() samt om ytterligare en metod som är
inblandad, nämligen update()
265338508
© Ove Lundgren
23
Kap 7: Sid 24
Metoderna paint(), repaint() och update()
Metoden paint(Graphics g) är definierad med en parameter som är referens till ett Graphics-objekt.
När paint() anropas blir automatiskt argumentet referensen till appletens eget grafiska objekt.
(Repetera gärna vad som står om klassen Graphics i kapitel 4)
Antag att vi skulle behöva anropa paint(), t ex i actionPerformed()-metoden.
(Vi kanske vill att appleten ska ritas om - exempelvis efter en knapptryckning. )
Om vi vill skriva kod, en sats som innebär anrop av paint(), vad ska vi då skriva för argument?
this.paint(????);
Vi känner ju inte namnet på referensen till det appletens grafiska objekt. Det är en intern referens.
Appletobjekt har ytterligare en metod, repaint(), som blir vår räddning. Den anropas utan argument:
this.repaint();
Metoden utför just vad vi vill: Appleten ritas om!
Låt oss se närmare på vad som händer vid ett repaint()-anrop:
Vi måste då först bekanta oss med en metod som heter update()
Detta är ytterligare en metod som ärvs från klassen Applet.
Den har ett Graphics-objekt som parameter, och så här är den definierad (i princip):
public void update(Graphics g)
{
// Bakgrunden ritas om varvid allt som
// eventuellt tidigare uppritats raderas
...
// paint() anropas:
paint(g);
}
update() gör alltså följande:
Raderar vad som eventuellt redan ritats på appleten - och anropar sedan paint()
När metoden repaint() anropas så anropar denna i sin tur metoden update()
Det vill säga, allt som eventuellt är ritat på appleten raderas först, och sedan ritas appleten om.
repaint()
265338508
 update()

ev. gammalt raderas
 paint()
© Ove Lundgren
24
Kap 7: Sid 25
Övning: Överskugga update()
Ta fram filen FlyttaJumbo.java och påminn dig om hur den fungerade:
I action()-metoden finns satsen
this.repaint();
Kör appleten. När du trycker på knapparna så försvinner en tidigare ritad Jumbo och en ny Jumbo ritas varje
gång!
Antag nu att vi vill göra så att en tidigare ritad Jumbo ligger kvar på appleten när en ny Jumbo ritas.
Hur ska vi gå till väga?
Naturligtvis genom att göra en egen definition av update() !
Vi överskuggar update() så att den inte gör något annat än anropar paint()
I filen FlyttaJumbo.java gör följande tillägg:
public void update(Graphics g)
{
paint(g);
}
Spara - kompilera - provkör…
265338508
© Ove Lundgren
25
Kap 7: Sid 26
Metoder som returnerar värde
Vi ska experimentera lite med egendefinierade icke-void-metoder (funktioner)
Övning: Kvadrattabell
Detta är en applet som skriver ut en kvadrattabell ( x2 )på talen 1 – 10
(Påminner mycket om appleten som skrev ut kvadratrötter…)
import java.applet.*;
import java.awt.*;
public class KvadratTabell extends Applet
{
public void paint(Graphics g)
{
g.drawString("x" , 50, 50);
g.drawString( "Kvadraten på x" , 100,50);
g.drawLine(50,55,200,55);
for(int x = 1 ; x <= 10; x++)
{
g.drawString(x + "" , 50 , 50 + 20 * x );
g.drawString( x * x + "" , 100, 50 + 20 * x );
}
}
}
Skriv in och testa! Spara KvadratTabell.java i mappen X\java\KvadratTabell
I klassen Math finns en funktion som beräknar kvadratroten ur ett tal (Math.sqrt)
Det finns däremot ingen funktion som beräknar kvadraten på ett tal. Låt oss skriva en egen sådan metod och
utnyttja den i appleten ovan!
Ändra ovanstående kod till:
import java.applet.*;
import java.awt.*;
public class KvadratTabell extends Applet
{
private int kvadrat(int i)
{
Här deklareras
return i * i ;
funktionen
}
public void paint(Graphics g)
{
g.drawString("x" , 50, 50);
g.drawString( "Kvadraten på x" , 100,50);
g.drawLine(50,55,200,55);
for(int x = 1 ; x <= 10; x++)
{
g.drawString(x + "" , 50 , 50 + 20 * x );
g.drawString( this.kvadrat(x) + "" , 100, 50 + 20 * x );
}
}
Här sker anropet
}
Här har vi deklarerat en egen private funktion i appleten med namnet kvadrat.
Metoden tar ett heltal som parameter och lämnar ett heltalsvärde.
Metoden anropas med heltalsargumentet x
265338508
© Ove Lundgren
26
Kap 7: Sid 27
Det är vanligt att man på detta sätt skriver egna metoder/funktioner.
Antag t ex att samma beräkning ska utföras många gånger i ett program. Då är det bekvämt att lägga
beräkningarna i en funktion som sedan anropas varje gång beräkningen behöver utföras.
Övning: En värdetabell
Här är en variant. Deklarera funktionen f(x) = 0,5x2 + x  2
Deklarera alltså funktionen double f(double x) som returnerar ovanstående funktionsvärde.
Gör en värdetabell som visar funktionsvärden i intevallet  2  x  2 i steg om 0,25
Använd en while-loop.
Försök att skriva appleten på egen hand. Kika nedan om du får problem.
import java.applet.*;
import java.awt.*;
public class VardeTabell extends Applet
{
double x, xstart, xslut, steg;
int rad;
double f(double a)
{
return 0.5 * a * a + a - 2 ;
}
public void init()
{
xstart = -2.0; xslut = 2.0; steg = 0.25;
rad = 70; // för radmatning i appeten
}
public void paint(Graphics g)
{
g.drawString("x" , 50, 50);
g.drawString( "f(x)" , 100,50);
g.drawLine(50,55,200,55);
x = xstart;
while(x < xslut + steg/2)
{
g.drawString(x + "" , 50 , rad );
g.drawString( this.f(x) + "" , 100, rad );
rad = rad + 20;
x = x + steg; // stega fram sist i while-loopen
}
}
}
Spara VardeTabell.java i mappen X\java\VardeTabell
Visa i en applet som är 400 x 400 pixels
265338508
© Ove Lundgren
27
Kap 7: Sid 28
Övning: En funktionskurva
Ovanstående program kan du använda som utgångspunkt i ett program som ritar en funktionskurva.
Vi behöver då ”översätta” x- och f(x)-värden till punkter på skärmen.
Vi inför heltalsvariablerna ox och oy som är koordinater för den punkt på appletytan där origo ska ligga.
Vidare införs heltalsvariabeln skala som anger hur många pixels det ska vara mellan två heltal på x- respektive
y-axeln. Dessutom behöver vi heltalsvariabler som används när vi ska rita kurvan. Vi kallar dem a1 och b1
(a1,b1)
(ox,oy)
skala
En punkt (x, f(x)) på kurvan motsvaras av punkten (a1, b1) på appletytan.
Om exempelvis x = 2 så får vi a1 så här: a1 = ox + 2 * skala
Allmänt: a1 = ox + x * skala
Eftersom a1 är ett heltal och det ingår ett flyttal (x) i vänsterledet måste vi dessutom göra en ”cast”.
Javasatsen blir: a1 = ox + (int)(x*skala);
På motsvarande sätt får vi y-koordinaten: b1 = oy – (int)( f(x) * skala);
Minusteckent kommer sig av att y (tvärtemot i matematiken) växer ”nedåt” i datagrafiska sammanhang.
När vi ritar kurvan använder vi drawLine()-metoden, så kurvan kommer att byggas upp av korta sträckor.
Vi inför därför även heltalskoordinaterna a2 och b2 så att vi kan hålla reda på två punkter åt gången.
Skriv appleten Kurva. Du får hjälp med det programavsnitt som ritar kurvan:
x = xstart;
a1 = ox + (int)(x*skala);
// Den första punktens x-koordinat på appleten
b1 = oy - (int)(f(x)*skala); // Den första punktens y-koordinat på appleten
x = x + steg; // Nästa x-värde ger ny punkt
while(x < xslut + steg/2)
{
a2 = ox + (int)(x*skala);
// Nya punktens x-koordinat på appleten
b2 = oy - (int)(f(x)*skala); // Nya punktens y-koordinat på appleten
g.drawLine(a1,b1,a2,b2); // Ritar sträckan från ”gammal” till ”ny” punkt
a1=a2; b1=b2; // Den ”nya” punkten blir ny ”gammal” punkt
x = x + steg; // Stega fram till nästa x-värde sist i while-loopen
}
Spara Kurva.java i mappen X\java\Kurva





Gör så att koordinataxlar (och kanske skalstreck) visas!
Byt till någon annan funktion. Testa trigonometriska och exponentiella funktioner.
Om kurvan blir ”kantig” får man ge variabeln steg ett mindre värde.
Genom att ändra variabeln skala får man olika storlek på kurvan.
Alternativa värden på xstart och xslut visar kurvan i andra intervall.
265338508
© Ove Lundgren
28
Kap 7: Sid 29
Egna klassmetoder
En klassmetod (ibland kallad ”statisk” metod) kan användas utan att man först behöver skapa ett objekt.
(Motsvarande för klassvariabler)
Övning: Klassmetoder
I kapitel 2 (avsnittet ”Klassmetoder och klassvariabler”) fanns en övning där du skulle skriva in följande kod
public class Matte
{
public static int sqr(int x)
{
return x*x;
}
public static final double pi = 3.14159;
}
Här deklarerade vi den statiska metoden sqr(int x) som (också) beräknade kvadraten på ett heltal.
Dessutom deklarerade vi klassvariabeln pi. Denna var dessutom final vilket betydde att den inte kunde
ändras (dvs pi är en konstant)
Testa metoden sqr() i din applet Kvadrattabell:
Kopiera filen Matte.class till mappen där du har appleten KvadratTabell
(Om du inte har filen: Skriv in koden ovan, spara och kompilera…)
I appleten KvadratTabell: Ersätt metoden this.kvadrat(x) med Matte.sqr(x).
Spara – kompilera –provkör.
Klassen Matte fungerar på samma sätt som JDK-klassen Math
Andra klasser kan givetvis använda metoden i Matte – dock under en förutsättning att de ligger sparade i
samma mapp!
Om du vill komma åt Matte från andra klasser måste den vara sparad i en mapp som ingår i classpath-listan
265338508
© Ove Lundgren
29
Kap 7: Sid 30
Övning: Metod som omvandlar sträng blir flyttal
Om du använder Java 1.1:
Skriv en metod, toFlyttal(String s) , som tar en sträng som argument och som returnerar motsvarande
flyttal. Metoden ska vara publik och statisk och ligga i klassen Matte.
Exempel: Vid anropet
double d = Matte.toFlyttal(”17.67”)
ska d få värdet 17.67
Utnyttja
Double.valueOf(s.trim().replace(',','.')).doubleValue();
Testa din metod i appleten Cirkel:
radie = Matte.toFlyttal( inruta.getText() );
Övning: Max3
Klassen Math har en funktion, max, som returnerar det största av de två tal som anges som argument.
Skriv en metod, max3, som returnerar det största av de tre heltal som anges som argument.
Metoden ska vara publik och statisk ligga i klassen Matte.
Exempel:
Vid anropet
int t = Matte.max3(12,5,18);
ska t får värdet 18
Skriv ett (enkelt konsol-) program, MaxTest.java, för att testa din metod.
Spara programmet i X\java\javagrunder
Hjälp: Algoritm för att ta fram det största talet av tre:
om a > b
om a>c
max = a
annars
max = c
annars
om b > c
max = b
annars
max = c
265338508
© Ove Lundgren
30
Kap 7: Sid 31
Paket
Om du vill att din klass ska tillhöra en package (ett paket), gör du så här:
package mittpaket;
// klassen Matte tillhör paketet mittpaket
public class Matte
{
public static int sqr(int i)
{
// metoddefinition enligt ovan
}
public static double toFlyttal(String s)
{
// metoddefinition enligt ovan
}
public static int max3(int a, int b, int c)
{
// metoddefinition enligt ovan
}
}
Filen sparas med namnet Matte.java och kompileras till Matte.class
Filen Matte.class ska ligga i en mapp med namnet mittpaket.
Den mappen ska i sin tur ligga i JDKs lib-mapp eller i en mapp till vilken du satt CLASSPATH
När du sen ska använda någon av metoderna måste klassen först importeras.
Om t ex en applet använder någon av metoderna måste appletens kod inledas med:
import mittpaket.Matte;
eller
import mittpaket.*;
Den senare varianten innebär att samtliga ”paketanslutna” klasser i mappen mittpaket importeras
(Du kanske har anslutit fler klasser än Matte till paketet…)
265338508
© Ove Lundgren
31