725G61 - Laboration 8 Ett enkelt GUI. Sahand Sadjadee och Johan Falkenjack



Relevanta dokument
Objektorienterad Programkonstruktion. Föreläsning 3 9 nov 2015

Föreläsnings 11 - GUI, Händelsestyrda program, MVC

ITK:P1 Föreläsning 4. Grafiska gränssnitt i Java. AWT-komponenter

Objektorienterad Programkonstruktion. Föreläsning 3 7 nov 2016

Kort om klasser och objekt En introduktion till GUI-programmering i Java

Laboration 10 - Eclipse

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

Föreläsning 3: Händelsestyrda program och användargränssnitt

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 18

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 3

Lab5 för prgmedcl04 Grafik

Malmö högskola 2007/2008 Teknik och samhälle

Föreläsning 15 (16) Historik (java.awt) Historik (javax.swing) Introduktion till Swing

Eclipse. Avsikt. Nu ska ett fönster liknande figuren till höger synas.

Programmeringsteknik II - HT18. Föreläsning 6: Grafik och händelsestyrda program med användargränssnitt (och Java-interface) Johan Öfverstedt

725G61 - Laboration 7 Implementation av ett API. Johan Falkenjack

Denna vecka. Idag. Grafiskt användarsnitt. Vi kommer att se

NetBeans 5.5. Avsikt. Projektfönster

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 7 Erik Nilsson, Institutionen för Datavetenskap, LiU

Objektorienterad programmering med Java Swing: Händelser, lyssnare och applets

Grafiska användargränssnitt i Java

Objektorienterad Programmering DAT043. Föreläsning 5 29/1-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

NetBeans 7. Avsikt. Projektfönster

Malmö högskola 2007/2008 Teknik och samhälle

Arv och Grafiska Användargränssnitt

Grafiska användargränssnitt i Java

Malmö högskola 2007/2008 Teknik och samhälle

Här beskrivs Eclipse, den programutvecklingsmiljö som utnyttjas i programmeringskurserna. Mera information finns på:

TUTORIAL: KLASSER & OBJEKT

1 Grafiska komponenter

2I1049 Föreläsning 8. Grafiska gränssnitt i Java. AWT-komponenter. Grafiska gränssnitt, Java interface och händelsehantering

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Editering, Kompilering och Exekvering av Javaprogram

Laboration 1 Introduktion till Visual Basic 6.0

Tentamen för kursen Objektorienterad programvaruutveckling GU (DIT010)

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 5. Laboration 4 Lådplanering Exempel på grafik, ett avancerat program Frågor

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Swing. MER Java Foundation Classes (JFC) Hur lära sig? Vad är farorna. LayoutManagers. Exempel på några av komponenterna

Swing. MER Java Foundation Classes (JFC) Vad är farorna. Hur lära sig? LayoutManagers. Exempel på några av komponenterna

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Laboration 1 - Grunderna för OOP i Java

DI-institutionen Sid 1 av 6 Hans-Edy Mårtensson Sten Sundin

Verktyg och Utvecklingsmiljö. Jochim von Hacht

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

Laboration 15 Grafiskt användargränssnitt

Eclipse. Kort genomgång

Gran Canaria - Arbetsbeskrivning knapplänkar (Mediator 8)

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

PROGRAMMERINGSTEKNIK TIN212

Lektion Händelsehanterare

KARLSTADS UNIVERSITET 12/8/09 informatik & datavetenskap Johan Öfverberg, Kerstin Andersson Laboration 4, ISG A04 och DVG A08 HT-09

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

ID1004 Laboration 3, 5-6 November 2012

Instruktion för användande av Citrix MetaFrame

OOP Objekt-orienterad programmering

Objektorienterad programmering i Java I

JAVA Mer om klasser och objektorientering

Projektuppgift - Biblioteket

Objektorienterad programmering med Java Swing. Programexempel. Swing och AWT AWT. = Abstract windowing toolkit

Laboration 10 - NetBeans

Projektuppgift - Gymmet

Paneler - VCPXX.2. Programmeringsmanual för VCP-paneler. Revision 2

Lab1 Introduktion. 1 Syfte. 2 Innehåll Win32API Skapa trådar Kritiska sektioner Mailslothantering. 3 Förberedelse & Tips

Kort repetition. Programmeringsteknik för Bio1 och I1. Vad ska vi lära oss idag? Ett exempel

Telia Connect för Windows

DUGGA: Objektorienterade applikationer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

CliMate följer Tre-lager-arkitektur. Domänobjekt - domänlogiklagret. Viktiga domänklasser i CliMate. De tre lagren. Paketen i CliMate:

Vad utmärker ett bra användargränssnitt?

Inledande programmering med C# (1DV402) Ditt första C#-program med Visual Studio

Handledning för Installation av etikettskrivare

Mobila applikationer. Mobil applikationer. Java ME. Konfigurationer. Grunderna i ME

Mer om grafiska komponenter. Händelsestyrda program

Juni 2003 PlanCon Viewer Handledning PlanCon PROJEKT

ITK:P1 Lektion 4. Lektion 4. Lektion 4. Att implementera en spelidé i Java. DSV Peter Mozelius

3.5 Visuell programmering

Krav: * Filen MpUpdate.exe får inte köras när du startar denna uppdatering.

DAT043 - föreläsning 8

FrontPage Express. Ämne: Datorkunskap (Internet) Handledare: Thomas Granhäll

Design och konstruktion av grafiska gränssnitt

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Verktyg och Utvecklingsmiljö. Föreläsning 2 Eclipse

Dagens program. Programmeringsteknik och Matlab. Vad är arv? Vi ärver från GregorianCalendar. Kan vi bygga vidare på existerande klasser?

MVC-mönstret. model-view-control i Swing

Objektorienterad programmering D2

DAT043 - Föreläsning 7

DD2385 Programutvecklingsteknik Några bilder till föreläsning 1 24/ Kursöversikt Javarepetition/Javaintroduktion

Lathund för BankID säkerhetsprogram

Att använda Java SE JDK 6

Föreläsning 7. Grafiska användargränssnitt

"Är en"-relation. "Har en"-relation. Arv. Seminarium 2 Relevanta uppgifter. I exemplet Boll från förra föreläsningen gällde

Windows Forms Winstrand Development

Instruktioner för uppdatering från Ethiris 4.10 till 5.x

Symprint Snabbstartsguide

Programutveckling med Java Development Kit. (JDK 1.1.x) och Programmers File Editor (PFE 7.02)

Laboration med Internet och HTML

Programmering A C# VT Ett kompendie över Programmering A (50p) i c# Stefan Fredriksson

TENTAMEN. Kurs: Applikationsutveckling i Java 5DV135. Ansvarig lärare: Johan Eliasson. HT12 Datum: Tid: kl

Transkript:

725G61 - Laboration 8 Ett enkelt GUI Sahand Sadjadee och Johan Falkenjack December 20, 2013

1 Inledning I de tidigare labbarna har ni fått lära er grundläggande programmering och objektorientering samt hur ni dokumenterar er kod. I den här labben kommer vi använda en del terminologi ni förväntas ha lärt er vid det här laget för att göra något mer verklighetsnära. 2 Vad är GUI? GUI står för Graphical User Interface och det är något ni använder er av varje dag. Ett GUI är det ni stöter på när ni startar ett program. I operativsystem som Windows och OS X är GUI:t mer eller mindre fönsterbaserat, dvs programmen representeras som fönster på en bakgrund. I operativsystem som ios på iphone/ipad/ipod och Android på mobiltelefoner fungerar GUI:n annorlunda men det är den grafikbaserade, till skillnad från textbaserade, interaktionen som gör att det kallas för ett GUI. I labb 4 byggde ni upp ett mer traditionellt textbaserat UI där användaren fick interagera med systemet genom att skriva olika kommandon. Nu är det dags att testa att bygga ett grafiskt gränssnitt, där användaren istället använder t ex knappar för att skicka olika kommandon till systemet. Att bygga grafiska gränssnitt är inte trivialt, det är faktiskt så komplicerat att det finns flera hela kurser i specifikt GUI-programmering (ofta heter de något i stil med Interaktionsprogrammering) och det finns även kurser i hur själva designen av GUI:n ska se ut (de brukar heta något i stil med Interaktionsdesign). Ofta säger man att i utvecklingen av ett nytt program läggs 90 % av själva programmeringstiden på GUI:t. Även om detta är en grov förenkling och beror väldigt mycket på vad det är för typ av program som skapas, finns det en viss sanning i det. I den här labben ska ni dock bara följa instruktionerna rakt av för att se ungefär hur processen att bygga ett GUI ser ut. Syftet är alltså inte främst att ni ska lära er bygga upp GUI:n, utan att ni ska få en känsla för hur GUI:n hänger ihop med det ni har gjort tidigare i kursen och hur man kan bygga upp och förpacka körbara program som är lite mer lika de ni alla är vana vid att använda. 3 Swing I Java byggs de flesta grafiska gränssnitt idag med Swing. Swing är ett paket med klasser baserat på det äldre AWT (Abstract Window Toolkit). I det gamla AWT såg Java-program ungefär likadana ut på alla system och var enligt många ganska fula och klumpiga. Med Swing kan man variera sina GUI:n mer och skapa program som ser ut som program normalt ser ut i den aktuella miljön (t.ex. Windows XP vs. Windows 8 vs. OS X). Dessa olika utseenden kallas "look-and-feel" och beroende på om ni gör den här labben i Windows, i OS 1

X eller till och med i Linux kommer resultatet, dvs utseenedet på fönstret och knapparna, variera lite. 4 Att skapa själva fönstret Vi ska nu skapa ett grafiskt program som använder en del av vår kod från Labb 6. Det GUI vi bygger i den här labben är generellt sett avsett att köras på ett fönstersystem som Windows eller OS X. Det kommer dock se lite olika ut i de olika systemen, pga olika look-and-feel, så oroa er inte om det inte ser exakt ut som på bilderna nedan. 4.1 Om JFrame Klassen JFrame är en så kallad container, en klass vars uppgift är att innehålla andra Swing-komponenter. I Swing-termer är en JFrame förälder (parent) till alla komponenter som ligger i JFrame:n. Vi pratar då inte om förälder i klassmeningen, att alla andra komponenter ärver av JFrame, utan att programmets organisation är hierarkisk och att alla komponenter som placeras i en JFrame visuellt, också logiskt tillhör denna JFrame, och man kan komma åt en komponents JFrame genom speciella metoder. Rent visuellt ger JFrame en tom rektangel med en titelrad överst, det vi i dagligt tal kallar ett fönster. Titelraden är det som ligger högst upp i alla fönster och innehåller normalt sett programmets titel, samt knappar för att minimera, maximera och stänga fönstret. Innan några inställningar gjorts eller några komponenter lagts till gör Swing automatiskt alla komponenter så små som möjligt, det kommer ni märka i Uppgift 8.1. JFrame kan användas på två sätt, antingen kan man skapa ett objekt av klassen och manuellt lägga till element, eller så kan man göra som i Uppgift 8.1 och skapa en subklass som är specialanpassad för ett visst syfte. Generellt sett betraktas den andra lösningen som bättre, då den tydliggör att vi skapar en specifik version av JFrame för ett visst syfte och vi kan förhållandevis lätt återanvända denna. Verkar det knöligt? Oroa er inte, vi kommer ta ett steg i taget och ni behöver inte förstå allting i detalj. Syftet med den här labben är, till skillnad mot de tidigare, mer fokuserat på att ni ska få pröva på att skapa ett GUI, snarare än att ni ska lära er exakt hur alla komponenter fungerar. 2

UPPGIFT 8.1 Skapa ett nytt paket edu.liu.ida.svp725g61.lab8. I detta paket ska ni skapa en ny klass Facade som ärver av klassen javax.swing.jframe. Klassen ska i nuläget inte innehålla någon kod utöver detta. Skapa sedan en klass som heter Main i samma paket. Klassen Main ska ha en main-metod som skapar en ny instans av Facade samt anropar metoden setvisible() med argumentet true på den nya instansen. Kör sedan klassen Main. Ni borde nu få upp ett litet, och tomt, fönster, t.ex. uppe i vänstra hörnet av skärmen. Fönstret borde, i Windows, se ut ungefär som i Bild 1. Bild 1: Efter Uppgift 8.1. I Uppgift 8.1 skapade ni ett första fönster. Eftersom ni inte skrev någon kod i klassen Facade har ni säkert räknat ut att vad vi kört är ett standardfönster som exakt motsvarar klassen javax.swing.jframe. Vi ska nu modifiera det här fönstret lite. OBS! När ni stänger det nyskapade fönstret betyder det inte att Java-processen bakom fönstret avslutas, för att stänga av den processen måste ni trycka på den lilla röda stopp-knappen i Consolefönstret i Eclipse. 3

UPPGIFT 8.2 Inne i klassen Facade ska ni nu skapa en ny metod init(), som inte har något returvärde och inte tar några parametrar. Följande kod ska finnas i init(): // setting size, location, title and // default behavior on close. this.setsize(200, 200); this.setlocation(100, 100); this.settitle("untitled"); this.setdefaultcloseoperation(jframe.hide_on_close); // --- end of setting size, location, title and // default behavior on close. Skapa sedan en konstruktor för Facade som inte tar några argument och som bara anropar init(). Kör Main igen och se vad det blir för skillnad. Det borde se ut ungefär som i Bild 2. Gör nu följande ändringar i koden: Ändra storleken från 200x200 till 640x480, placeringen från 100,100 till 250,250 och namnet på fönstret till "Student Registration Form". Ni ska också ändra standardbeteendet när fönstret stängs till JFrame.EXIT_ON_CLOSE. Efter den sista ändringen kommer ni inte längre behöva stoppa Java-processen manuellt (inifrån Eclipse) utan den kommer avslutas när fönstret stängs. Det kommer se ut ungefär som i Bild 3 Bild 2: Efter första ändringarna i Uppgift 8.2. 4

Bild 3: Efter sista ändringarna i Uppgift 8.2. Notera förändringen i skala från tidigare bilder. 5 Lägga till komponenter Swing består av ett antal olika komponenter, avsedda för olika syften och med speciella utseenden. Med undantag av JLabel, som visar en text, och några få andra komponenter för att visa information, t.ex. bilder, så är de flesta andra komponenter interaktive, så att användaren kan interagera med dem på olika sätt. De kan t.ex. användas både för att visa information eller skicka kommandon eller data från användaren till programmet. Några sådana komponenter är t.ex. JTextField, JTextArea och JButton, vilka kommer användas i nästa uppgift. Ni har nu skapat fönstret i ett rimligt format, med en rimlig placering, med ett bra namn och med det förväntade avslutningsbeteendet. Nu ska ni lägga till lite fler grafiska komponenter i fönstret. 5

UPPGIFT 8.3 Nu ska ni lägga till koden från Bild 4 och Bild 5 på lämpliga ställen i Facadeklassen. Ni ska också lägga till koden från Bild 6 och Bild 7 i metodkroppen för metoden init(). När det är gjort bör fönstret se ut som i Bild 8. Ge sedan JTextField-elementen för förnamn, efternamn och födelseår standardvärden (använd ditt eget namn och födelseår), dvs värden som visas från början när komponenten visas (men som användaren naturligtvis kan gå in och ändra om han eller hon vill). Använd metoden settext() på lämpliga ställen i init() för att åstadkomma detta. När detta är gjort bör programmet se ut ungefär som i Bild 9 direkt när du startar det. // imports import javax.swing.jbutton; import javax.swing.jlabel; import javax.swing.jtextarea; import javax.swing.jtextfield; Bild 4: Imports att lägga till i Uppgift 8.3. 6

// declaring component variables private JLabel firstnamelabel; private JLabel familynamelabel; private JLabel birthyearlabel; private JTextField firstnametextfield; private JTextField familynametextfield; private JTextField birthyeartextfield; private JButton registerbutton; private JButton showallbutton; private JLabel outputlabel; private JTextArea outputtextarea; // end of declaring component variables Bild 5: Instansvariabler att lägga till i Uppgift 8.3. // creating and adding new components to the main frame this.setlayout(null); firstnamelabel = new JLabel("Name"); firstnamelabel.setsize(100,20); firstnamelabel.setlocation(20,20); firstnametextfield = new JTextField(); firstnametextfield.setsize(300,20); firstnametextfield.setlocation(120,20); familynamelabel = new JLabel("Familyname"); familynamelabel.setsize(100,20); familynamelabel.setlocation(20,50); Bild 6: Kod att lägga till i init() i Uppgift 8.3. 7

familynametextfield = new JTextField(); familynametextfield.setsize(300,20); familynametextfield.setlocation(120,50); birthyearlabel = new JLabel("Birth Year"); birthyearlabel.setsize(100,20); birthyearlabel.setlocation(20,80); birthyeartextfield = new JTextField(); birthyeartextfield.setsize(300,20); birthyeartextfield.setlocation(120,80); registerbutton = new JButton("Register"); registerbutton.setsize(120,30); registerbutton.setlocation(500, 20); showallbutton = new JButton("Show All"); showallbutton.setsize(120,30); showallbutton.setlocation(500, 60); outputlabel = new JLabel("Output"); outputlabel.setsize(200,20); outputlabel.setlocation(20, 110); outputtextarea = new JTextArea(); outputtextarea.seteditable(false); outputtextarea.setsize(600,300); outputtextarea.setlocation(20, 130); this.add(firstnamelabel); this.add(firstnametextfield); this.add(familynamelabel); this.add(familynametextfield); this.add(birthyearlabel); this.add(birthyeartextfield); this.add(registerbutton); this.add(showallbutton); this.add(outputlabel); this.add(outputtextarea); // end of creating and adding new components to // the main frame Bild 7: Kod att lägga till i init() i Uppgift 8.3. 8

Bild 8: Efter första delen av Uppgift 8.3. 9

Bild 9: Efter sista delen av Uppgift 8.3. 10

6 Funktionalitet Nu har vi fixat den faktiska layouten, dvs utseendet på programmet. Alla element som vårt program ska innehålla finns på skärmen. De saknar dock all funktionalitet, så det ska vi göra något åt nu. För att något ska hända när vi t.ex. trycker på en knapp så måste vi lägga till en så kallad lyssnare (listener) som fångar en viss händelse (event). När man lägger till en lyssnare skapar man ett nytt objekt av den aktuella lyssnarklassen och överlagrar eventuella metoder som behövs, via en konstruktion vi inte stött på tidigare i kursen. Ni får dock koden av oss och behöver bara implementera innehållet i metoden, så det gör inget om ni inte förstår exakt hur strukturen är uppbyggd. Vi ska också visa en dialogruta. En dialogruta används för att föra en dialog med användaren angående en specifik uppgift. Dialogrutor är containers precis som JFrame men körs bara under perioder av programmets hela körtid, för att hantera specifika saker. T.ex. kan man ha en dialogruta som utfärdar en varning, informerar om att något gått fel (ett felmeddelande), eller informerar om att något har lyckats. Mer avancerade dialogrutor kan t.ex. hantera sparande av en fil, utskrift, eller som dialogrutan ni använder i Eclipse i Uppgift 8.7, export av data till ett annat format. Vi ska skapa några mycket enkla dialogrutor i vårt program, enbart för att visa upp meddelanden för användaren. För detta ska vi använda metoden JOptionPane.showMessageDialog() som visar ett fönster med en text och en OK-knapp som stänger fönstret. 11

registerbutton.addactionlistener(new ActionListener() { @Override public void actionperformed(actionevent e) { // This method is called as the Register button // is clicked by the user. }); } // TODO: implement the students // information storage here. Bild 10: Kod att lägga till i init() i Uppgift 8.4. UPPGIFT 8.4 Börja med att importera klasserna java.awt.event.actionevent och java.awt.event.actionlistener i er Facade-klass. Lägg sedan till koden i Bild 10 på lämpligt ställe i metoden init(). Skapa sedan en ArrayList<Student> som en instansvariabel i Facade-klassen där Student är klassen från labb 6 (ni kan kopiera klassen till lab8-paketet eller importera klassen). Gå sedan till TODO-markeringen i den nya metoden actionperformed(). Ni ska här hämta ut värdena från de tre textfälten med gettext()-metoden och skapa ett nytt Student-objekt med hjälp av de tre värdena. Kom ihåg att ni kan använda Integer.parseInt() för att konvertera en sträng till ett heltal. Detta nya Student-objekt ska läggas till den ArrayList<Student> som ni nyss skapade, och som tillhör instansen av Facade. När det nya Student-objektet lagts till i listan skall följande rad läggas till sist i actionperformed(), för att visa ett meddelande för användaren att operationen lyckats: JOptionPane.showMessageDialog(null, "The new student registered successfully"); När ni nu kör programmet och klickar på Register-knappen bör det se ut ungefär som i Bild 11. 12

Bild 11: Efter Uppgift 8.4. Nu kan vi lägga till studenter i vårt system. Vi vill dock kunna se vilka studenter som är tillagda också, annars är inte programmet särskilt användbart. UPPGIFT 8.5 Lägg till en lyssnare till, den här gången ska lyssnaren läggas till för showallbutton men i övrigt motsvara den vi lade till registerbutton i Uppgift 8.4. Ta dock bort hela metod-kroppen (koden inuti metoden) från den nya actionperformed()-metoden, dvs vi vill inte att samma sak ska hända när vi klickar på den här knappen. I den nya actionperformed()-metoden ska vi istället lägga till en kropp som skapar en sträng och lägger till den i outputtextarea (använd metoden settext() för att lägga till texten). Strängen ska representera information om samtliga tillagda studenter, samt antalet studenter i listan, och vara formaterad i stil med Bild 12. 13

Bild 12: Efter Uppgift 8.5. Det enda som är kvar att lägga till i vårt lilla program nu är lite felhantering. UPPGIFT 8.6 Lägg till kontroller vid registreringen av nya studenter som kontrollerar följande två regler: 1. Inget inputfält får vara tomt, dvs användaren måste ange både förnamn, efternamn och födelseår. 2. Födelseåret måste vara ett heltal. Om någon regel bryts ska ett lämpligt felmeddelande visas med hjälp av JOptionPane, på samma sätt som när vi visade upp ett meddelande att allt gått bra, i Uppgift 8.4, och ingen ny student ska skapas. Exempelvis som i Bild 13. 14

Bild 13: Efter Uppgift 8.6. 7 Distribution av kod Nu har vi skapat ett litet program med ett grafiskt gränssnitt som låter oss registrera studenter. Om vi nu skulle vilja distribuera detta som ett körbart program så skapar vi en så kallad körbar jar-fil. En jar-fil är ungefär som en exe-fil i Windows, och kan köras på alla datorer med Java installerat. För att skapa en körbar jar-fil i Eclipse klickar man på File->Export. Man får då upp en dialog där man kan välja olika typer av export. Klicka på mappen Java, därunder finns alternativet Runnable JAR file, markera det och klicka sedan på Next. Välj Launch Configuration ur drop-down-menyn för att tala om vilken av klasserna som innehåller er main-metod, där programmet startas, detta är i vårt exempel klassen Main. Välj sedan en lämplig destination och ett filnamn för er JAR, exempelvis lab8.jar och spara i en katalog på ert studentkonto. Se till att alternativet Extract required libraries into generated JAR är markerat. UPPGIFT 8.7 Skapa en körbar jar-fil för koden i Labb 8 och testa att ni kan köra programmet genom att dubbelklicka på JAR-filen istället för att starta programmer inifrån Eclipse. 15

8 Redovisning Lämna in koden för Facade, Main och Student-klassen (den ni återanvände från labb 6 - handledarna kommer inte bedöma den här klassen igen, men behöver den för att testköra ert system), samt den genererade jar-filen. Tänk på att som vanligt kommentera er kod noga (ni behöver inte lägga till kommentarer i den kod ni klippt in från uppgifterna här, men den kod ni själva skrivit ska vara kommenterad). 16