Java er et objekt-orienteret programmeringssprog, en modernisering og forbedring af det udbredte sprog C++. Dette er del 1 af en kort oversigt over dele af Java til brug i kurset Databehandling ved KVL. Oversigten består af følgende afsnit:
Der er masser af materiale om Java på nettet, f.eks.
En Java `applet' er et Java-program der har sit eget vindue på
skærmen. En applet kan for eksempel startes af en webside med
HTML-mærket APPLET
; så vises applettens vindue som en del
websiden i browseren (Netscape). En nærmere forklaring findes i HTML-oversigten, del 3.
En Java applet med navnet Klasse defineres i en fil kaldet Klasse.java, som skal indeholde Java-tekst af denne form:
import java.applet.Applet; import java.awt.*; public class Klasse extends Applet { ... erklæringer ... public void init() { ... } public boolean action( Event e, Object o ) { ... } public void paint( Graphics g ) { ... } }
Som det ses vil appletten normalt indeholde metoder kaldet init, action og paint. Disse metoder spiller en særlig rolle:
Det er programmørens opgave at indsætte erklæringer i klassen og at fylde indmad i metoderne init, action og paint. Det sker ved at skrive erklæringer, ordrer og udtryk:
Af sikkerhedshensyn kan en applet ikke læse og skrive filer på den
lokale disk eller diskette, og kan ikke skrive ud på printeren. Til
disse formål er man nødt til at bruge et egentligt Java-program.
2. Et komplet eksempel på en applet
Nedenstående Java-applet viser en knap med teksten `Klik her' og et tekstfelt (et lille vindue) når den køres. I tekstfeltet vises et tal. Hver gang man trykker på knappen forøges tallet i tekstfeltet med én.
import java.applet.Applet; import java.awt.*; public class Klik0 extends Applet { int antalklik; Button knap = new Button("Klik her"); TextField vindue = new TextField(10); public void init() { add(knap); add(vindue); antalklik = 0; } public boolean action(Event e, Object o) { if (e.target == knap) { antalklik = antalklik + 1; vindue.setText(Integer.toString(antalklik)); } return true; } }
Forklaring: Når appletten startes, oprettes en tæller (variablen
antalklik
), en knap (variablen knap
) og et
tekstfelt (variablen vindue
). Derefter udføres metoden
init
, hvor add
bevirker at knappen og
tekstfeltet vises på skærmen. Tælleren antalklik
nulstilles.
Hver gang brugeren trykker på knappen, udføres ordrerne der står i
action
. Derved forøges tælleren antalklik
med 1, og den nye tællerværdi vises i tekstfeltet vindue
.
Den synlige effekt er at hvert klik forøger værdien i tekstfeltet med
én.
Du kan prøvekøre ovenstående eksempel ved at klikke
her og trykke på knappen `Oversæt og kør'.
3. Ordrer
Her er nogle eksempler på de vigtigste ordrer i Java. Semikolon (;) bruges til at afslutte simple ordrer. Krølleparenteser { ... } bruges til at gruppere ordrer. Man behøver ikke lave indrykning af linierne, men det fremmer overblikket.
Ordre, eksempel | Betydning | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ambi = indk * 0.07 ;
| Tildeling: udregn udtryk og gem resultatet | ||||||||||
saldo += indskud ;
| Addition og tildeling: forøg saldo med
indskud .
Samme virkning som saldo = saldo + indskud ;
| ||||||||||
saldo -= gebyr ;
| Subtraktion og tildeling: formindsk saldo med gebyr .
Samme virkning som saldo = saldo - gebyr ;
| ||||||||||
saldo *= 1 + 0.01 * rentefod ;
| Multiplikation og tildeling: forøg saldo med
rentefod %.
Samme virkning som saldo = saldo * (1 + 0.01 * rentefod);
| ||||||||||
if (indk > 134500)
| Valg uden alternativ | ||||||||||
if (vaegt < 1000)
| Valg med alternativ | ||||||||||
switch (ugedag) {
|
Udtryk | Betydning |
---|---|
x
| Variabel x |
Aritmetiske operatorer | |
termin++
| Forøg termin med 1; returnér startværdien
|
++termin
| Forøg termin med 1; returnér slutværdien
|
termin--
| Formindsk termin med 1; returnér startværdien
|
--termin
| Formindsk termin med 1; returnér slutværdien
|
- x
| Fortegnsvending |
x * y
| Multiplikation |
x / y | Division. Hvis x og y har heltalstype, så afkortes resultatet til et heltal. Dvs. 8/3 er 2. |
dagnr % 7
| Heltalsrest ved division med 7 |
x + y
| Addition af tal, eller sammensætning af tegnstrenge |
x - y
| Subtraktion |
Sammenligningsoperatorer | |
x < y
| x er mindre end y |
x <= y
| x er mindre end eller lig med y |
x > y
| x er større end y |
x >= y
| x større end eller lig med y |
x == y
| x er lig med y |
x != y
| x er forskellig fra y |
Logiske operatorer | |
! (i == 2)
| Logisk negation: i er ikke lig 2 |
(0 < i) && (i < 100)
| Logisk konjunktion: i er større end nul og mindre end hundrede |
(i == 2) || (i > 10)
| Logisk disjunktion: i er lig 2 eller større end 10 |
Metodekald | |
Math.pow(x, n+1)
| Metodekald, her potensopløftning: udregn argumentudtrykkene og kald metoden. Metodens resultat er udtrykkets værdi |
En erklæring indfører en ny variabel, og fortæller hvilken type værdier variablen kan indeholde. I erklæringen skrives typen eller klassen først, fulgt af en liste af variable som alle får den pågældende type.
En variabel kan kun bruges hvor den er synlig. Variablens synlighed bestemmes af hvor den er erklæret:
init
, action
eller paint
) så
kan den kun benyttes i den pågældende metode, og kun efter
erklæringen. Eksempel: Variablen indkomst
i appletten Skat1.java.
for
-løkkes hoved
for (int i=0; i<10; i++) ...
, så kan den kun
benyttes i for
-løkkens hoved og krop. Eksempel:
Variablen i
inde i metoden action
i
appletten Dage02.java.
antalklik
i appletten Klik.java.
Man bør erklære variable så de er så lidt synlige som muligt. Hvis
variablen kun bruges i action
, så erklær den i
action
. Hvis variablen kun bruges som tællevariabel i en
for
-løkke, så erklær den i
for
-løkkens hoved.
Erklæring | Betydning | Eksempler på værdier |
---|---|---|
int a, b, c;
| a, b og c kan indeholde heltal | -12, 67, 129836122 |
double x, y, z;
| x, y og z kan indeholde kommatal | -1.2, 67.9, 3.1415926, 3E8, 1E-34 |
boolean fundet, slut;
| fundet og slut kan indeholde logiske værdier | true, false |
char c1, c2;
| c1 og c2 kan indeholde tegn | 'A', 'Z', '7' |
String s1, s2, s3;
| s1, s2 og s3 kan indeholde tegnstrenge | "Hello", "kartoffel" |
int[] dage;
| dage er en tabel af heltal
| |
String[] navne;
| navne er en tabel af tegnstrenge
| |
int a = 117;
| erklær a og initialiser med 117 | |
int[] dage = new int[12];
| erklær og opret tabellen dage med 12 heltal
| |
String[] navne = new String[7];
| erklær og opret tabellen navne med 7 strenge
|
Erklæringen int[] dage
siger blot at hvis
dage
henviser til noget, så er det en tabel af heltal.
For at lave en tabel af heltal skal man bruge operatoren
new
.
Med tildelingen dage = new int[12]
kan man oprette en
tabel med plads til 12 heltal, og binde den til variablen
dage
.
De tre sidste eksempler ovenfor viser at erklæring kan kombineres
med initialisering, hvorved variablene får en værdi med det samme.
Denne værdi kan oprettes med new
om nødvendigt.
6. Tegnstrenge
En tegnstreng (engelsk: string) er en tekst, for eksempel "abc 67lyx" eller "Hello, world".
Programtekst | Betydning |
---|---|
s1 = new String("Hello, world");
| Opret teksten "Hello, world" og gem i s1 |
s1.length()
| Længden af s1, dvs. antal tegn i s1 |
s2 + s3
| Konkatenering (sammensætning) af s2 og s3 |
s1.charAt(0)
| Det første tegn i s1 |
s1.equals(s2)
| Er s1 og s2 ens? |
s1.equalsIgnoreCase(s2)
| Er s1 og s2 ens pånær store/små bogstaver? |
s1.compareTo(s2) | Giver negativt resultat hvis s1 er mindre end s2, nul hvis s1 lig med s2, positivt hvis s1 større end s2 |
Sammensætningsoperatoren +
på strenge er speciel: hvis
et af argumenterne er en streng, så vil det andet argument blive
konverteret til en streng inden konkateneringen foretages. Man kan
altså skrive "abc" + 112
og få strengen
"abc112"
, hvor tallet 112 er blevet konverteret til
strengen "112" inden de to strenge sættes sammen.
Bemærk at ("abc" + 100 + 12) giver "abc10012", ikke "abc112". Tallene 100 og 12 konverteres til "100" og "12" hver for sig inden strengene sættes sammen.
Se også afsnittet om konvertering mellem
typer.
7. Tabeller
En tabel (engelsk: array) er en samling nummererede værdier. Nummereringen starter altid 0, 1, ...
Programtekst | Betydning |
---|---|
dage = new int[12] ;
| Opret tabel med plads til 12 heltal |
dage[0] = 31 ;
| Sæt første element i tabellen til 31 |
dage[0]
| Find indholdet af det første element |
dage.length
| Find tabellens størrelse |
for ( int i = 0 ; i < dage.length ; i++ )
| Gennemløb tabellen nedefra og op |
for ( int i = dage.length - 1 ; 0 <= i
; i-- )
| Gennemløb tabellen oppefra og ned |
Et navn kan betegne en variabel eller en metode. En navn skal
begynde med et bogstav eller $
eller _
og
fortsætte med nul eller flere cifre eller bogstaver eller
$
eller _
. Der skelnes mellem små og store
bogstaver.
Variabelnavne kan vælges frit; det er altså ligegyldigt for
computeren om en variabel hedder antalklik
eller bare
n
. Variabelnavne må dog ikke være sammenfaldende med
nøgleord, som har en speciel betydning. Nøgleordene er:
abstract boolean break byte case catch char class
const continue default do double else extends final finally float for
goto if implements import instanceof int interface long native new
package private protected public return short static super switch
synchronized this throw throws transient try void volatile while
Alle nøgleord skrives med små bogstaver. I disse noter vises
nøgleordene med fede typer
for nemmere at skelne dem
fra andre navne.
9. Komponenter der kan vises i en applet
En komponent vises som et separat grafisk objekt i applettens vindue. En komponent kan være Label, Button, TextField, TextArea, Choice, Checkbox, eller List. De tre sidstnævnte er omtalt i Java-oversigt del 2.
Programtekst | Betydning | Anvendelse |
---|---|---|
Etiket (Label) | ||
Label etiket1;
| Erklær en etiket | erklæring |
etiket1 = new Label("Etikettens tekst");
| Opret etiket med given tekst | init |
add(etiket1);
| Tilføj den til appletten | init |
etiket1.setText("Ny tekst til etiketten");
| Udskift etikettens tekst | |
Knap (Button) | ||
Button knap1;
| Erklær en knap | erklæring |
knap1 = new Button("Knappens tekst");
| Opret knap med given tekst | init |
add(knap1);
| Tilføj knap til applet | init |
Tekstlinie (TextField) | ||
TextField uddata1, inddata1;
| Erklær to tekstlinier | erklæring |
uddata1 = new TextField("Tekstliniens tekst");
| Opret tekstlinie med given tekst | init |
inddata1 = new TextField(25);
| Opret tom tekstlinie med plads til 25 tegn | init |
add(uddata1);
add(inddata1);
| Tilføj de to tekstlinier til applet | init |
uddata1.setEditable(false);
| Teksten kan ikke redigeres | |
uddata1.setText("Ny tekst");
| Udskift tekstindholdet | |
inddata1.getText();
| Tekstindholdet som streng | |
Tekstområde (TextArea) | ||
TextArea uddata2, inddata2;
| Erklær to tekstområder | erklæring |
uddata2 = new TextArea("Tekst", 5, 40);
| Opret tekstområde, viser 5 linier à 40 tegn | init |
inddata2 = new TextArea(5, 40);
| Opret tomt tekstområde, viser 5 linier à 40 tegn | init |
add(uddata2); add(inddata2);
| Tilføj de to tekstområder til applet | init |
uddata2.setEditable(false);
| Teksten kan ikke redigeres | |
uddata2.setText("Ny tekst til tekstområdet");
| Udskift tekstindholdet | |
uddata2.appendText("Mere tekst");
| Tilføj til tekstindholdet | |
uddata2.appendText("\n");
| Tilføj linieskift i tekstindholdet | |
inddata2.getText();
| Tekstindholdet som streng | |
inddata2.getSelectedText()
| Valgt tekst (som tegnstreng) |
action
Når brugeren gør noget ved applettens vindue, f.eks. indtaster
tekst, flytter musen eller klikker på en musetast, så sker der en
hændelse (engelsk: event). Når der sker en hændelse kaldes
applettens metode action
så appletten kan reagere på
hændelsen.
Lad metoden action
være erklæret således:
public boolean action( Event e, Object o ) { ... reaktion på hændelse ... return true; }
Når der sker en hændelse (f.eks. et museklik) kaldes
action
, idet parameteren e
overføres som en
beskrivelse af hændelsen. Denne parameter giver forskellige slags
information:
e.target
er den komponent som hændelsen vedrører.
Det kan være den knap eller det tekstfelt som brugeren har rørt ved.
Med if (e.target == knap) ...
i eksemplet ovenfor kan man således undersøge om der
blev trykket på et knappen hørende til variablen knap
.
Hvis der er flere knapper på appletten bruger man flere if
(e.target == ...) ...
til at skelne mellem knapperne.
Ordren return true
signalerer at hændelsen er blevet
håndteret af metoden action
.
11. Grafik og metoden
paint
Man kan tegne i en applet ved at benytte grafik-objektet
g, der overføres til metoden paint
når appletten
startes, og hver gang man kalder repaint()
. Nedenstående
metoder skal altså benyttes i paint
. Alle koordinater og
størrelser angives i pixels, dvs. skærmpunkter.
Programtekst | Betydning |
---|---|
g.drawString("Tekst", 100, 200)
| Skriv teksten "Tekst" med nederste venstre hjørne ved (100, 200) |
g.setColor(Color.red)
| Vælg farve. Mulige farvenavne er orange, pink, cyan, magenta, yellow, black, white, gray, lightGray, darkGray, red, green, blue |
g.setColor(new Color(255, 0, 255))
| Vælg farve; farvekoderne skal være 0-255 |
g.setFont(new Font("TimesRoman", Font.BOLD, 14))
| Vælg skriftsnit Times, fed, 14 punkt. Andre muligheder:
Font.ITALIC og Font.PLAIN
|
g.drawLine(10, 20, 110, 120)
| Tegn linie fra (10, 20) til (110, 120) |
g.drawRect(10, 20, 100, 50) | Tegn rektangel; øverst venstre er (10, 20), bredde er 100 og højde er 50 |
g.fillRect(10, 20, 110, 120)
| Udfyld rektangel |
g.clearRect(10, 20, 110, 120)
| Tegn rektangel med baggrundsfarven |
g.drawOval(10, 20, 100, 200)
| Tegn oval; øverste venstre er (10, 20), bredde er 100 og højde er 200 |
g.fillOval(10, 20, 100, 200)
| Udfyld oval. |
g.drawArc(10, 20, 100, 200, -45, 90)
| Tegn buen (ovalperiferien) fra -45 til 90 grader |
g.fillArc(10, 20, 100, 200, -45, 90)
| Tegn udfyldt bue (ovalsektor) fra -45 til 90 grader |
g.drawPolygon(xPoints, yPoints, 7)
| Tegn polygon (mangekant) med 7 hjørner; xPoints og yPoints er tabeller af heltal med hjørnernes (x, y)-koordinater |
g.fillPolygon(xPoints, yPoints, 7)
| Udfyld polygon |
g.copyArea(10, 20, 50, 100, 120, 130)
| Kopier området med øverste venstre (10, 20), bredde 50 og højde 100; kopien forskydes 120 til højre og 130 ned |
Svarende til metoden action
, som kan håndtere
hændelser der vedrører knapper og tekstfelter, er der nogle metoder
som kan håndtere hændelser der vedrører musen og tastaturet. Disse
metoder bør ligesom action
returnere true
.
public boolean mouseDown( Event e, int x, int y ) | Kaldes når museknappen trykkes ned; (x, y) angiver hvor musen pegede. |
public boolean mouseUp( Event e, int x, int y ) | Kaldes når museknappen slippes; (x, y) angiver hvor musen pegede. |
public boolean mouseMove( Event e, int x, int y ) | Kaldes når musen flyttes uden at en museknap er trykket; (x, y) angiver hvor musen peger. |
public boolean mouseDrag( Event e, int x, int y ) | Kaldes når musen flyttes mens en museknap er trykket; (x, y) angiver hvor musen peger. |
public boolean keyDown( Event e, int key ) | Kaldes når en tast trykkes; key er tegnkoden for den tast der trykkes. |
public boolean keyUp( Event e, int key ) | Kaldes når en tast slippes; key er tegnkoden for den tast der slippes. |
For et eksempel på brugen af disse metoder, se
Life2.java.
13. Konvertering mellem typer
Fra | Til | Udtryk | Bemærkning |
---|---|---|---|
int i | String | Integer.toString(i) | |
String s | int | Integer.parseInt(s) | |
String s | int | new Integer(s).intValue() | Alternativ til ovenstående |
int i | double | (double)(i) | |
double d | String | Double.toString(d) | |
String s | double | new Double(s).doubleValue() | |
double d | int | (int)(d) | Afrund mod nul |
boolean b | String | Boolean.toString(b) | |
String s | boolean | Boolean.getBoolean(s) | |
String s | boolean | new Boolean(s).booleanValue() | Alternativ til ovenstående |
Hvis strengsammensætningsoperatoren +
anvendes på et
argument, der ikke er en streng, konverteres dette automatisk til en
streng; se afsnittet om tegnstrenge. For
eksempel vil udtrykket ("abc" + 112) have samme værdi som ("abc" +
Integer.toString(112)), nemlig strengen "abc112".
14. Læsning af flere tal fra en tegnstreng
Kaldet Integer.parseInt(s) kan bruges til at læse ét heltal fra tegnstrengen s. Når man skal læse mere end ét tal fra en tegnstreng bør man i stedet benytte StreamTokenizer. Dette kan bruges til at læse vilkårlig mange tal fra TextField, TextArea eller en tekstfil.
Eksempel
Sumtal.java.
Denne programstump indlæser en række tal fra et TextArea kaldet
inddata
og udregner deres sum:
String s = inddata.getText(); // 1 InputStream istroem = new StringBufferInputStream(s); // 2 StreamTokenizer tstroem = new StreamTokenizer(istroem); // 3 tstroem.parseNumbers(); // 4 double sum = 0; // 5 int brik = tstroem.nextToken(); // 6 while (brik == StreamTokenizer.TT_NUMBER) { // 7 sum += tstroem.nval; // 8 brik = tstroem.nextToken(); // 9 }
Forklaring:
TextArea inddata
gemmes i tegnstrengen
s
.
s
konverteres til en indstrøm kaldet
istroem
.
istroem
konverteres til en strøm af
brikker (engelsk: tokens), her kaldet tstroem
.
En brik er et tal (TT_NUMBER
) eller et ord
(TT_WORD
) eller linieskift (TT_EOL
) eller
slut-på-strømmen (TT_EOF
).
tstroem
.
tstroem
.
sum
vil da indeholde summen af alle de læste tal).
tstroem.nval
, som lægges
til den foreløbige sum. (Den læste tegnstreng kan fås ved at skrive
sval
i stedet for nval
).
tstroem
, og løkken
fortsætter ved linie 7.
Bemærk: Når man bruger StreamTokenizer skal man:
import java.io.*;
forrest i programmet, og
throws IOException
for den omgivende metode.
I et egentligt Java-program kan man indlæse fra tekstfiler og fra
tastaturet på helt tilsvarende måde.
15. Linievis læsning
Hvis man vil beregne talsummerne linie for linie, så skal man bruge to while-løkker. Den ydre kører en omgang for hver linie, og den indre en gang for hvert tal på linien.
Eksempel
Liniesum.java.
Beregn summen for hver linie, og gem alle summerne i en tegnstreng
summer
. Dette gøres ved at erstatte linie 5-9 i
eksemplet ovenfor med nedenstående; linie 1-4 er uændret:
String s = inddata.getText(); // 1 InputStream istroem = new StringBufferInputStream(s); // 2 StreamTokenizer tstroem = new StreamTokenizer(istroem); // 3 tstroem.parseNumbers(); // 4 tstroem.eolIsSignificant(true); // A int brik = tstroem.nextToken(); // B while (brik != StreamTokenizer.TT_EOF) { // C double sum = 0; // D while (brik == StreamTokenizer.TT_NUMBER) { // E sum += tstroem.nval; // F brik = tstroem.nextToken(); // G } summer += sum + " "; // H brik = tstroem.nextToken(); // I }
Forklaring:
tstroem
.
tstroem
.
tstroem.nval
, lægges til liniens
foreløbige sum.
tstroem
, og den indre
løkke fortsætter ved linie E.
sum
er
summen af liniens tal, som føjes til de andre liniesummer.
tstroem
, og den ydre
løkke fortsætter ved linie C.