LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
PROGRAMMERING I SPRÅKET JAVA
Innehåll
1. VI BÖRJAR PROGRAMMERA..................................................................................................................................2
INLEDNING......................................................................................................................................................................2
NEDLADDNING OCH INSTALLATION AV JAVA........................................................................................................................2
JAVA MED TEXTPAD........................................................................................................................................................3
JAVADOKUMENTATION......................................................................................................................................................3
FÖRSTA PROGRAMMET I JAVA - UTMATNING.........................................................................................................................4
INMATNING MED STANDARDKLASSER...................................................................................................................................5
String och tecken....................................................................................................................................................5
Heltal och decimaltal..............................................................................................................................................6
AVRUNDNING..................................................................................................................................................................6
HELTALSDIVISION............................................................................................................................................................6
ASCII-KOD...................................................................................................................................................................6
MATEMATISKA FUNKTIONER..............................................................................................................................................7
URVAL OCH LOOPAR........................................................................................................................................................7
FÄLT (ARRAY)................................................................................................................................................................8
2. GRAFISKA METODER.............................................................................................................................................10
FÖNSTER (FRAME).........................................................................................................................................................10
FÄRGER.......................................................................................................................................................................10
LINJE I FÖNSTER............................................................................................................................................................11
TEXT I FÖNSTER............................................................................................................................................................11
INSTANSVARIABLER MED KONSTRUKTOR OCH OBJEKT...........................................................................................................13
INLÄSNING AV VARIABLER...............................................................................................................................................14
3. APPLETS OCH GRAFISKA KOMPONENTER...................................................................................................15
APPLETS......................................................................................................................................................................15
PARAMETRAR I HTML-KODEN.......................................................................................................................................16
GRAFISKA KOMPONENTER...............................................................................................................................................17
Knapp....................................................................................................................................................................17
Textruta.................................................................................................................................................................18
Etikett (label)........................................................................................................................................................19
Egenskaper hos komponenter...............................................................................................................................20
Rullningslist (scrollbar)........................................................................................................................................21
4. MUS- OCH TANGENTHÄNDELSER.....................................................................................................................22
MUSHÄNDELSER............................................................................................................................................................22
OVERRIDE PÅ UPDATE....................................................................................................................................................23
RITA UTAN PAINT..........................................................................................................................................................25
TANGENTHÄNDELSER......................................................................................................................................................25
5. ANIMERING MED TRÅDAR...................................................................................................................................27
TRÅDAR OCH MULTITASKING...........................................................................................................................................27
MULTIPELT ARV OCH GRÄNSSNITT I JAVA..........................................................................................................................27
KLASSEN THREAD OCH GRÄNSSNITTET RUNNABLE..............................................................................................................27
TVÅ TRÅDAR................................................................................................................................................................28
TRÅDAR I EGEN KLASS....................................................................................................................................................29
6. KLASSER I EGNA FILER.........................................................................................................................................32
EGEN KLASSFIL.............................................................................................................................................................32
/home/micko/Skrivbord/java_lektioner.doc
1
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
1. Vi börjar programmera
Inledning
Denna kurs i Java-programmering bygger på goda kunskaper i språket C++ och på att begrepp
som variabler, urval, loopar, objekt etc. är kända. Kan man C++ är det dock relativt enkelt att
lärar sig Java, eftersom Java till härstammar ifrån och till stor del har samma syntax som C++.
Språket Java skapades 1991 av den kanadensisk-amerikanske programmeraren James Gosling
vid dataföretaget Sun Microsystem och blev allmänt tillgängligt 1995. Ursprungligen var Java
tänkt som ett språk för konsumentartiklar (typ tvättmaskiner), men kom i början främst att
användas för bla grafiska effekter med s k applets på Internet. Java har emellertid nu slagit
igenom stort och i viss mån ersatt traditionella språk som C++. Java har många fördelar:
•
Syntaxen är i stort sett identisk med C++. Java är därför relativt enkelt att lära sig för den
som redan kan C eller C++.
•
Det är plattformsoberoende, d v s ett program kan köras i olika operativsystem (Windows
2000, Unix etc.) utan att ändras.
•
Det innehåller grafiska verktyg såsom knappar och textrutor (som VB) även om
programmeringen görs i en texteditor.
•
Det stödjer s k trådar (threads). Exempelvis kan det rita upp en bild samtidigt som det
gör en inläsning.
•
Det kan användas på Internet för att skapa dynamiska funktioner på webbsidor. Detta
görs med javaapplets.
•
Det saknar pekare, vilket innebär att ett program i Java ofta är enklare att förstå än i C++.
Java har också några nackdelar:
•
Det är ett s k interpreterande (d v s översätter kod vid varje exekvering) språk och därför
långsammare än t ex C++. Detta kompenseras dock av att dagens datorer är så pass
snabba att detta ofta inte är något hinder.
•
Det är ett innehållsrikt språk med väldigt många färdiga standardklasser (bl a för grafik)
som kan vara svåra att få grepp om. Man behöver dock inte lära sig allt på en gång.
I denna javakurs berörs främst syntax och begrepp som skiljer sig från C++, som tas upp i
kursdokumentet http://hem.passagen.se/anderskristerandersson/data/Cplus_lektioner.doc.
Nedladdning och installation av Java
En av fördelarna med Java är att utvecklingsmiljön JDK (Java Development Kit, som bl a
innehåller kompilatorn) är gratis. Programmet (52 MB) j2sdk-1_4_2_07-windows-i586-p.exe
laddas ner från företaget Suns hemsida http://java.sun.com/j2se/1.4.2/download.html till din
dator. När programmet installeras skapas mappen c:/ j2sdk1.4.2_07, där programmet packas
upp. Javaprogrammen utvecklade med JDK och körs sedan i konsollmiljö, d v s programmen
skrivs i en textredigerare typ Anteckningar och de kompileras och exekveras i MS-DOS via
Kommandotolken i Tillbehör. I mappen c:/ j2sdk1.4.2_07/bin finns bl a filen javac.exe, som
använs för att kompilera javaprogram. Väljer vi att spara våra javaprogram i en annan mapp än
mappen bin ovan, vilket är det vanligaste, måste sökvägen anges till bin-mappen så att filen
/home/micko/Skrivbord/java_lektioner.doc
2
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
javac.exe hittas. Detta är krångligt. För att slippa
ange sökvägen kan vi istället lägga in en sökväg
(path) till mappen bin via
Kontrollpanelen/System/Avancerat/Miljövariabler. Markera Path i den undre rutan och
klicka på knappen Redigera. Skriv där in sökvägen C:\j2sdk1.4.2_07\bin, enligt urklippet intill.
Javaprogram kan nu kompileras och köras (exekveras) via kommandotolken.
Java med TextPad
För att slippa skriva javaprogrammen i Anteckningar och kompilera och exekvera i DOS-miljön
skall vi använda oss av editeringsprogrammet TextPad. Programmet (2Mb) laddas ner från
http://www.download.com. Installera programmet och öppna det sedan via Start/Alla program.
Programmet TextPad är en mer avancerad editor än Anteckningar, bl a görs automatisk
indentering och färgning av texten. Dessutom kan javaprogrammen kompileras och köras i
TextPad, utan att sökvägen till bin-mappen i Miljövariabel behöver anges (som i förra stycket).
Programmet kompileras och körs via menyvalet Tools/Compile Java (Ctrl+1) respektive
Tools/Run Java Application (Ctrl+2).
Javadokumentation
Java är ett stort språk med väldigt många standardklasser och metoder. Detta finns samlat i en
dokumentation som kan laddas ner som ett zippat dokument (30 MB) från Suns hemsida
http://java.sun.com/j2se/1.4.2/download.html. Uppackat blir dokumen knappt 200 MB stort.
Dokumentet finns även uppackat i j:/Anders_A/java/javadokumentation/index.html.
/home/micko/Skrivbord/java_lektioner.doc
3
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Första programmet i Java - utmatning
Skriv in följande program i TextPad:
class test1{
public static void main(String args[]){
System.out.println("Det funkar i textpad!");
System.out.println("Deta är andra raden");
System.out.print("Tredje raden");
System.out.print("Fjärde raden");
}
}
//Klamrar på samma rad (ej som i C++)
//main-metoden börjar
//Ger utskrift
//println, ny rad efter utskrift
//print, ej ny rad efter utskrift
//main-metoden slutar
Programmets enda klass heter test1, som kan ses som programmets namn. Källkodfilen skall ha
samma namn som programmet. Spara därför programmet som test1.java i mappen java, där du i
fortsättningen sparar alla dina javaprogram. Filslutet .java anger att det är en källkodfil för ett
javaprogram. Kompilera nu programmet till bytekod (andra program kompilerar direkt till
maskinkod). Då skapas klassfilen test1.class, som är plattformsoberoende. När klassfilen sedan
körs med en javatolk interpreteras den till maskinkod. Ordet public anger att main-metoden
(som i C++) är åtkomlig utifrån klassen (programmet) test1, vilket den måste vara för att den
skall kunna anropas av av interpretatorn. Ordet static anger att main-metoden är en s k
klassmetod (eller statisk metod), d v s en metod som inte hör till ett visst objekt. Parametern
String args[] i main-metoden skall alltid vara med för att main-metoden skall kunna anropas
med en parameter, vilket dock sällan görs. Följande program illustrerar variabeldeklaration och
addition. Observera likheterna med C++:
class test3{
public static void main(String args[]){
int a,b=5;
double c=3.33;
a=7;
System.out.println("Summan är " + (a+b) +" och decimaltalet " + c);
}
}
Utelämnas parentesen runt additionen (a+b) i utskriften blir värdet 75.
/home/micko/Skrivbord/java_lektioner.doc
4
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Inmatning med standardklasser
Som du såg i förra exemplen är utskrift i textfönstret i Java relativt enkelt. Inläsning från
tangentbordet är krångligare. Främsta skälet till detta är att Java oftast använder grafiska
gränssnitt och därför saknar bra standardklasser för konsollprogrammering.
String och tecken
Följande program läser in och skriver ut två textsträngar:
import java.io.*; //Standardpaketet java.io.* innehåller metoder för in- och utmatning.
class test3{
public static void main(String args[]) throws IOException{
//Tar hand om fel i readLine()
String fnamn, enamn;
//Klassen String används (jämför med C++)
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));//krångligt
System.out.print("Ange ett förnamn: ");
fnamn=in.readLine();
//Förnamnet läses in
System.out.print("Ange ett efternamn: ");
enamn=in.readLine();
//Efternamnet läses in
System.out.println("Du matade in namnet " + fnamn + " " + enamn);
}
}
Vad den krångliga raden som skapar (objekt-) strömmen in för inläsning egentligen innebär bryr
vi oss inte om. Enskilda tecken (char) plockas enklast ur en inläst string:
System.out.print("Ange en tecken: ");
String s=in.readLine();
System.out.println("Du matade in tecknet " + s.charAt(0));
//Ger strängens första tecken
String-metoden s.charAt(n) plockar ut n:te tecknet ur strängen s. Följande metoder finns för
hantering av strängar, d v s metoder i klassen String:
str.length()
str.charAt(n)
str.substring(n)
str.substring(n,m)
str.compareTo(str2)
str.equals(str2)
str.equalsIgnoreCase(str2)
str.startsWith(str2)
str.startsWith(str2,n)
str.endsWith(str2)
str.indexOf(c)
str.indexOf(c,n)
str.lastIndexOf(c)
str.lastIndexOf(c,n)
str.indexOf(str2)
str.indexOf(str2,n)
str.lastIndexOf(str2)
str.lastIndexOf(str2,n)
str.trim()
str.replace(c1,c2)
str.toUpperCase()
str.toLowerCase()
String.valueOf(x)
/home/micko/Skrivbord/java_lektioner.doc
//ger antalet tecken i str
//ger tecknet i position n
//ger den delsträng som börjar i position n
//ger den delsträng som börjar i position n och slutar i m-1
//ger 0 om str = str2 , <0 om str kommer före str2 annars >0
//true om str och str2 är lika, annars false
//samma som ovan, men skiljer inte på stora och små bokstäver
//true om str inleds med strängen str2, annars false
//true om strängen str2 börjar i position n i str, annars false
//true om str avslutas med strängen str2, annars false
//ger första positionen om tecknet c finns i strängen str, annars -1
//letar från position n efter första platsen för tecknet c
//ger sista positionen om tecknet c finns i strängen str
//letar från position n efter sista platsen för tecknet c
//ger första positionen för delsträngen str2 i str
//letar från position n efter första platsen för strängen str2
//ger sista positionen om delsträngen str2 finns i strängen str
//letar från position n efter sista platsen för delsträngen str2
//returnerar str utan inledande och avslutande blanktecken
//ersätter alla tecken c1 med tecken c2 (å, ä och ö går ej att ersätta)
//ändrar till enbart stora bokstäver
//ändrar till enbart små bokstäver
//omvandlar x till en sträng (x är enkel taltyp: int , double osv)
5
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Heltal och decimaltal
All inläsning görs som strängar och omvandlas sedan till t ex integer eller double. Följande
program läser in och skriver ut hel- och decimaltal:
import java.io.*;
class test3{
public static void main(String args[]) throws IOException{
int i;
double d;
String s;
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Ange ett heltal: ");
s=in.readLine();
i=Integer.parseInt(s);
//Omvandlar sträng till heltal
System.out.println("Du matade in heltalet " + i);
System.out.print("Ange ett decimaltal: ");
s=in.readLine();
d=Double.parseDouble(s);
//Omvandlar sträng till decimaltal
System.out.println("Du matade in decimaltalet " + d);
}
}
Metoderna parseInt(s) och parseDouble(s) tillhör klasserna Integer respektive Double. Inläsning
till heltal direkt kan göras med följande sats:
int antal=Integer.parseInt(in.readLine());
Avrundning
Även avrundning är ganska krånkligt i Java. Följande program avrundar till tre decimaler:
import java.io.*;
import java.text.*;
//Klassen NumberFormat finns i detta paket
class test3{
public static void main(String args[]) throws IOException{
double d=3.823456;
NumberFormat r = NumberFormat.getInstance();
//Instans av redigerare r
r.setMaximumFractionDigits(4);
//Formaterar utrskrift till högst 4 decimaler
System.out.println("Med fyra decimaler: " + r.format(d) );
//Omvandlar decimaltalet d till
//en sträng med 4 decimaler
}
}
Heltalsdivision
Fungerar på samma sätt som i C++, d v s är båda termerna heltal blir kvoten ett heltal. Problemet
löses med casting, d v s omtypning.
ASCII-kod
ASCII-koden erhålls i Java liksom i C++ genom omtypning av ett tecken:
String s="Anders";
System.out.println("ASCII-koden för femte tecknet: " + (int)s.charAt(4));
Tecknet för motsvarande ASCII-kod fås på omvänt sätt:
int i=232;
System.out.println("Tecknet är: " + (char)i);
/home/micko/Skrivbord/java_lektioner.doc
6
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Matematiska funktioner
Klassen Math i Java har några metoder (funktioner) som C++ saknar. Följande program visar
vilka:
import java.io.*;
import java.lang.*;
//Innehåller klassen Math. Paketet behöver inte importeras, finns alltid med.
class test3{
public static void main(String args[]) throws IOException{
System.out.println(Math.PI);
//Ger pi med 15 decimaler
System.out.println(Math.pow(5,2));
//25.0
System.out.println(Math.sqrt(49));
//7.0
System.out.println(Math.random());
//Slumptal mellan 0-1. ’Blandas’ automatiskt.
System.out.println(Math.max(5,8));
//8
System.out.println(Math.min(5,8));
//5
System.out.println(Math.round(5.5)); //6
}
}
Observera att klassnamnet Math måste föregå metodanropet. Nedan följer en sammanställning
av de matematiska metoderna:
Math.abs(a)
Math.max(a,b)
Math.min(a,b)
Math.PI
Math.E
Math.exp(x)
Math.log(x)
Math.sqrt(x)
Math.ceil(x)
Math.floor(x)
Math.pow(x,y)
Math.round(x)
Math.random()
Math.sin(x)
Math.cos(x)
Math.tan(x)
Math.asin(x)
Math.acos(x)
Math.atan(x)
//absolutvärdet eller beloppet av talet a
//ger det största av talen a och b
//ger det minsta av talen a och b
//talet π
//talet e = 2,7…
//ger ex
//ger naturliga logaritmen av x
//ger kvadratroten av x
//rundar av uppåt till heltal
//rundar av nedåt till heltal
//ger xy
//avrundar till heltal av typ long
//ger slumptal mellan 0 och 1
//x anges i enheten radianer
//arcsin(x), motsvarar miniräknarens sin-1. Returnerar ett värde i radianer.
Urval och loopar
Urval med if och case, samt looparna for och while har samma syntax i Java som i C++.
/home/micko/Skrivbord/java_lektioner.doc
7
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Fält (array)
I Java är fält dynamiska så till vida att storleken kan anges vid exekveringen (jämför med pekare
i C++). Dessutom innehållet klassen Arrays metoder för bl a sortering, sökning och jämförelse
av fält. Följande program illustrerar hur en vektor fylls med hela slumptal mellan , sorteras i
stigande ordning, samt slutligen skrivs ut igen:
import java.io.*;
import java.lang.Math;
import java.util.Arrays; //Importerar klassen Arrays för att kunna sortera fältet nedan
class test3{
public static void main(String args[]) throws IOException{
int [] a=new int[10];
//Deklarerar fältet med new (påminner om pekare i C++)
for (int i=0;i<10;i++)
a[i]=(int)(Math.random()*5)+1; //Fyller fältet med slumptal mellan 1 och 5
Arrays.sort(a);
//Sorterar fältet i stigande ordning
for (int i=0;i<10;i++)
System.out.println(a[i]);
}
}
Sortering av strängar görs på liknande sätt. Sorteringen fungerar dock endast om hela det
deklarerade fältet är fyllt. Deklarationen av fältet görs därför efter inläsningen av fältets storlek:
System.out.print("Ange hur många namn som skall matas in: ");
int antal=Integer.parseInt(in.readLine());
//Omvandling till heltal görs direkt
String [] a=new String[antal];
Klassen Arrays innehåller bl a följande användbara metoder:
a.length
Arrays.equals(a,b)
Arrays.fill(a,b)
Arrays.fill(a,m,n,b)
Arrays.sort(a)
Arrays.sort(a,m,n)
binarySearch(a,b)
//Ger antalet komponenter i a (tillhör ej klassen Arrays)
//Returnerar true om fälten a och b är lika (komponenter och antal)
//Ger alla komponenterna i fältet a värdet b
//Returnerar komponenterna nr m till n-1 I fältet a värdet b
//Sorterar komponenterna i a i stigande ordning
//Sorterar komponenterna nr m till n-1 i a i stigande ordning
//Söker efter variabeln b i fältet a. Returnerar b:s index om den finns, annars -1
Övning 1.1:
Skriv ett program som skriver ut följande textsträng på skärmen:
Detta är kul. Detta är kul. Detta är kul.
Övning 1.2:
Skriv ett program som läser in ett namn och sedan skriver ut det på skärmen på tre rader:
Vad heter du: Anders Andersson
Var bor du? Skoghall
Du heter Anders Andersson och bor i Skoghall
Du heter Anders Andersson och bor i Skoghall
Du heter Anders Andersson och bor i Skoghall
Övning 1.3:
Skriv ett program som beräknar resten vid division mellan två heltal. Programmet skall ha
följande utskrift:
Ange taljare: 16
Ange namnare: 6
Rest vid division: 4
Heltalsdivision: 2
Kvot med alla decimaler: 2.6666666666666665
/home/micko/Skrivbord/java_lektioner.doc
8
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Kvot med tre decimaler: 2.667
Övning1.4:
Skriv ett program som läser in en textrad och antal gånger som den skall skrivas ut och som
sedan skriver ut texten, med följande utskrift:
Ange en text: Jag gillar Java
Antal gånget texten skall skrivas ut: 4
1: Jag gillar Java
2: Jag gillar Java
3: Jag gillar Java
4: Jag gillar Java
Övning 1.5:
Skriv ett program som läser in en sträng och som sedan skriver ut antal tecken, texten med
versaler, ersätter alla mellanslag (’ ’) med bokstaven ’a’, samt skriver ut texten baklänges, enligt
följande exempel:
Ange en text: Jag gillar Java
Antal tecken: 15
JAG GILLAR JAVA
JagagillaraJava
avaJ rallig gaJ
Övning 1.6:
Skriv ett program som läser in två namn och som sedan skriver ut dem i bokstavsordning med en
if-sats, med följande utskrifter:
Ange första namnet: kalle
Ange andra namnet: anders
I bokstavsordning: anders kalle
Övning 1.7:
Skriv ett program som läser in namn och som sedan sorterar dem och skriver ut dem i
bokstavsording, med följande utskrifter:
Hur många namn skall läsas in: 4
Skriv in namn 1: kalle
Skriv in namn 2: eva
Skriv in namn 3: anna
Skriv in namn 4: bengt
I bokstavsordning: anna, bengt, eva, kalle,
Övning 1.8:
Skriv ett program som beräknar hypoteunsan med Pythagoras sats avrundad till ett heltal, med
följande utskrift:
Ange ena kateten: 12
Ange andra kateten: 19
Hypotenusan avrundad till heltal: 22
Övning 1.9:
1 1 1 1
1
1
+ + + +
+ ... +
för olika värden på N. Vad blir summan om man
2 4 8 16 32
N
tar med många termer?
Beräkna summan
/home/micko/Skrivbord/java_lektioner.doc
9
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
2. Grafiska metoder
Hittills har programmen körts i konsollfönstret. Java har dock stora grafiska möjligheter. Vi skall
inledningsvis skapa ett fönster. Sedan fyller vi detta med linjer, polygoner och texter via grafiska
metoder. Därefter lär vi oss att hantera grafiska komponenter som knappar och textrutor.
Fönster (frame)
I Java API (Application Programming Interface) finns paketet java.awt (Abstract Window
Toolkit), som innehåller många klasser för hantering av grafik, text, färger och komponenter som
knappar och textrutor. Ur detta paket behöver vi strax klasserna Graphics, Font och Color. Vi
importerar dem därför med följande satser:
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
Eller kortare:
import java.awt.*;
Paketet java.awt innehåller en klass Frame, som automatiskt öppnar ett fönster när man skapar
ett objekt av klassen. Eftersom vårt program skall ha samma egenskaper som klassen Frame,
måste det ärva Frame:s egenskaper. Följande program skapar ett fönster:
import java.awt.*;
class test4 extends Frame{
//extends anger att klassen test4 ärver av Frame
test4() {
setBackground(Color.yellow);
setSize(400,150);
}
//Konstruktor för klassen test4
//Anger fönstrets bakgrundsfärg
//Anger fönstrets storlek
public static void main(String args[]) {
test4 d=new test4();
d.setVisible(true);
}
//Main-funktionen
//Skapar objektet d av klassen test4 (fönstret skapas)
//Fönstret görs synligt med Frame-metoden setVisible
}
Observera att fönstret inte kan stängas med systemknappen. Stäng istället via konsollfönstret.
Färger
Färgen kan även anges mer fritt på RGB-format. Ett ”färgobjekt” av klassen Color måste då först
skapas:
Color c=new Color(200,0,0);
setBackground(c);
//Skapar objektet c av klassen Color med RGB-färgen (200,0,0) d v s röd
Följande färger finns fördefinierade (anges med Color.):
black, blue, cyan, gray, darkGray, lightGray, green, magenta, orange, pink, red, white, yellow
Övning 2.1:
Kopiera och modifiera ovanstående programexempel så att bakgrunden får en slumpmässig färg
varje gång fönstret öppnas.
Övning 2.2:
Modifiera föregående övning ytterligar så att även fönstrets storlek öppnas med slumpmässig
storlek.
/home/micko/Skrivbord/java_lektioner.doc
10
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Linje i fönster
Klassen Graphics innehåller grafiska metoder som bl a ritar streck och polygoner, samt text.
Följande program bygger vidare på förra exemplet och ritar en linje i fönstret:
import java.awt.*;
class test4 extends Frame{
test4() {
setBackground(Color.yellow);
setSize(400,400);
}
public void paint(Graphics g){
//Metoden paint anropas automatiskt när fönstret skapas
g.setColor(Color.red);
//Grafikfärg
g.drawLine(100,100,300,300); //Linjen ritas mellan koordinaterna (100, 100) och (300, 300)
}
public static void main(String args[]) {
test4 d=new test4();
d.setVisible(true);
}
}
Observera att metoden paint anropas automatiskt när fönstret skapas eller ändras.
Övning 2.3:
Modifiera ovanstående exempel så att ett slumpmässigt antal (1-10) linjer ritas ut i fönstret med
slumpmässiga färger. Fönstrets bakgrundsfärg skall vara grå.
Text i fönster
Följande program ritar en linje och lägger in text:
import java.awt.*;
class test4 extends Frame{
test4() {
setBackground(Color.yellow);
setSize(400,400);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(100,100,300,300);
g.drawString("Det funkar!",200,200); //Skriver ut en textsträng o koordinaten (200, 200)
}
public static void main(String args[]) {
test4 d=new test4();
d.setVisible(true);
}
}
Texten som skriv ut är oformaterad, men kan formateras med klassen Font. Följande rad visar ett
exempel på hur texten kan formateras med Font-variabeln f (objektet f av klassen Font):
Font f=new Font("Arial",Font.BOLD,24);
//Typsnitt (ett fåtal stöds), stil, storlek
För stilen finns även Font.ITALIC och Font.PLAIN. Kombinationer av olika stilar anges med:
Font.BOLD+Font.ITALIC
Följande programexempel illustrerar hur det fungerar genom att modifiera föregående exempel:
/home/micko/Skrivbord/java_lektioner.doc
11
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
import java.awt.*;
class test4 extends Frame{
Font f=new Font("Arial",Font.BOLD,24);
test4() {
setBackground(Color.yellow);
setSize(400,400);
}
//Objektet f av klassen Font deklareras
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(100,100,300,300);
g.setColor(Color.green);
//Grafikfärgen ändras för texten
g.setFont(f);
//Den valda fonten sätts
g.drawString("Det funkar!",200,200);
}
public static void main(String args[]) {
test4 d=new test4();
d.setVisible(true);
}
}
Följande metoder finns för klassen Graphics:
drawLine(x1,y1,x2,y2);
drawRect(x,y,b,h);
fillRect(x,y,b,h);
drawRoundRect(x,y,b,h,m,n)
fillRoundRect(x,y,b,h,m,n)
draw3DRect(x,y,b,h,upp)
fill3DRect(x,y,b,h,upp)
drawOval(x,y,b,h)
fillOval(x,y,b,h)
drawArc(x,y,b,h,s,l)
drawPolygon(xp,yp,n)
fillPolygon(xp,yp,n)
//Ritar en linje mellan koordinaterna (x1, y1) och (x2, y2)
//Ritar en rektangel med övre vänstra hörnet i (x, y), bredd b och höjd h
//Fyller rektangeln
//Rektangel med rundade hörn, där m och n anger rundning
//Fyller rundad rektangel
//Tredimensionell rektangel, upp är tru elle false
//Fyller en tredimensionell rektangel
//Ritar en oval
//Fyller en oval
//Ritar en båge, där s är startpunkt ock I slitpunkt I grader
//Ritar en polygon. Koordinaterna (n st) ligger i fälten xp och yp
//Fyller polygonen
Övning 2.4:
Modifiera föregående övning så att fönstret fylls med 100 slumpmässigt utritade och färglagda
cirklar med diametern 100 pixlar. Fönstrets bakgrundsfärg skall vara grå.
*Övning 2.5:
Modifiera föregående övning så att fönstret fylls med 10 slumpmässigt utritade och färglagda
lika stora polygoner. Välj själv polygonens antal hörn och utseende i programkoden. Fönstrets
bakgrundsfärg skall vara grå.
/home/micko/Skrivbord/java_lektioner.doc
12
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Instansvariabler med konstruktor och objekt
I förra exemplet var linjens ändpunkter i paint-metoden fixerade. Vill kunna variera
ändpunkternas koordinater är det lämpligt att tilldela dem i main-metoden. Eftersom Java bygger
på klasser måste klassen test4 först få instansvariabler (samma som datamedlemmar i C++) för
ändpunkterna (x1, y1) och (x2, y2), som kan tilldelas antingen via en konstruktor eller via ett
objekt. Nedan visas båda varianterna. Först med konstruktor:
import java.awt.*;
class test4 extends Frame{
Font f=new Font("Arial",Font.BOLD,24);
int x1,y1,x2,y2;
//Instansvariabler (datamedlemmar)
test4(int a1,int b1,int a2,int b2) {
//Variablerna tilldelas via konstruktorn
x1=a1; y1=b1; x2=a2; y2=b2;
setBackground(Color.yellow);
setSize(400,400);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(x1,y1,x2,y2);
//Instansvariablerna används i metoden paint
g.setColor(Color.green);
g.setFont(f);
g.drawString("Det funkar!",200,200);
}
public static void main(String args[]) {
int x=0, y=50, v=200, w=250;
test4 d=new test4(x,y,v,w);
//Konstruktorn anropas
d.setVisible(true);
}
}
Följande exempel gör samma sak, men här tilldelas instansvariablerna via objektet d:
import java.awt.*;
class test4 extends Frame{
Font f=new Font("Arial",Font.BOLD,24);
int x1,y1,x2,y2;
test4() {
setBackground(Color.yellow);
setSize(400,400);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(x1,y1,x2,y2);
g.setColor(Color.green);
g.setFont(f);
g.drawString("Det funkar!",200,200);
}
public static void main(String args[]) {
test4 d=new test4();
d.x1=100;
//Instansvariablerna tilldelas via objektet d
d.y1=50;
d.x2=200;
d.y2=350;
d.setVisible(true);
}
}
/home/micko/Skrivbord/java_lektioner.doc
13
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Inläsning av variabler
Följande exempel visar hur koordinaterna läses in i main-metoden. Observera att inläsning och
omvandling från string- till int-typ görs i en sats:
import java.awt.*;
import java.io.*;
class test4 extends Frame{
Font f=new Font("Arial",Font.BOLD,24);
int x1,y1,x2,y2;
test4() {
setBackground(Color.yellow);
setSize(400,400);
}
//Objektet f av klassen Font deklareras
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(x1,y1,x2,y2);
g.setColor(Color.green);
//Grafikfärgen ändras för texten
g.setFont(f);
//Den valda fonten sätts
g.drawString("Det funkar!",200,200);
}
public static void main(String args[]) throws IOException {
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
test4 d=new test4();
System.out.print("Ange första x-värdet: ");
d.x1=Integer.parseInt(in.readLine());
//Inläsning och omvandling görs i en sats.
System.out.print("Ange första y-värdet: ");
d.y1=Integer.parseInt(in.readLine());
System.out.print("Ange andra x-värdet: ");
d.x2=Integer.parseInt(in.readLine());
System.out.print("Ange andra y-värdet: ");
d.y2=Integer.parseInt(in.readLine());
d.setVisible(true);
}
}
Övning 2.6:
Skriv ett program som frågar efter hur många hörn en polygon skall ha och som sedan läser in xoch y-koordinater och ritar/fyller polygonen. Ledning: Läs in antal hörn och koordinaterna i
main-metoden i en for-loop:
test4 d=new test4();
System.out.print("Ange antal hörn: ");
d.ant_horn=Integer.parseInt(in.readLine());
for (int i=0;i<d.ant_horn;i++)
{
System.out.print("Ange x-värdet: ");
d.xp[i]=Integer.parseInt(in.readLine());
System.out.print("Ange y-värdet: ");
d.yp[i]=Integer.parseInt(in.readLine());
}
Samt deklarera tre instansvariabler i klassen test4:
int [] xp=new int[10];
int [] yp=new int[10];
int ant_horn;
/home/micko/Skrivbord/java_lektioner.doc
//Maximalt tio hörn
//Anger antal hörnpunkter
14
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
3. Applets och grafiska komponenter
Hittills har vi skrivit fristående javaprogram, främst för att lära oss grunderna i språkets syntax.
Ofta används dock javaprogram i samband med webbsidor och då behövs inte JDK:s javatolk för
att köra/interpretera det kompilerade programmet (class-filen), eftersom de vanligaste
webbläsarna kan köra javaprogram – s k javaapplets. En applet (förkortning av applikation) är
alltså ett fristående javaprogram som kan köras av en webbläsare. Detta innebär att
konsollmiljöns inläsningar inte fungerar i applet, där inläsningar istället görs via bl a textrutor
som i Visual Basic. Detta återkommer vi till senare.
Applets
Vi börjar med att göra om exemplet på sidan 12 till en applet:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
//Klassen Applet i paketet applet importeras
//Klassen test4 ärver egenskaperna från klassen Applet
Font f;
//Objektet f av klassen Font deklareras
public void init() {
//Metoden init anropas när test4 skapas, d v s först
f=new Font("Arial",Font.BOLD,24);
setBackground(Color.yellow);
}
public void paint(Graphics g){
//Metoden paint anropas när skärmen ändras
g.setColor(Color.red);
g.drawLine(100,100,300,300);
g.setColor(Color.green);
//Grafikfärgen ändras för texten
g.setFont(f);
//Den valda fonten sätts
g.drawString("Det funkar!",200,200);
}
}
Det finns tre huvudsakliga skillnader mellan ett fristående program och en applet:
1. Istället för från standardklassen Frame ärver klassen test4 sina egenskaper från
standardklassen Applet, som har liknande egenskapre som Frame. Fönstret som klassen
Applet skapar kan dock inte visas fristående utan webbläsaren.
2. En applet saknar en main-metod. Istället är det webbläsaren som skapar första objektet av
klassen test4.
3. Klassen test4 saknar konstruktor. Initieringar görs istället i metoden init. Fönstrets storlek
anges i webbläsaren.
Programmet kompileras som förut till en class-fil, som exekveras av webbläsaren (se nedan).
Appleten kan dock enkelt testköras med programmet AppletViewer via TextPad:s menyval
Tools/Run Java Applet. Under menyvalet Applet i AppletViewer finns några funktioner. I
webbläsaren körs appleten med följande HTML-kod:
<html>
<head>
<title> Min hemsida </title>
</head>
<body>
Detta är min hemsida.
<applet code="test4.class" width=500 height=300>
</body>
</html>
/home/micko/Skrivbord/java_lektioner.doc
15
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Attributet code får filnamnet för appleten, och attributen width och height ger fönstrets storlek.
Spara HTML-koden i programmet Anteckningar med filändelsen .html (eller .htm) och öppna
filen i webbläsaren. Alternativt sparas HTML-koden på motsvarande sätt i TextPad. Webbsidan
kan sedan visas via menyvalet View/In Web Browser.
Parametrar i HTML-koden
Parametrar (variabler) i appleten kan anges i HTML-koden. I följande exempel anges texten som
skall skrivas ut i appleten, samt textens storlek i HTML-koden. Först visas HTML-koden:
<html>
<head>
<!--Kommentar i HTML-->
<title> Min hemsida </title>
</head>
<body>
Detta är min hemsida.
<applet code="test4.class" width=500 height=300>
<param name="t" value="Detta är texten">
<!--parametern t får värdet ”Detta är texten”-->
<param name="storlek" value="80">
<!--parametern storlek får värdet 80-->
</body>
</html>
Javaprogrammet läser in värdet på parametrarna t och storlek från HTML-filen:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
Font f;
String text, textstorlek;
int storlek;
public void init() {
textstorlek=getParameter("storlek"); //Värdet på parametern storlek hämtas till textstorlek
storlek=Integer.parseInt(textstorlek);
f=new Font("Arial",Font.BOLD,storlek);
text=getParameter("t");
//Värdet på parametern t hämtas till variabeln text
setBackground(Color.yellow);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(100,100,300,300);
g.setColor(Color.green);
g.setFont(f);
g.drawString(text,200,200);
}
//Grafikfärgen ändras för texten
//Den valda fonten sätts
//Texten skrivs ut via variabeln text
}
All hantering av grafik läggs alltså i metoden paint.
Övning 3.1:
Skriv och provkör en applet som ritar ut ett antal slumpmässigt placerade fyllda cirklar med
slumpmässig färg. Antalet cirklar och cirklarnas storlek skall anges som parametrar i HTMLkoden.
/home/micko/Skrivbord/java_lektioner.doc
16
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Grafiska komponenter
Kommunikationen med javaprogram sker ofta via grafiska komponenter av samma typ som i
Visual Basic. Java har för detta ett antal standardklasser för grafiska komponenter, såsom t ex
knapp, label (etikett), kryssruta, alternativknapp, listruta, textruta och rullningslist. Samtliga
klasser finns i paketet java.awt.*. Vi kommer nedan att ta upp dessa standardklasser och hur
olika händelser hanteras, t ex knapp- och tangenttryckningar och musklickningar.
Knapp
Knappar skapas av klassen Button. Programmet nedan
innehåller två knappar, som byter till röd respektive grön
färg på bakgrunden:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
public void init() {
setBackground(Color.yellow);
Button knappA=new Button("Röd");
add(knappA);
Button knappB=new Button("Grön");
add(knappB);
}
//Objektet knappA skapas med texter Röd
//Knappen läggs ut i webbfönstret
//Motsvarande för knapp med text Grön
public boolean action(Event evt,Object arg){
String text=(String)arg;
if (evt.target instanceof Button){
if (text.equals("Röd"))
setBackground(Color.red);
if (text.equals("Grön"))
setBackground(Color.green);
}
return true;
}
//action reagerar på en händelse
//arg innehåller knappens (komponentens) text
//evt kollar typ av komponent (klass)
}
Observera att knapparna centreras i fönstret från vänster i den ordning de skapas. Senare kommer
vi att placera ut dem på ett sätt vi själva väljer. Vi modifierar programmet så att en slumpmässig
färg används när knappB aktiveras. Koden för detta läggs lämpligen i en egen metod slumpfarg.
Programmet får då följande utseende:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
public void init() {
setBackground(Color.yellow);
Button knappA=new Button("Röd");
add(knappA);
Button knappB=new Button("Slumpfärg");
add(knappB);
}
public void slumpfarg(){
int r=(int)Math.round(255*Math.random());
int g=(int)Math.round(255*Math.random());
int b=(int)Math.round(255*Math.random());
Color c=new Color(r,g,b);
setBackground(c);
/home/micko/Skrivbord/java_lektioner.doc
17
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
}
public boolean action(Event evt,Object arg){
String text=(String)arg;
if (evt.target instanceof Button){
if (text.equals("Röd"))
setBackground(Color.red);
if (text.equals("Slumpfärg"))
slumpfarg();
}
return true;
}
}
Klassen Button har två konstruktorer för knappen k:
Button k=new Button();
Button k=new Button(”Tryck”);
//Ger en textlös knapp
//Ger knappen texten Tryck
Nedan visas några användbara metoder för textrutan t:
k.setLabel(”Text”);
String texten=k.getLabel();
//Placerar texten Text på knappen
//Returnerar knapptexten till variabeln texten
Textruta
Textrutor skapas av klassen TextField. I programmet nedan färgas bakgrunden av den färg som
matas in i textrutan:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
TextField rutan1;
public void init() {
setBackground(Color.yellow);
Button knappA=new Button("Textfärg");
add(knappA);
Button knappB=new Button("Slumpfärg");
add(knappB);
rutan1=new TextField("Skriv här",10);
add(rutan1);
}
//Objektet rutan1 skapas
//Placerar textrutan I fönstret
public void slumpfarg(){
int r=(int)Math.round(255*Math.random());
int g=(int)Math.round(255*Math.random());
int b=(int)Math.round(255*Math.random());
Color c=new Color(r,g,b);
setBackground(c);
}
public void textfarg(){
if (rutan1.getText().equals("g"))
//Metoden getText() returnerar texten i textrutan
setBackground(Color.green);
if (rutan1.getText().equals("r"))
setBackground(Color.red);
if (rutan1.getText().equals("b"))
setBackground(Color.blue);
if (rutan1.getText().equals("y"))
setBackground(Color.yellow);
}
public boolean action(Event evt,Object arg){
/home/micko/Skrivbord/java_lektioner.doc
18
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
String text=(String)arg;
if (evt.target instanceof Button){
if (text.equals("Textfärg"))
textfarg();
if (text.equals("Slumpfärg"))
slumpfarg();
}
return true;
//Metoden textfärg anropas
}
}
Klassen TextField har några olika konstruktorer för en textruta t:
TextField t=new TextField();
TextField t=new TextField(10);
TextField t=new TextField("Skriv här");
TextField t=new TextField("Skriv här",n);
//Ger ett tomt textfält
//Ger ett textfält med plats för 10 tecken
//Ger ett textfält med texten ”Skriv här”
//Ger ett textfält med texten ”Skriv här” och med n positioner
Nedan visas några användbara metoder för textrutan t:
t.SetColumns(n)
String texten=t.getText();
t.SetText(”Detta står i textrutan”);
t.setEchoChar(’*’);
t.selectAll();
t.select(i,j);
texten=t.getSelectedText();
//Antal teckenpositioner sätts till n
//Textrutans innehåll returneras alltid som typen String
//Tilldelar textrutan en text
//Hemlig text, en ’*’ visas istället för tecknen
//All text markeras
//Tecknen i till j markeras
//Returnerar markerad text
Etikett (label)
Etiketter skapas av klassen Label. I programmet nedan skrivs innehållet i textrutan ut
högerjusterat i en label när knappen aktiveras:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
TextField te;
Label la;
public void init() {
setBackground(Color.yellow);
Button knappA=new Button("Tryck");
add(knappA);
te=new TextField("Skriv här",10);
add(te);
la=new Label("Detta är en label",Label.RIGHT);
add(la);
}
public boolean action(Event evt,Object arg){
String text=(String)arg;
if (evt.target instanceof Button){
if (text.equals("Tryck"))
la.setText(te.getText());
}
return true;
}
//Etiketten la skapas högerjusterad
//Texten i textrutan tilldelas etiketten
}
/home/micko/Skrivbord/java_lektioner.doc
19
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Klassen Label har två konstruktorer för etiketten e:
Label e=new Label(”Text i etikett”);
Label e=new Label(”Text i etikett”,Label.RIGHT);
//Skriver ut texten vänsterjusterad i etikettens textyta
//Skriver ut texten högerjusterad; Label.RIGHT,
//Label.LEFT och Label.CENTER finns
Nedan visas några användbara metoder för etiketten e:
e.setText(”Text”);
String texten=e.getText();
e.setAligment(Label.CENTER);
//Placerar texten Text i etiketten
//Returnerar etiketttexten till variabeln texten
//Centrerar texten
Egenskaper hos komponenter
Komponenternas färg, text, storlek och läge kan påverkas av bl a samma metoder som vi använt
för hela fönstret:
setBackground(c);
setForegrund(c);
setFont(f);
setVisible(true/false);
setSize(bredd, höjd);
setLocation(x,y);
//Påverkar bakgrundsfärg hos text och knapp
//Påverkar textfärg
//Anger textstil och storlek
//Komponenten döljs med false
//Anger komponentens bredd och höjd i pixlar. Görs efter initieringen i t ex paint
//Placerar komponenten med övre vänstra hörnet i koordinaten (x,y) i t ex paint
Nedan visas några exempel på färg- och textändringar för knapp, textruta och etikett:
TextField t = new TextField("Skriv här!",10);
Label e = new Label("Grön:",Label.RIGHT);
Button b = new Button("Tryck");
Font f=new Font("Arial",Font.BOLD,24);
Color c=new Color(200,200,0);
e.setFont(f);
//Etikettens text anges
b.setVisible(false);
//Knappen döljs
e.setForeground(Color.green);
//Etikettens text blir grön
e.setBackground(c);
//Etikettens bakgrund får färgen c
t.setBackground(Color.blue);
//Textrutans bakgrundsfärg blir blå
e.setSize(50,15);
//Etiketten får längden 50 och höjden 15 pixlar
e.setLocation(10,100);
//Lägger etiketten med övre vänstra hörnet i koordinaten (10,100)
Övning 3.2:
Skriv och kör en applet via ett HTML-dokument läser in och
beräknar summan av två decimaltal, enligt urklippet intill.
Ledning: Använd Double.parseDouble(text); för omvandling
från text till double och String.valueOf(x) för omvandling från
typen double till text.
Övning 3.3:
Modifiera föregående applet så att den istället beräknar hypotenusan till till två inmatade kateter.
Övning 3.4:
Skriv ett program där bakgrundsfärgen anges i tre textrutor på
RGB-format (0-255). Följande skall gälla (se även urklipp):
•
Textfärgen på etiketten och i textrutan skall vara röd, grön
respektive blå.
•
Etiketternas bakgrundsfärg skall vara samma som fönstrets
bakgrundsfärg. Texten skall vara 24 p fet.
/home/micko/Skrivbord/java_lektioner.doc
20
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Rullningslist (scrollbar)
Rullningslisten skapas av klassen Scrollbar. I programmet nedan skrivs läget hos rullningslisten
ut i en etikett:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
Label la;
Scrollbar rull;
public void init() {
setBackground(Color.yellow);
rull=new Scrollbar(Scrollbar.HORIZONTAL,50,10,0,110); //Rullningslistens konstruktor
add(rull);
la=new Label("50",Label.RIGHT);
add(la);
}
public boolean handleEvent(Event evt){
//handleEvent hanterar händelser från rullningslist
if (evt.target instanceof Scrollbar)
la.setText(String.valueOf(rull.getValue())); //Läget hos rullningslisten skrivs ut i label
return true;
}
}
Observera att metoden action inte fungerar för rullningslister. Istället används metoden
handleEvent. Klassen Scrollbar har följande konstruktor för rullningslisten r:
Scrollbar r=new Scrollbar(Scrollbar.HORIZONTAL,position,knappbredd,min,max);
Positionen avläses vid knappens vänstra sida (undre sida vid Scrollbar.VERTICAL). Om
exempelvis min=0, max=100 och knappbredd=10 blir maximala positionen 90 när knappen
ligger längst till höger. Nedan visas några användbara metoder för rullningslisten r:
r.getValue();
r.setValue(n);
r.getMaximum()
r.getMinimum()
//Ger position hos rullningslistens knapp som heltal
//Sätter rullningslistens knapp till positionen n (heltal, även negativt)
//Ger maxvärdet
//Ger minvärdet
Övning 3.5:
Skriv ett program med tre
rullningslister, med vilka
bakgrundsfärgen kan justeras (0-255).
Vald färg skrivs ut i respektive etikett
på RGB-form. Etikettfärgen skall
dessutom vara röd, grön och blå, samt
deras bakgrundsfärg samma som
fönstrets bakgrundsfärg, enligt urklippet till höger.
Övning 3.6:
Skriv en applet som fyller en kvadrat med den
övertonade gråskalan i urklippet till höger.
/home/micko/Skrivbord/java_lektioner.doc
21
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
4. Mus- och tangenthändelser
I förra kapitlet hanterades händelser vid knapptryckningar och ändringar hos en rullningslist. I
detta kapitel skall vi ta hand om händelser hos mus och tangenter.
Mushändelser
Följande metoder hanterar händelser hos musen:
mouseDown(Event evt, int x, int y)
mouseUp(Event evt, int x, int y)
mouseMove(Event evt, int x, int y)
mouseDrag(Event evt, int x, int y)
mouseEnter(Event evt, int x, int y)
mouseExit(Event evt, int x, int y)
//Ger markörens koordinat när en musknapp trycks ned
//Ger markörens koordinat när en musknapp släpps upp
//Ger markörens koordinat när musen rör sig
//Samma som föregående, men när en musknapp är nedtryckt
//Ger markörens koordinat när musen kommer in i fönstret
//Ger markörens koordinat när musen lämnar fönstret
Programmet nedan skriver ut markörens koordinat när musknappen trycks ned, släpps upp
respektive när musen rör sig i tre olika etiketter:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
Label l1,l2,l3;
public void init() {
l1=new Label("MouseDown x=000 y=000",Label.LEFT);
add(l1);
l2=new Label("MouseUp x=000 y=000",Label.LEFT);
add(l2);
l3=new Label("MouseMove x=000 y=000",Label.LEFT);
add(l3);
}
public boolean mouseDown(Event evt, int x, int y){
l1.setText("MouseDown x="+String.valueOf(x)+" y="+String.valueOf(y));
return true;
}
public boolean mouseUp(Event evt, int x, int y){
l2.setText("MouseUp x="+String.valueOf(x)+" y="+String.valueOf(y));
return true;
}
public boolean mouseMove(Event evt, int x, int y){
l3.setText("MouseMove x="+String.valueOf(x)+" y="+String.valueOf(y));
return true;
}
}
/home/micko/Skrivbord/java_lektioner.doc
22
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Override på update
Följande program skriver ut markörens koordinat med ritmetoden drawString där musknappen
trycks ned:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
int x1,y1;
//Globala variabler
public void paint(Graphics g){
g.drawString("x="+String.valueOf(x1)+" y="+String.valueOf(y1),x1,y1);
}
public boolean mouseDown(Event evt, int x, int y){
x1=x;
y1=y;
repaint();
//Anropar metoden paint
return true;
}
}
Observera att den gamla koordinaten raderas vid varje ny musklickning. Detta beror på att
metoden repaint även anropar metoden update, som målar över all grafik (dock inte
komponenter som knappar och etiketter) med bakgrundsfärgen. Genom att göra en
omdefiniering av update så att den anropar paint utan att rita om bakgrunden, kommer även de
gamla koordinaterna att visas. Att omdefiniera en metod kallas override. Följande program visar
hur det fungerar:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
int x1=50, y1=50;
//Startkoordinater för paint, som anropas när fönstret skapas
public void paint(Graphics g){
g.drawString("x="+String.valueOf(x1)+" y="+String.valueOf(y1),x1,y1);
}
public void update(Graphics g){
paint(g);
}
//override på update
public boolean mouseDown(Event evt, int x, int y){
x1=x;
y1=y;
repaint();
return true;
}
}
Originalversionen av update har följande utseende:
public void update(Graphics g){
g.setColor(getBackground());
g.fillRect(0,0,width,height);
g.setColor(getForeground());
paint(g);
}
/home/micko/Skrivbord/java_lektioner.doc
23
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Övning 4.1:
Skriv ett program som ritar ut en röd cirkel
med diametern 20 punkter när musknappen
klickas, enligt urklippet.
Övning 4.2:
Skriv ett program som ritar en linje mellan
två punkter som klickar med musen.
Övning 4.3:
Skriv ett program som ritar en gul rektangel
med röd ram med diagonalen mellan de två
klickade punkterna. Observera att rekrangeln
omges av en röd linje, samt att det inte spelar
någon roll hur punkterna klickas, d v s om
nedre eller övre punkten klickas först. Ledning: Använd funktionerna Math.min() och
Math.abs().
Övning 4.4:
Modifiera föregående övning så att rektangeln ritas ut i ’realtid’ med musknappen nedtryckt. Det
skall även fungera att minska rektangelns storlek. När musknappen släpps och en ny
rektangelpåbörjas raderas den gamla. Ledning: Gör inte override på update.
Övning 4.5:
Skriv ett program där man kan rita
med musen när en knapp är nedtryckt.
/home/micko/Skrivbord/java_lektioner.doc
24
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Rita utan paint
Metoden paint anropas automatiskt när appleten startas. Ibland ställer detta till problem, t ex när
variabler i paint ännu inte är initierade. Därför är det bättre att lägga kod som ritar figurer i en
egendefinierad metod, som anropas från t ex en musmetod. Detta illustreras i följande exempel,
där en kvadrat ritas ut vid varje musklickning. Programmet innehåller även en knapp som raderar
fönstret:
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet{
Button knapp;
//Raderaknappen
Graphics g;
//Deklarera objektet g av klassen Graphics
public void init() {
g=getGraphics(); //Skapar objektet g. Observera get istället för new
setBackground(Color.yellow);
knapp=new Button("Radera");
add(knapp);
}
public boolean action(Event evt,Object arg){
repaint();
return true;
}
//Reagerar på knappen
//Ritar om fönstret, d v s raderar
public void rita(int x1, int y1){
g.setColor(Color.red);
g.fillRect(x1-10,y1-10,20,20);
}
//Egen metod rita som ritar
//Fyller en rektangel med markör i mitten
public boolean mouseDown(Event evt, int x, int y){
rita(x,y);
//Anropar egna funktionen rita. Skickar med x och y.
return true;
}
}
Observera att programmet innehåller den egendefinerade metoden rita, som ritar ut en kvadrat.
Övning 4.6:
Skriv ett program där man kan rita polygoner genom
att klicka i hörnen med musen. Polygonen ritas när det
sista hörnet klickas. Antal hörn matas in i textrutan.
Det skall även finnas en knapp som raderar fönstret.
Tangenthändelser
Händelserna keyDown(Event evt, int key) och KeyUp(Event evt, int key) hanterar
tangenttryckningar. Parametern key anger ASCII-koden för den nedtryckta tangenten och evt
används för att kolla om Alt-, Ctrl- eller Skift-tangenten är nedtryckt:
if (evt.controlDown())
if (evt.shiftDown())
if (evt.metaDown())
//true om Ctrl-tangen är nedtryckt
//true om Skift-tangen är nedtryckt
//true om Alt-tangen är nedtryckt
/home/micko/Skrivbord/java_lektioner.doc
25
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Följande exempel skriver ut ASCII-koden och tecknet för den nedtryckta tangenten:
import java.applet.Applet;
import java.awt.*;
public class test3 extends Applet{
String s="";
public void paint(Graphics g){
g.drawString(s,50,50);
}
public boolean keyDown(Event evt, int key){
s="ASCII-kod: "+String.valueOf(key)+" Tecken: "+(char)key;
repaint();
return true;
}
}
Observera att man måste klicka på appleten med musen en gång innan tangenthändelserna
aktiveras. Det går heller inte att använda tangenthändelserna för att skriva ut text i
komponenterna textrura och etikett. För vissa tangenter som saknar ASCII-kod, t ex
piltangenterna, finns specialtecken:
Event.HOME
Event.END
Event.PGUP
Event.PGDN
Event.UP
Event.DOWN
Event.LEFT
Event.RIGHT
//Home-tangenten
//End-tangenten
//Page Up-tangenten
//Page Down-tangenten
//Pil upp-tangenten
//Pil ned-tangenten
//Pil vänster-tangenten
//Pil höger-tangenten
Specialtecknen används på följande sätt:
if(key==Event.LEFT)
//Kollar om tangenten för pil vänster är nedtryckt
Övning 4.7:
Gör en applet där du kan flytta runt en kvadrat på skärmen med piltangenterna.
Övning 4.8:
Gör en applet där du kan rita en figur med pitangenterna med en liten punkt som penna. Trycker
man på ’f’-tangenten kan flytta punkten på skärmen utan att det ritas ett streck. Trycker man på
’r’-tangenten ritar punkten ett streck efter sig när den flyttas.
/home/micko/Skrivbord/java_lektioner.doc
26
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
5. Animering med trådar
Innan vi börjar animera skall vi presentera sex huvudmetoder som finns i klassen Applet (utom
run). Två av dem, init och paint, har vi använt tidigare:
init()
Detta är den första metoden som körs när appleten laddas i webbläsaren. Här görs
initieringar av t ex komponenter, globala variabler och av bakgrundsfärg.
start()
Efter att init anropats körs metoden start. Den används för att starta någon aktivitet,
t ex en animering (se nedan).
run()
Metoden anropas efter att en aktivitet startats i metoden start, t ex att en tråd har
startats (finns i gränssnittet Runnable, se nedan).
stop()
…kan användas för att stoppa en aktivitet. Metoden anropas automatisk när
användaren lämnar webbsidan. Metoden används sällan i program.
paint(Graphics g) Här placeras grafikrutinera för att rita på appleten. Metoden anropas
automatiskt när appleten startas och när fönstrets storlek eller läge
förändras. I tidigare exempel (s. 25) har vi visat hur man kan rita utan paint
genom att deklarera en egen metod.
destroy()
Denna metod anropas automatiskt när appleten avslutas och webbfönstret stängs
och frigör då allt allokerat minne. Metoden används sällan i program.
Trådar och multitasking
När ett program befinner sig i en loop är det normalt helt uppslukat av vad som händer i loopen
och kan inte påverkas utifrån. Exempelvis går det inte att avbryta en loop via en knapptryckning.
Med trådar (threads) kan man emellertid använda sig av s k multitasking, d v s programmet får
då förmågan att reagera på yttre händelser trots att det är upptaget av en loop. För att detta skall
fungera Java måste vi införa gränssnittet Runnable, som innehåller metoder för trådar. Först
något om multipelt arv i Java.
Multipelt arv och gränssnitt i Java
I C++ använde vi ibland multipelt arv. Detta innebär att en klass kan ärva från flera klasser. I
Java däremot kan en klass ärva från endast en klass (via extends). Java har dock begreppet
gränssnitt, som är en samling av metoder som kan ’ärvas’ via kommandot implements.
Klassen Thread och gränssnittet Runnable
Klassen Thread har några metoder för att starta och stänga av trådar:
Thread trad;
trad.start();
trad.stop();
trad.suspend();
trad.resume();
Startar en tråd
Stoppar en tråd
Deaktiverar en tråd, d v s pausar tråden
Återstartar en deaktiverad tråd
Observera att dessa start och stop inte är samma som tillhör klassen Applet. I följande exempel
ärver klassen test4 egenskaperna från klassen Applet, samt implementerar gränssnittet Runnable,
som innehåller metoden run. Programmet flyttar en cirkel över skärmen så länge x<300 pixlar:
/home/micko/Skrivbord/java_lektioner.doc
27
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
import java.applet.Applet;
import java.awt.*;
public class test4 extends Applet implements Runnable{
Thread trad;
int x=10;
public void start(){
if(trad==null)
{
trad=new Thread(this);
trad.start();
}
}
public void run(){
while (x<300)
{
x++;
repaint();
try {Thread.sleep(10);}
catch (InterruptedException e){}
}
}
//Metoden paint anropas när fönstret ritas om.
//Skapar en fördröjning på 10 ms
public void paint(Graphics g){
g.fillOval(x,100,20,20);
}
}
Felmeddelandet som vid kompileringen är inget att bry sig om.
Övning 5.1:
Gör en applet som flyttar runt en cirkel slumpmässigt på skärmen med en fördröjning på 100 ms.
Övning 5.2:
Modifiera föregående program så att flyttningen kan startas respektive stoppas via två knappar.
Övning 5.3:
Gör en applet som ändrar bakgrundsfärgen från rött till blått via en animering.
Två trådar
Vitsen med trådar är ju att kunna köra flera processer samtidigt. Följande exempel visar hur två
trådar ’processar’ två bollar oberoende av varandra. Metoden i metoden run avgör vilket tråd
som för tillfället är aktiv. Bollarna startas (resume) och stoppas (suspend) med var sin knapp:
import java.applet.Applet;
import java.awt.*;
public class test3 extends Applet implements Runnable{
Thread trad1,trad2;
int x1=50,y1=50,x2=100,y2=100,paus;
Button start,stopp;
boolean tryck1=false, tryck2=false;
public void init() {
start=new Button("Blå");
stopp=new Button("Röd");
add(stopp);
add(start);
trad1=new Thread(this);
/home/micko/Skrivbord/java_lektioner.doc
28
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
trad2=new Thread(this);
}
public void start(){
trad1.start();
trad1.suspend();
trad2.start();
trad2.suspend();
}
public void stop(){
trad1.stop();
trad2.stop();
}
public void run(){
while (true){
if (Thread.currentThread().equals(trad1)){
x1=(int)Math.round(300*Math.random());
y1=(int)Math.round(300*Math.random());
paus=1000;
}
if (Thread.currentThread().equals(trad2)){
x2=(int)Math.round(300*Math.random());
y2=(int)Math.round(300*Math.random());
paus=500;
}
repaint();
try {Thread.sleep(paus);}
catch (InterruptedException e){}
}
}
public void paint(Graphics g){
g.setColor(Color.red);
g.fillOval(x1,y1,20,20);
g.setColor(Color.blue);
g.fillOval(x2,y2,20,20);
}
public boolean action(Event evt,Object arg){
String text=(String)arg;
if (evt.target instanceof Button)
if (text.equals("Röd")){
tryck1=!tryck1;
if (tryck1)
trad1.resume();
else
trad1.suspend();
}
if (text.equals("Blå")){
tryck2=!tryck2;
if (tryck2)
trad2.resume();
else
trad2.suspend();
}
return true;
}
}
Trådar i egen klass
I förra exemplet kördes de båda trådarna i samma run-metod i appleten. Detta är en liten
’halvdan’ parallellprocessering, eftersom trådarna startas samtidigt när run-metoden anropas.
Genom att köra trådarna via en klass blir det mer uppenbart att trådarna exeveras parallellt.
/home/micko/Skrivbord/java_lektioner.doc
29
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
Följande program fungerar som förra exemplet. Programmet använder dock den egna klassen
Boll för trådar och grafik, samt inte gränssnittet Runnable:
import java.applet.Applet;
import java.awt.*;
public class test3 extends Applet {
public class Boll extends Thread{
private int x,y,tid;
private Graphics gr=getGraphics();
private Color farg;
Boll (int a,int b,Color f,int t){
x=a;
y=b;
farg=f;
tid=t;
}
}
//Egna klassen Boll ärver från klassen Thread
//Konstruktor för klassen Boll
public void run() {
while (true){
x++;
gr.setColor(farg);
gr.fillOval(x,y,20,20);
try {Thread.sleep(tid);}
catch (InterruptedException e){}
gr.setColor(Color.white);
//Raderar och ritar om utan repaint
gr.fillOval(x,y,20,20);
if (x>getWidth())
//Ger fönstrets bredd
x=0;
}
}
//Definitionen för klassen Boll slutar
Boll b1, b2;
Button knappb, knappr;
boolean tryck1=false, tryck2=false;
//Två Boll-objekt deklareras
public void init() {
knappb=new Button("Blå");
knappr=new Button("Röd");
add(knappb);
add(knappr);
b1=new Boll(0,100,Color.red,10);
b1.start();
b1.suspend();
b2=new Boll(0,200,Color.blue,20);
b2.start();
b2.suspend();
}
public boolean action(Event evt,Object arg){
String text=(String)arg;
if (evt.target instanceof Button)
if (text.equals("Röd")){
tryck1=!tryck1;
if (tryck1)
b1.resume();
else
b1.suspend();
}
if (text.equals("Blå")){
tryck2=!tryck2;
/home/micko/Skrivbord/java_lektioner.doc
30
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
if (tryck2)
b2.resume();
else
b2.suspend();
}
return true;
}
public void stop(){
b1.stop();
b2.stop();
}
}
Observera att bollarna raderas genom att de ritas om med bakgrundsfärgen innan de ritas i en ny
position. Genom att inte använda repaint minskas flimret i animeringen.
Övning 5.4:
Modifiera exemplet ovan och gör så att en eller några bollar studsar med olika fart mellan
fönstrets sidor.
Övning 5.5:
Gör en applet som innehåller 20 studsande bollar mellan fönstrets sidor. Skapa bollarna via en
array och använd klassen Boll i föregående exempel. Bollarnas färg, fart och startposition skall
vara slumpmässig. Låt gärna den slumpmässiga färgen i genereras i klassen Boll.
/home/micko/Skrivbord/java_lektioner.doc
31
09-08-21
LEKTIONSGENOMGÅNGAR I JAVA
av Anders Andersson
6. Klasser i egna filer
Följande exempel använder klassen Test för att skriva ut en sträng. Klassen innehåller även två
konstruktorer; en med och en utan parameter:
import java.applet.Applet;
import java.awt.*;
public class test3 extends Applet{
public class Test{
private String namn;
//Klassen Test definieras
//Instansvariabeln namn deklareras
public Test(String n){
namn=n;
}
//Konstruktor med parameter
public Test(){
namn="Kalle Anka";
}
//Konstruktor utan parameter
public String skriv_namn(){
return namn;
}
//Metod skriv_namn för utskrift av variabeln namn definieras
}
//Slut på klassdefinitionen
Test t1,t2;
public void init() {
t1=new Test();
t2=new Test("Musse Pigg");
}
//Referensvariablerna (objekten) t1 och t2 deklareras
//t1 initieras till att referera till ett objekt av klassen Test
//t1 och t2 är en instans av klassen Test
public void paint(Graphics g){
g.drawString(t1.skriv_namn()+" och "+t2.skriv_namn(),100,100);
}
}
Egen klassfil
Vi modifierar föregående program genom att spara klassen Test i filen Test.java och kompilera
den i samma mapp som appleten test3.java. Programmet blir då något kortare:
import java.applet.Applet;
import java.awt.*;
public class test3 extends Applet{
Test t1,t2;
public void init() {
t1=new Test();
t2=new Test("Musse Pigg");
}
public void paint(Graphics g){
g.drawString(t1.skriv_namn()+" och "+t2.skriv_namn(),100,100);
}
}
/home/micko/Skrivbord/java_lektioner.doc
32
09-08-21