webbservern.se :: Handboken :: Programmering :: Java

webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Handboken / Programmering / Java
I denna guide ska jag försöka hålla mig kortfattat eftersom Java är ett så pass stort ämne. Det ska inte bli
någon bok och allt kommer inte att gås igenom 100-procentigt. Det blir många exempel eftersom det är ett
bra sätt att uttrycka mycket med få ord. Jag tror och hoppas att det ska gå att hänga med bra även om man
inte är bekant med programmering sedan tidigare.
Jag har för avsikt att följa detta förslag till svenska Javaterminologi. Om jag misslyckas med detta på
något ställe får du gärna upplysa mig om detta.
Ursprung
Java började utvecklas av SUN under ledning av James Gosling runt 1991. Det var tänkt att Java, eller
Oak som det först kallades, skulle användas i olika typer av elektronik, till exempel en brödrost.
Vad är Java för typ av språk?
Java är ett objektorienterat, statiskt typat, imperativt, kompilerat (eller semikompilerat) och
plattformsoberoende programmeringsspråk.
Objektorienterat
Java är strikt objektorienterat, det är inte påklistrat i efterhand som fallet är med PHP och Perl. Java är
från grunden utvecklat i enlighet med det objektorienterade tänkandet.
Statiskt typat och imperativt
Java är liksom C++ statiskt typat och imperativt. Att Java är statiskt typat (jo, det är svengelska) innebär i
praktiken att variabler måste deklareras innan de används och att Javatolken kommer att protestera om du
försöker associera till exempel ett decimaltal till en heltalsvariabel. Det finns mycket mer att orda om
skillnaderna mellan statiskt och dynamiskt typade språk men det gräver vi inte djupare i just nu.
Plattformsoberoende och kompilerat
Java är kompilerat på så vis att din Javakod måste kompileras innan du exekverar programmet. Det
kompileras dock inte till maskinkod utan till ett mellansteg, bytekod som i sin tur interpreteras av en
Javatolk (JVM, Java Virtual Machine). Detta har den uppenbara fördelen att ditt Javaprogram kan köras i
de operativsystem som har en Javatolk portad till sig. Eftersom det finns en JVM portad till alla vanligt
förekommande operativsystem kan man möjligen hävda att Java är plattformsoberoende.
Java på webbservern - utvecklingsmiljö och kompilering
För tillfället körs Java 1.4.2 på webbservern. Du kan kontrollera själv vilken version som körs:
webbservern.se ::
-1-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Emacs är den rekommenderade utvecklingsmiljön eftersom det lämpar sig väl att köras via SSH över
nätverk. Den som vill kan även pröva Eclipse.
Grunderna i Java
Ett komplett program
Innan vi dyker in bland variabler och allt annat tar vi ett komplett, enkelt men framför allt traditionsenligt
Javaprogramexempel. Det kan vara bra att känna till strukturen för ett komplett Javaprogram om du vill
provköra någon kodsnutt nedan. Byt då bara ut innehållet i main-metoden.
class Hello {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Om du skulle vilja provköra exemplet skriver du in de fem raderna i en fil. Sparar den som ren text och
ger den filnamnet Hello.java. För att kompilera Hello.java och sedan köra programmet skriver du:
javac Hello.java
java Hello
Variabler och datatyper
Java är som sagt statiskt typat och när du skapar en variabel ska du ange vilken datatyp du vill ha. Det
beror förstås på vad för data du vill associera till din variabel. Nedan har du en tabell med vilka du har att
välja på:
Typ
Beskrivning
byte
heltal, [-128 - 127]
short
heltal, [-32768 - 32767]
int
heltal, [-2147483648 - 2147483647]
long
heltal, [-9223372036854775808 - 9223372036854775807]
float
flyttal, [-3.4E38 - 3.4E38]
double
flyttal, [-1.7E308 - 1.7E308]
boolean
boolsk variabel [antingen true eller false]
char
tecken (lagras som Unicode, 16 bitar)
webbservern.se ::
-2-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Det går även att tilldela variabeln ett värde direkt vid deklareringen. Vi tar några exempel (där det också
framgår hur man kommenterar och avslutar satser):
byte fingers; //Antalet fingrar
short result1, result2;
int hair = 120000;
long gatesMoney, distanceToMoonInMillimetres = 384400000000;
float average, height;
boolean isMore = false, isEmpty = true;
char favouriteLetter = ’J’, tab = ’\t’;
Det kan även vara bra att veta att det går att till explicit omvandla en variabels datatyp till en annan. Man
skriver på följande vis för att omvandla från en integer till en float:
int a = 10;
float flyttal = (float) a // flyttal = 10.0;
Lite aritmetik
Java är en kraftfull miniräknare och det går att räkna hejvilt. Dessa aritmetiska operatorer finns att tillgå.
Operator
Betydelse
+
Addition
-
Subtraktion
/
Division
*
Multiplikation
%
Modulus
Det mesta fungerar som man kan förvänta sig och det går bra att använda parenteser för att specificera
evalueringsordningen (precedensen med ett fint ord). Exempel är bra.
double average, quantity = 50, total = 547.6;
average = total / quantity;
System.out.println("Per styck: " + average);
// Java skriver ut: Per styck: 10.952
I förbigående passar vi på att notera att utskrifter sker via System.out.println.
Modulusoperatorn kanske du inte stött på tidigare. Den ger dig resten vid en heltalsdivision. Exempelvis
är "11 modulus 6" lika med 5.
int a = 11 % 6; // a = 5
webbservern.se ::
-3-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Det finns ett gäng operatorer till men de kan du läsa om på annat håll. Lägg även märke till deras inbördes
prioritetsordning.
Strängar
Siffror i all ära men strängar, en bunt alfanumeriska tecken alltså, är också bra att kunna hantera. Strängar
är inte en vanlig datatyp i Java, det är en instans av String-klassen. Det där med objektorienterad
programmering har vi inte kommit till ännu så du har inte missat nåt om "instans" känns som ett
främmande ord.
Vi tar ett exempel som vanligt.
String greeting = "Tjena!\n", body, bye = "Hejdå!";
body = "Jag mår bra. Hur mår du?\n";
System.out.println(greeting + body + bye);
Javatolken tittar på satserna ovan och skriver ut följande:
Tjena!
Jag mår bra. Hur mår du?
Hejdå!
Kommentarer
Du bör ta som vana att kommentera allt som inte är uppenbart i din kod. Vad som är uppenbart är
individuellt och dynamiskt men hellre en kommentar för mycket än en kommentar för lite.
Om du vill infoga en mindre kommentar används två snedstreck, //, och därefter kommentaren. Det som
kommer efter snedstrecken på den raden antas vara en kommentar.
Om du vill infoga en längre kommentar omgärdar du kommentaren med /* och */.
Så här skulle några kommentarer (med något kommenterbart) se ut:
// Beräknar medelvärde
double average = (totalAmount / noOfParticipants);
String command = program + " " + arguments; // Hela kommandot.
/*
Metoden nedan kan starkt ifrågasättas men
i nuläget finns annat som är viktigare att
korrigera.
*/
Det finns även något som kallas dokumentationskommentarer. Om du nyttjar dig av sådana kan du med
hjälp av javadoc skapa en separat dokumentation för ditt program.
webbservern.se ::
-4-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
En dokumentationskommentar börjar med /** och slutar med */. Det finns ett antal nyckelord som man
kan använda sig av för att dokumentera metoder och klasser i ett standardformat.
Vi kikar som brukligt är på ett exempel:
/**
* Krypterar med IDEA-algoritmen och
* sparar den nya filen under nytt namn.
* @author Arne Anka
* @param filename
filnamnet för filen som ska krypteras<
*
doCompress anger om filen ska krypteras eller ej
* @return
absoluta sökvägen till den krypterade filen
*/
public String crypt(String inFile, boolean doCompress) {
// Lite kod som gör det som utlovas.
}
Villkorsstyrning
Naturligtvis finns den (förhoppningsvis) bekanta if...else-konstruktionen implementerad i Java. Även om
den inte är bekant bör den vara lätt att ta till sig: Om ett villkor är uppfyllt, gör si, i annat fall kan vi testa
mot ett annat villkor och göra något annat, om inget av villkoren är uppfyllda kan vi välja att göra
ytterligare något annat. Ett exempel (om än småfjantigt) säger mer än tusen ord som vi säger på
webbservern.se:
short grade = 3;
if (grade < 3) {
System.out.println("Nja, inte riktigt bra.");
} else if (grade == 3) {
System.out.println("Okej, det funkar.");
} else {
System.out.println("Stabilt! Fortsätt så.");
}
I exemplet ovan används "else if" och "else" för att testa ytterligare villkor men dessa två är inte
obligatoriska. Exemplet ovan skulle även kunna implementeras med hjälp av en switch-konstruktion. Så
här skulle det kunna se ut:
short grade = 3;
switch(grade) {
case(1): {
System.out.println("Nja, inte riktigt bra.");
break;
}
case(2): {
System.out.println("Nja, inte riktigt bra.");
break;
}
case(3): {
webbservern.se ::
-5-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
System.out.println("Okej, det funkar.");
break;
}
case(4): {
System.out.println("Stabilt! Fortsätt så.");
break;
}
default: {
if (grade == 5) {
System.out.println("Stabilt! Fortsätt så.");
} else {
System.out.println("Märkligt betyg.");
}
break;
}
}
Loopar
En loop gör att du kan köra en sats eller ett block (ett gäng satser) upprepade gånger. Vi ska titta på tre
konstruktioner: for, while samt do while. I alla dessa tre varianter kan break och continue användas. Break
hoppar ut ur loopen medan continue hoppar till nästa iteration i loopen.
For
For-loopen är kompakt och praktiskt i många fall. Den används till exempel ofta för att iterera över en
listas element. I det enkla exemplet nedan loopar vi runt 10 gånger och skriver ut vilken iteration vi
befinner oss på för tillfället.
for (int i = 0; i < 10; i++) {
System.out.println("Iteration: " + i);
}
While
While-loopen är enkel till sin natur. Den ligger nära vårt vardagliga sätt att tänka: Gör si så länge ett
villkor är uppfyllt.
int i = 0;
while (i < 10) {
System.out.println("Iteration: " + i);
i++;
}
webbservern.se ::
-6-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Do-While
Do-loopen nedan kontrollerar villkoret första gången efter att den har skrivit ut "Iteration: 0". I detta
exempel är det oväsentligt men i andra tillämpningar kan det vara en viktigt skillnad.
int i = 0;
do {
System.out.println("Iteration: " + i);
i++;
} while (i < 10);
Matriser
Enkelt uttryckt låter matriser dig hantera flera variabler av samma typ via endast ett variabelnamn. Det
kanske inte låter så användbart men det är det. Jag tror vi är redo för ett litet exempel där vi även knyter an
till avsnittet om for-loopar ovan. Med hjälp av for-loopen kan vi loopa precis så många gånger som det
finns element i matrisen (matrisnamn.length).
int[] grades = {3,5,4,3,3}; //Vi fyller matrisen med betygen för våra 5 kurser.
for(int i = 0; i < grades.length; i++) {
System.out.println("Betyg i kurs " + i + ": " + grades[i]);
}
I exemplet ovan deklareras matrisen grades samtidigt som den initieras med betygen. Varje betyg
motsvarar ett element i matrisen och kan kommas åt på formen grades[x] där x är en siffra 0-4.
Det går även bra att göra flerdimensionella matriser samt naturligtvis fylla dem med annat än heltal.
Metoder
Det som i många andra programmeringsspråk kallas för funktioner heter i Java metoder. Metoder är bra
till mycket, till exempel är det vettigt att lägga en ofta använd kodsnutt i en metod och därefter anropa
metoden istället för att duplicera kodsnutten ännu en gång.
Ett exempel får illustrera som så många gånger förr.
public double average (int persons, double totalAmount) {
return (totalAmount / persons);
}
Det finns flera intressanta iakttagelser vi kan göra. För det första, public är metodens åtkomstmodifierare
(fungerar på samma sätt för hela klasser) och definierar vad som ska kunna komma åt denna metod. Vi
ska snart titta på vad public innebär och vad det finns för andra alternativ.
Efter åtkomstmodifieraren följer vilken datatyp som metodens returvärde ska ha. Metoden "average" ovan
ska returnera ett flyttal, en variabel av datatypen double. Om en metod inte ska returnerar något anges
"void".
webbservern.se ::
-7-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Inom parenteserna finns metodens parametrar. Om metoden inte tar emot några parametrar skriver man
helt enkelt ingenting mellan parenteserna En parameter definierar alltså typen för det värde som kan
skickas till metoden samt namnet som kan användas för att referera till den i koden i metoden. En del
blandar ihop argument med parameter. Argumentet är det värde som skickas till metoden när den körs och
detta värde refereras av parameternamnet under exekvering av metoden.
Vi noterar även att vi returnerar värdet från metoden med return vilket samtidigt gör att vi lämnar
metoden. Om en en metod inte har något definierat returvärde kan "return" användas ensamt för att lämna
metoden.
Åtkomstmodifierare och paket
I en statisk klassmetod (deklarerad som static) är det möjligt att referera till de andra statiska
medlemmarna i samma klass medan en icke-statisk metod kan nå alla medlemmar. (Som medlem i en
klass räknas fält och variabler. Ett fält är en variabel som deklarerats i en klass, med andra ord
instansvaribler och klassvariabler.)
Utöver ovanstående regler ska vi bekanta oss med åtkomstmodifieraren som talar om hur variabler och
metoder inuti en klass är åtkomliga från andra klasser. Detta åskådliggörs enklast i tabellform.
Åtkomstmodifierare
Åtkomst
Ingen åtkomstmodifierare
angiven
Från klasser i samma paket.
public
Från alla klasser.
private
Ingen åtkomst utanför klassen.
protected
Från klasser i samma paket och från alla
subklasser.
Vi stötte nu på begreppet paket. Paket är en namngiven samling klasser som används för att gruppera
klasserna. Om man inte anger något paket först i filen så kommer filens klasser att tillhöra ett namnlöst
paket som är gemensamt för alla filer utan paketdeklaration.
Ett kortill exempel för att visa hur paketdeklarationen kan se ut.
package myPackage; //På första raden i filen
De filer som ska tillhöra paketet "mittPaket" måste sparas i en katalog med samma namn, det vill säga
"mittPaket" (utan citationstecken). Det går även att bygga upp en hierarki med paket genom att särskilja
paketen med punkter. Ett exempel till.
package allMyPackages.myPackage; //På första raden i filen
I exemplet ovan antas "myPackage" vara en underkatalog till "allMyPackages".
webbservern.se ::
-8-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Undantagshantering
Undantag används för att signalera att något har gått på tok. Dessa signaler kan snappas upp så att du har
möjlighet att parera misstaget eller helt enkelt "dö graciöst" (ruggig direktöversättning av "die
gracefully").
Upplägget är följande:
try {
Gör det farliga;
}
catch (Undantagsparameter) {
Hantera felet (undantaget).
}
Vi "försöker" (try) göra något som vi vet kan gå snett. Om det går snett "kastas" (throw) ett undantag. Om
vi har varit förutseende kan vi "fånga" (catch) det kastade undantaget.
Det går att ha flera catch-block, nästlade try-block och till och med kasta tillbaka undantag till det
anropande programmet. Det är dock inget vi kikar på närmare i detta kapitel. Något vi ska titta lite på
innan vi är klara med undantag är finally-blocket.
Finally-blocket körs efter catch-blocken och används när du vill vara säker på att viss kod körs innan en
metod avslutas. Du kan rensa upp efter det avbrutna try-blocket, exempelvis stänga öppna filer.
try {
Gör det farliga;
}
catch (Undantagsparameter) {
// Hantera felet (undantaget).
}
finally {
// Rensa upp.
}
I nästa stycke om filhantering studerar vi hur undantagshanteringen kan gå till i praktiken.
Läsa/skriva till fil
Det är skillnad på hur text- respektive binärfiler hanteras. Vi behandlar endast fallet med textfiler men om
du vill läsa/skriva binära filer går det till på liknande sätt.
Vi börjar med ett exempel där vi läser en textfil och skriver ut dess innehåll till standardutenheten
(skärmen i vårt fall). Det blir även ett utmärkt tillfälle att studera undandtagshantering i praktiken.
import java.io.*;
class ReadFile {
public static void main(String[] args) {
webbservern.se ::
-9-
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
try {
FileReader fr = new FileReader("testfil.txt");
BufferedReader br = new BufferedReader(fr);
// Läs första raden.
String stringRead = br.readLine();
// Läs resten av filen.
while (stringRead != null) {
System.out.println(stringRead);
stringRead = br.readLine();
}
br.close();
}
catch (FileNotFoundException e) {
System.out.println("Filen hittades inte!");
System.exit(0);
}
catch (IOException f) {
System.out.println("IOExecption under läsning av fil.");
System.exit(0);
}
}
}
Först skapas ett FileReader-objekt som upprättar en anslutning till den specificerade filen och
Javaprogrammet. Därefter skapas ett BufferedReader-objekt som kan buffra operationer från ett annat
Reader-objekt (såsom FileReader). (Klasserna i standardbiblioteket är alla subklasser till den abstrakta
superklassen Reader.)
När det väl är ordnat så att vi kan läsa från filen läser vi sträng för sträng tills filen är slut.
Nu tittar vi istället på hur det kan se ut när vi ska skriva till en textfil. Då använder vi några smidiga
subklasser till den abstrakta klassen Writer.
import java.io.*;
class WriteFile {
public static void main(String[] args) {
try {
FileWriter fr = new FileWriter("testfil.txt");
BufferedWriter br = new BufferedWriter(fr);
br.write("Detta skrivs till filen.\n");
br.write("Det här med.");
}
catch (IOException e) {
System.out.println("Det gick inte att skriva till filen.");
System.exit(0);
}
}
webbservern.se ::
- 10 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
}
I exemplet ovan skapas en ny fil med filnamnet "testfil.txt" om denna inte redan finns, i så fall skrivs den
över. För att lägga till text i "testfil.txt" istället för att skriva över skapar du FileWriter-objektet enligt
följande:
FileWriter fr = new FileWriter("testfil.txt", true);
Även i detta fall skapas "testfil.txt" om den inte redan finns.
Klasser och objekt
Nu är det dags att förstå sig på det här med objektorienterad programmering (OOP). Lite grand i alla fall.
Det finns, som om allt annat i den här guiden, mycket att säga om OOP och bara OOP erbjuder material
för ett rejäl bok. Om du tyckte att det ovanstående var klurigt och inte riktigt tagit in det ännu kan det vara
klokt att vänta med objektorienteringen tills det andra känns mer greppbart.
Vi ska gå igenom klasser och objekt genom en liknelse. Min erfarenhet är att OOP bäst förstås genom ett
exempel som relaterar till verkligheten. Det fina i kråksången är nämligen att OOP är en tydlig analogi till
verkligheten.
Tänk dig begreppet bil. Vad utmärker en bil? Vi kanske kan enas kring fyra hjul, motor, färg, växellåda,
ratt samt ett eller flera säten. Denna prototyp av "bil" kallar vi för en klass (även om vi senare ska se att
det mer liknar en abstrakt klass). Det är den allmänna bilen som bara finns i våra hjärnor (jmfr Platons
idévärld). De bilar vi ser ute på vägarna är objekt som är instanser av klassen bil.
En gång till med andra ord: en klass är en specifikation för en samling objekt med gemensamma
egenskaper. Det är en mall uttryckt i programkod som definierar vad en viss typ av objekt består av.
Ordet instans är detsamma som ett objekt av en viss klass. När du skapar ett objekt utifrån en klass säger
man att klassen instansieras.
Vi lämnar bilarna ett tag och tar ett enkel exempel med rektanglar. Vi återkommer till bilarna snart.
public class Rectangle {
//Klassvaribel
static final int noOfSides = 4;
//Instansvariabler
double height;
double width;
double area() {
return (this.height * this.width);
}
}
De objekt som skapas från klassen Rectangle kommer att dela på klassvariabeln "noOfSides" som
dessutom är definierad som en konstant (final). De skapade objekten kommer dock att få varsin kopia av
instansvariablerna "height" och "width" som talar om hur hög och bred rektangeln är. Vi kan även notera
webbservern.se ::
- 11 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
att instansmetoden (area) har en variabel this som refererar till det aktuella objektet för vilken metoden
anropas.
Vi kan nu skapa rektangelobjekt på detta sätt:
Rectangle myRectangle = new Rectangle();
//Bestämmer rektangelns storlek
myRectangle.height = 10.5;
myRectangle.width = 6.5;
System.out.println("Rektangelns area: " + myRectangle.area() + " areaenheter.");
Konstruktorer
I exemplet ovan bestäms höjden och bredden på den skapade rektangeln efter att rektangeln skapats. Det
går naturligtvis att göra så att den skapade rektangeln redan vid dess skapelse tilldelas en höjd och en
bredd. Med hjälp av två konstruktorer kan vi hantera både fallet när en höjd och bredd har angivits vid
skapelsen och när höjd och bredd saknas.
public class Rectangle {
//Klassvaribel
static final int noOfSides = 4;
//Instansvariabler
double height;
double width;
//Konstruktor som tar hand om fallet när höjd och bredd är angiven.
Rectangle (double height, double width) {
this.height = height;
this.width = width;
}
//Konstruktor som tar hand om fallet när höjd och bredd inte är angiven.
Rectangle() {
this.height = 10;
this.width = 5;
}
double area() {
return (this.height * this.width);
}
}
Abstrakta klasser
Som det nämndes tidigare finns det något som heter abstrakta klasser. Bilklassen som diskuterades i
exemplet ovan skulle behöva implementeras som en abstrakt klass eftersom bilarna skiljer sig åt på en del
punkter, Car-klassen svarar inte mot något objekt i verkligheten. Exempelvis finns det bilar med manuell
respektive automatisk växellåda och det vore då lämpligt att inte specificera exakt hur det går till när man
växlar. Det är upp till subklasserna som ärver från den abstrakta klassen att definiera dessa funktioner.
Lugn bara lugn så ska vi snart räta ut eventuella frågetecken.
webbservern.se ::
- 12 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Vi ska nu titta på hur bilklassen kan se ut i ett exempel där vi även stöter på en del andra nyheter.
public abstract class Car {
static final int wheels = 4; //Klassvariabel med ett fast värde.
//Instansvariabler
String engine;
String gearbox;
String colour;
int seats;
//Instansmetoder
void horn() {
System.out.println("Tut tut!");
}
void gas() {
System.out.println("Wrooom!");
}
//Instansmetoder som deklareras men inte definieras
abstract void steer (double degree);
abstract void changeGear (int gear);
}
Vi noterar att den definierade klassen är abstrakt, den börjar med "public abstract class...". Den är abstrakt
eftersom det finns två abstrakta metoder, steer() och changeGear(), som är deklarerade men inte
definierade. Det går inte att skapa objekt direkt från denna abstrakta klass. Istället måste subklasserna ärva
från superklassen "Car".
Vi tittar på ett exempel där vi skapar två subklasser varav en (V70) inte är abstrakt.
public abstract class Volvo extends Car {
static final String brand = "Volvo";
}
class V70 extends Volvo {
static final String model = "V70";
boolean manualGearBox = true;
//Konstruktor
V70 (String colour) {
this.colour = colour;
System.out.println("Tjena V70:n här, jag är " + this.colour + ".");
}
void steer (double degree) {
//Ställ in hjulens vinklar.
}
void changeGear (int gear) {
//Växla
}
}
webbservern.se ::
- 13 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Nu har vi skapat en klass, V70, som går att instansiera. Vi ska titta på hur detta går fill.
//Skapar en ny V70.
V70 minVolvoV70 = new V70("röd");
System.out.println("Jag är en " + minV70.brand + ".");
minV70.gas();
minV70.horn();
Java-tolken svarar:
Tjena! V70:n här, jag är röd.
Jag är en Volvo.
Wrooom!
Tut tut!
Exemplet ovan gör inte anspråk på att vara det bästa upplägget när man ska modellera bilar i allmänhet
och Volvo V70 i synnerhet men förhoppningsvis illustrerar det något av kraftfullheten med OOP.
Grafiska gränssnitt
I vissa sammanhang krävs ett grafiskt gränssnitt. Javakodens komplexitet ökar naturligtvis men vi ska
ändå titta på några exempel för att få ett hum om hur det fungerar.
Vi ska använda oss av Swing vilket är ett klassbibliotek för att skapa grafiska gränssnitt som bygger
föregångaren AWT (Abstract Windowing Toolkit).
Ett enkelt fönster
Vi börjar med att skapa ett fönster helt enkelt.
import javax.swing.*;
public class SimpleFrame extends JFrame {
public SimpleFrame() {
// Top-Level Container, en JFrame
JFrame myFrame = new JFrame ("Ett fönster");
myFrame.setSize (400, 300);
myFrame.setVisible (true);
}
public static void main (String args[]) {
new SimpleFrame();
}
}
Programmet ovan är inte bra till mycket annat än att visa hur man skapar ett fönster. Vi ser att en JFrame
skapas och döps till myFrame. Denna JFrame är en så kallad Top-Level Container. En Top-Level
Container kan även bestå av en JDialog eller JApplet.
webbservern.se ::
- 14 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
I exemplet bestämmer vi fönstrets storlek och säger att det ska visas. Som standard kommer fönstret då att
hamna längst upp till vänster vilket motsvarar koordinaterna (0,0). Positionen kan bestämmas genom
setLocation (x, y). Som vanligt symboliserar x koordinaten i sidled och y koordinaten i höjdled.
Vi utvidgar nu exemplet något ger det lite mer funktionalitet.
import javax.swing.*;
public class SimpleFrame extends JFrame {
public SimpleFrame() {
// Top-Level Container, en JFrame
JFrame myFrame = new JFrame ("Ett fönster");
// Gör så att det går att stänga fönstret på vanligt vis
myFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
myFrame.setSize (400, 300);
myFrame.setLocation (200, 100);
myFrame.setVisible (true);
}
public static void main (String args[]) {
new SimpleFrame();
}
}
I exemplet ovan gjorde vi det möjligt att stänga fönstret på vanligt sätt genom användandet av
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE).
Ett fönster med innehåll
Det finns en del att hålla reda på nu när vi tar ytterligare ett steg och det är förstås nödvändigt att ha lite
grundläggande koll på detta om resultatet ska bli lyckat.
Att skapa tomma fönster kan vara kul men de är som sagt inte så användbara alla gånger. Nu ska vi lägga
in några komponenter (typ knappar, menyer, textinmatningsrutor och etiketter). Komponenter som ska
visas måste placeras i en container. JFrame, som vi redan använt, är en container (till och med Top-Level
Container som du minns) och i Swing är även en komponent en container.
Varje container har en layout manager som bestämmer hur komponenternas ska placeras ut i containern.
Det finns ett antal olika layout managers men vi nöjer oss med den som är standard för en JFrame,
nämligen Border Layout.
import javax.swing.*;
import java.awt.event.*;
public class SimpleFrame extends JFrame {
public SimpleFrame() {
// Skapar en knapp.
JButton myButton = new JButton("Klicka på mig!");
// Ger knappen ett kortkommando, Alt-K
myButton.setMnemonic(KeyEvent.VK_K);
// Skapar en JPanel att ha knappen i.
webbservern.se ::
- 15 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
JPanel myPane = new JPanel();
// Lägger till knappen i panelen.
myPane.add(myButton);
// Top-Level Container, en JFrame
JFrame myFrame = new JFrame ("Ett fönster");
// Gör så att det går att stänga fönstret på vanligt vis
myFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
myFrame.setContentPane(myPane);
myFrame.setSize (400, 300);
myFrame.setLocation (200, 100);
myFrame.setVisible (true);
}
public static void main (String args[]) {
new SimpleFrame();
}
}
I exemplet ovan kopplade vi ett kortkommando till knappen och för att göra det var vi tvungna att
importera från klassbiblioteket AWT som du ser på näst översta raden. I övrigt hoppas jag att
kommentarerna i koden räcker för att förstå vad som händer.
Hantera händelser
Vi har skapat ett fönster med en knapp men det är ingen funktionalitet kopplad till knappen. Inte så bra
kan man tycka. För att snappa upp klicket på knappen måste vi koppla ett lyssnarobjekt till komponenten.
Lyssnaren ligger och lyssnar efter klick på knappen. När den tror sig höra ett klick kan vi reagera på
användarens knappklickande och göra något passande.
I exemplet nedan ska vi göra så att man bara kan klicka på knappen en gång. Lyssnaren rapporterar det
första klicket och sen är det klippt.
import javax.swing.*;
import java.awt.event.*;
public class SimpleFrame extends JFrame {
private JButton myButton = null;
private JPanel myPane = null;
private JFrame myFrame = null;
public SimpleFrame() {
// Skapar en knapp.
myButton = new JButton("Klicka på mig!");
// Ger knappen ett kortkommando, Alt-K
myButton.setMnemonic(KeyEvent.VK_K);
// Skapar en lyssnare
myButton.addActionListener(new ButtonListener());
// Skapar en JPanel att ha knappen i.
JPanel myPane = new JPanel();
// Lägger till knappen i panelen.
webbservern.se ::
- 16 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
myPane.add(myButton);
// Top-Level Container, en JFrame
JFrame myFrame = new JFrame ("Ett fönster");
// Gör så att det går att stänga fönstret på vanligt vis
myFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
myFrame.setContentPane(myPane);
myFrame.setSize (400, 300);
myFrame.setLocation (200, 100);
myFrame.setVisible (true);
}
// Knappens händelsehanterare
public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Inaktivera knappen
myButton.setEnabled(false);
}
}
public static void main (String args[]) {
new SimpleFrame();
}
}
För att låta klassen ButtonListener komma åt knappen har vi lyft ut deklarationen av "myButton" utanför
metoden main.
För att göra ett grafiskt Javaprogram med lite mer vettig funktionalitet blir det raskt mycket kod.
Eventuellt fyller jag på med ett lite större exempelprogram senare.
Applets och JAR-arkiv
Applets har uppmärksammats en hel del, även utanför programmerarkretsar, och är Java-program som
körs i en webbläsare. Det medför att de är lite begränsade till sin natur men vi låter oss inte nedslås av det
utan kikar på ett simpelt applet.
import javax.swing.*;
public class SimpleAppletill extends JApplet {
public void init() {
getContentPane().add(new JLabel("Webbservern.se introducerar applets."));
}
}
Det är klokt att paketera appleten i ett JAR-arkiv för att effektivisera både nedladdningen och
exekveringen av appleten. I vårt fall har vi vara en .class-fil men vi gör ett JAR-arkiv ändå:
jar cf SimpleApplet.jar SimpleApplet.class
webbservern.se ::
- 17 -
19 Mar 2016 04:23
webbservern.se :: Handboken :: Programmering :: Java
Jonas Liljenfeldt
Det går alltså bra att paketera flera .class-filer i ett JAR-arkiv, byt helt enkelt ut "SimpleApplet.class" till
"*.class" eller något annat passande.
För att bädda in appleten i en webbsida när JAR-arkivet ligger i samma katalog som webbsidan skriver du
så här:
<head><title>SimpleApplet</title></head>
<body>
<applet code=SimpleApplet.class
archive=SimpleApplet.jar
width=400 height=100>
</applet>
</body>
Servlets
För en introduktion till servlets rekommenderas Java-servlets-kapitlet.
Läs mer på annat håll
Allt om JVM: http://java-virtual-machine.net/
Förslag till svensk Javaterminologi: http://www.nada.kth.se/datorer/haften/javaterminologi.html
Java-historia: http://www.ils.unc.edu/blaze/java/javahist.html
SUNs nybörjarguide: http://java.sun.com/docs/books/tutorial/getStarted/index.html
SUN undervisar om GUI och JFC/Swing: http://java.sun.com/docs/books/tutorial/uiswing/TOC.html
Den här filen ändrades senast Sunday, 13-Mar-2016 01:43:32 CET.
Respons i någon form mailas till webmaster at webbservern.se
webbservern.se ::
- 18 -
19 Mar 2016 04:23