4.4 Swing ett interaktivt grafiskt gränssnitt Våra javaprogram har hittills bara haft utdata, inga indata. Det var utdata som skrevs ut från programmet till bildskärmen antingen med metoden showmessagedialog() till Swing-rutor eller med System.out.print() till konsolen. Men hur gör man när man vill skicka indata till ett javaprogram? När det gäller Swing-dialogrutor visar följande program hur man kan göra det med metoden showinputdialog(): // SwingInput.java // Läser in två gånger via Swing-dialogrutan showinputdialog() // som är en metod definierad i klassen JOptionPane och returne- // rar den inmatade strängen // Datatypen String lagrar varje sträng som sedan skickas till // utskrift med Swing-dialogrutan showmessagedialog() import javax.swing.joptionpane; class SwingInput public static void main(string[] a) String namn, kurs; // String-variabler // 1:a inläsning: namn = JOptionPane.showInputDialog(null, "Vad heter du?", "Inläsning av namn", 3); JOptionPane.showMessageDialog(null, "Hej på dig, " + namn, "Välkomsthälsning", 1); kurs = JOptionPane.showInputDialog(null, // 2:a inläsning: "Vilken kurs läser du?", "Inläsning av kurs", 3); JOptionPane.showMessageDialog(null, "Välkommen till " + kurs + "kursen, " + namn, "Hälsning från kurs", 1); Programmet ovan producerar en dialog i två delar. Den första frågar efter namn, läser in det och ger, efter att användaren matat in ett namn och klickat på OK, följande bild: Den andra delen gör samma sak med inläsning av kurs: 82
Data som matas in från tangentbordet eller läses in från filer, är indata. Till skillnad från utdata som inte behöver mellanlagras, måste indata lagras i minnet. Hur man får indata in i datorn visar bilden på sid 41: Både indata och programkod måste lagras i RAM-minnet. Programkoden laddas från hårddisken till RAM-minnet när maskinkoden i den exekverbara filen körs. Indata däremot måste matas in under programmkörning och mellanlagras i en minnescell i RAM-minnet innan den kan vidarebearbetas av programmet. Mjukvarumässigt innebär detta att indata måste tas emot och lagras i en variabel ytterligare ett skäl till att variabeln måste vara definierad, dvs vara associerad med en minnescell av en viss storlek som är reserverad i datorns RAM-minne. Variabelns namn blir en referens till minnesadressen som sedan kan användas för att komma åt data. Medan allokeringen av minnesutrymme i regel sker under kompilering via variabeldefinition, borde inmatningen göras under exekveringen. Därför avbryts exekveringen när en inmatning ska ske. I koden förorsakas detta temporära avbrott av anropet av metoden showinputdialog() som vi ska nu förklara närmare. Inläsning med Swing Vad metoden gör kan vi se när programmet SwingInput exekveras: Den första av de fyra dialogrutorna ovan kommer upp när metoden första gången anropas i satsen namn = JOptionPane.showInputDialog(null, "Vad heter du?", "Inläsning av namn", 3); Anropet sker med fyra parametrar: Den första (null = centrerad) bestämmer rutans position på skärmen, den andra skickar en s.k. ledtext till dialogrutan, den tredje skriver text till rutans rubrik och den fjärde tar emot en konstant som bestämmer ikontypen som ska visas i rutan enligt listan på sid 65 (3 = fråge-ikon). Som man ser hamnar ledtexten "Vad heter du?" ovanpå ett tomt textffält och används där för att instruera användaren vid inmatning. Man kan alltså skicka vilken ledtext som helst till dialogrutan. Dialogrutans övriga utformning sköts automatiskt av showinputdialog() som är en fördefinierad metod i klassen JOptionPane varför den också måste anropas med punktnotation dvs klassen till vänster om punkten och tillhörande metoden höger om punkten. Observera att exekveringen av programmet alltid stoppas tillfälligt när showinputdialog() anropas i ett program. Markören sätts i dialogrutans textfält och väntar tills användaren matar in ett heltal och klickar på OK-knappen eller trycker på Enter. Men varför står metodens anrop i en tilldelningssats: namn =...? Så är det inte med utskriftsmetoden showmessagedialog(). Anropet av den står varken i en tilldelningseller någon annan sats utan fritt i en självständig sats (jfr. sid 52). Detta beror på skillnaden mellan in- och utdata som nämndes ovan: Till skillnad från utdata som inte behöver 83
mellanlagras, måste indata lagras i minnet. Programmeringstekniskt görs denna lagring i en variabel, i vårt exempel ovan variabeln namn. Denna variabel tar emot och lagrar den inmatade texten. Vi har i showinputdialog() för första gången att göra med en metod som inte bara utför vissa uppgifter ritar och utformar dialogrutan osv. utan också returnerar ett värde, det s.k. returvärdet. showinputdialog() är en metod med returvärde. Sådana metoder kan man jämföra med en låda i vilken man stoppar in parametrar och får ut ett returvärde: Parametrar Metod Returvärde showinputdialog() åtminstone i den variant vi använder i programmet Swing- Input tar in fyra parametrar och returnerar en sträng, nämligen den av användaren inmatade texten i dialogrutans textfält. Denna sträng hamnar i variabeln namn när användaren klickar på OK. Därför står anropet i en tilldelningssats, just för att ta hand om den returnerade strängen (returvärdet). Att en sträng dvs vanlig text kallas här för returvärde är inte något anmärkningsvärt. All form av data betecknas som värde som lagras i form av en sekvens av ettor och nollor i en minnescell. För ett korrekt anrop av en fördefinierad metod är det dessutom avgörande att veta vilka datatyper metodens parametrar och returvärde har. Dessa är nämligen också fördefinierade och kan inte väljas fritt. Vi måste deklarera variabeln som lagrar returvärdet med just den datatyp som metoden föreskriver för sitt returvärde. Faktum är att returvärdet till showinputdialog() är av datatypen String. Denna information står i Javas APIdokumentation vars nedladdning beskrivs på sid 46. Alltså, för att lagra returvärdet i variabeln namn och sedan kurs måste dessa variabler deklareras till datatypen String. Klassen String Klassen String är definierad i Javas Language package java.lang som är det enda paket i Javas API som inte behöver importeras. Det följer med i alla javaprogram. Klasser ur detta paket kan användas utan import-sats och utan att behöva ange paketnamnet före klassnamnet. Ett enkelt sätt att testa pakettillhörigheten är att i programmet Swing- Input skriva java.lang.string istället för String och kompilera (sid 82). Går det bra har man gissat rätt. String kan användas för att deklarera variabler som refererar till strängar vilket i programmet SwingInput har gjorts med variablerna namn och kurs som ska ta hand om indata från Swing-dialogrutor. De måste vara av typ String för att kunna lagra de strängar som metoden showinputdialog() returnerar. Objekt av typ String är i Java oföränderliga (eng. immutable). Egentligen är de namngivna konstanter som man kan referera till med variabler. De är read-only dvs kan bara läsas. Att String skrivs med stort S är enligt konventionen att skriva alla klassnamn med inledande versal, en indikation på att det är en klass. Att kalla klassen String för en datatyp som om dessa båda begrepp vore synonymer, är en sanning med modifikationer. De är inte exakt synonymer: Varje klass är en datatyp, men inte omvänt. Närmare bestämt är en klass en sammansatt datatyp. Vi kommer att förstå det bättre när vi lärt känna skillnaden mellan enkla datatyper, klasser och andra sammansatta datatyper. 84
3.4 Swingvarianter Visst är det roligare att få ut sin utskrift på skärmen i en färgglad swingruta än i det svarta kommandofönstret. Vi hade redan i vårt allra första javaprogram MySwing stiftat bekantskap med Swing (sid 52). Nu ska vi fördjupa våra kunskaper i Swing för att kunna bestämma lite mer vad gäller rutans utseende. Följande program visar ett antal varianter av Swings meddelanderutor: // SwingOutput.java // Skriver ut text i olika varianter av Swings meddelanderutor // Anropar först showmessagedialog() en gång med 2 parametrar // Anropar sedan showmessagedialog() fem gånger med 4 parametrar // Visar MESSAGE-konstanternas numeriska värden i konsolen import javax.swing.joptionpane; class SwingOutput public static void main(string[] a) JOptionPane.showMessageDialog (null, "showmessagedialog() med 2 parametrar:\n" + "Den 1:a för centrering på skärmen (null)\n" + "Den 2:a för meddelanderutans text\n" + "Ingen möjlighet att påverka rubrik eller ikontyp"); System.out.println( "\n\terror_message = " + JOptionPane.ERROR_MESSAGE + "\n\tinformation_message = " + JOptionPane.INFORMATION_MESSAGE + "\n\twarning_message = " + JOptionPane.WARNING_MESSAGE + "\n\tquestion_message = " + JOptionPane.QUESTION_MESSAGE + "\n\tplain_message = " + JOptionPane.PLAIN_MESSAGE + '\n'); JOptionPane.showMessageDialog(null, "showmessagedialog() med 4 parametrar:\n" + "Den 1:a för centrering på skärmen (null)\n" + "Den 2:a för meddelanderutans text\n" + "Den 3:e för rubrikens text\n" + "Den 4:e för ikontypen\n" + "4:e parametern = 0", "ERROR_MESSAGE", 0); JOptionPane.showMessageDialog(null, " 4:e parametern = 1", "INFORMATION_MESSAGE", 1); JOptionPane.showMessageDialog(null, " 4:e parametern = 2", "WARNING_MESSAGE", 2); JOptionPane.showMessageDialog(null, " 4:e parametern = 3", "QUESTION_MESSAGE", 3); JOptionPane.showMessageDialog(null, " 4:e parametern = -1" + "\n Ingen ikon alls", "PLAIN_MESSAGE", -1); 63
Programmet SwingOutput skickar inte bara text till meddelanderutor, utan kan även bestämma rutans rubrik och ikon, vilket vi inte hade en chans till i den första Swing-varianten. I övrigt är programmet nästan självinstruerande i den bemärkelsen att körningen visar programmets budskap. Först ska vi titta på skaran av meddelanderutor som Swing- Output producerar. De programmeringstekniska detaljerna följer efteråt. 1 2 3 4 5 6 Dessa meddelanderutor kommer upp i den ordning som radvis visas ovan, dvs översta rutan till vänster kommer först, sedan den översta till höger osv. De är resultat av sex anrop av metoderna showmessagedialog(). Att vi säger metoderna är inget skrivfel utan beror på att det verkligen är två olika metoder med samma namn som används: Båda heter showmessagedialog(), en har två, den andra fyra parametrar. Den showmessagedialog()-metod som skapar ruta 1 är den samma som vi redan använt i programmet MySwing. Den har två parametrar: null som positionerar rutan centrerad på skärmen och en text som skrivs ut i rutan. Texten är konkatenerad och går över fyra rader. Även om den är lite längre utgör den endast en parameter. Avgörande för antal parametrar är varken textens längd eller konkateneringen eller radbytena utan endast kommatecknet i parameterlistan. I denna variant har man ingen chans att påverka rutans rub- 64
rik, ikon eller andra delar. En beskrivning av denna metod finns på sid 57. Den andra showmessagedialog()-metod som skapar rutorna 2-6 är en annan variant av den, som förklaras här: Varianter av showmessagedialog() I Java kan man ha olika metoder (eller olika varianter av en metod) med samman namn precis som i det verkliga livet. Man har en funktionalitet som varierar när man tillämpar den i olika sammanhang. T.ex. att tvätta ser ganska annorlunda ut när man tvättar hår än när man tvättar bil, men ingen skulle därför kräva olika beteckningar för dessa två olika tillämpningar av verbet att tvätta. En cykelbroms är tekniskt mycket enklare än en bilbroms, ändå är båda bromsar. I Javas swingbibliotek finns det flera metoder i klassen JOptionPane som heter showmessagedialog(). De skiljer sig från varandra genom olika antal parametrar eller olika datatyper till parametrarna. Konceptet kallas överlagring av metoder och liknar överlagring av operatorer som vi stötte på när vi behandlade konkatenering (sid 61). I programmet SwingOutput förekommer showmessage- Dialog() i två olika varianter. Både kompilatorn och vi kan skilja åt dem via de olika antalen parametrar. Vilken variant som gäller aktuellt avgörs när vi anropar metoden med två resp. fyra parametrar. Den nya varianten med fyra parametrar som ger oss fler möjligheter att påverka meddelanderutans utseende, anropas förenklat vi bortser från punktnotation så här: showmessagedialog(par1, par2, par3, par4); där par står för parameter. De första två parametrarna är identiska med den första varianten av showmessagedialog(): Den första bestämmer rutans position på skärmen (null=centrerad) och den andra skickar text till meddelanderutan. Den tredje parametern par3 skickar text till rutans rubrik och den fjärde par4 tar emot en konstant som bestämmer typen av ikon som ska visas i Swing-rutan. Dessa konstanter visas i konsolen, när vi kör programmet SwingOutput. I koden anges de antingen som namngivna konstanter (i versaler) eller med sina resp. numeriska värden, se ovan. Hur ikonerna ser ut, kan man se på meddelanderutorna 2-6 på förra sidan. Ruta 1 är inte resultat av den här varianten av metoden showmessagedialog(). I ruta 2 är texten som skrivs ut (den 2:a parametern), lite längre och går konkatenerad över sex rader. Men då endast kommatecknet i parameterlistan är avgörande för antal parametrar, utgör den endast en parameter. Den den 3:e parametern bestämmer rutorna 2-6:s rubriker och vi har bara för demonstrationens skull skrivit texter som betecknar ikontyperna. Annars kan förstås skickas vilken text som helst. Det är inte denna text som bestämmer ikontyperna utan bara den 4:e parametern vars olika varianter nämndes ovan. 65