TDDD78, TDDE30, 729A85 jonas.kvarnstrom@liu.se 2018 Grafiska användargränssnitt i Java En genomgång av de viktigaste begreppen
Alternativ 2 Från början fanns AWT, Abstract Window Toolkit Stora delar har ersatts av Swing: Mer omfattande, mer flexibelt Passar bra för våra behov Illustrerar begrepp som är vanliga i GUI-programmering Ett alternativ: JavaFX Helt annan struktur (scenes, stages, nodes)
Del 1: Att använda Swing: Fönster, knappar, menyer, Layout (placering) Händelsehantering någon tryckte en knapp" Genomgående exempel: "Ordbehandlare" Del 2: Att rita på skärmen, i en egen komponent
Att öppna ett fönster 5 Fönster: Ordbehandlaren behöver komma ihåg sitt fönster Sätt fönsterstorleken, se till att fönstret visas på skärmen
Komponenter och behållare 6 En är: En komponent Något grafiskt som visas på skärmen En behållare (container) Något som kan innehålla andra komponenter Kan läggas till vid behov Hela fönstrets innehåll. utom titelrad / menyrad
Komponenter 8 Istället för att "rita": Säg till vilka komponenter som ska finnas Menyer, knappar, textfält, statusrad Swing sköter om utseende (med mera) Alla komponenter: https://docs.oracle.com/javase/tutorial/uiswing/components/componentlist.html
Knappar i Java 9 Grunden för Swing-komponenter Har två lägen, av/på Radioknappar: Bara en aktiv åt gången i varje Standardknapp Checkbox, av/på
Textkomponenter 10 Editera text med flera stilar: HTML, Abstrakt, gemensam funktionalitet En enda rad text Textarea med flera rader Speciell formattering för datum, valuta, Lösenord syns inte när de skrivs in
Ordbehandlare med komponenter 11 Lägger till flera komponenter till behållaren fönstret Inget syns på skärmen än! NU är det dags att visa fönstret och dess innehåll
Hålla reda på komponenter 12 Behåll pekare till det du vill ha senare (plocka ut texten för att spara den, )
Resultat 13 Resultat: Rätt komponenter Fel layout Liten textarea
Layout 1: Önskemål 15 Hur får vi önskad layout (positioner och storlek)?
Layout 2: Absoluta koordinater? 16 Absoluta koordinater? Fördelar / nackdelar: (+) Enkelt att förstå ( ) Inget stöd för att ändra fönsterstorlek ( ) Hur hanterar man större text? ( ) Översättningar till andra språk, där ord kan ta mer plats? Tools / Инструменти URL / nettadresse
Layout 3: Layouthanterare 17 Alternativa layouthanterare med olika layout-regler! Om ingen annan angiven: Layout vänster till höger Ingen text inskriven preferred size är minimal! Komponenter kan tala om sin önskade storlek (preferred size) : Storlek på texten i inställd fontstorlek + lite marginaler Returneras av getpreferredsize() Respekteras om det finns tillräckligt med utrymme
Layout 4: Fönsterstorlek 18 Så varje komponent vet önskad storlek men hur fick hela fönstret precis lagom storlek? frame.pack() anropar layouthanterare (layout manager) Layout: Frågar subkomponenter hur stora de vill vara Beräknar behållarens önskade storlek enligt sina layoutregler (här: "Allt i en rad") frame.pack() frame.setsize(önskad storlek)
Layout 5: Hierarkisk pack() 19 Fönster har en hierarki av komponenter pack() Varje behållare frågar sina direkta subkomponenter Fönster Jag vill vara så stor att hela menyraden får plats överst och ContentPane under den Menyrad ContentPane Meny: File Meny: Edit Meny: Help Knapp1 Knapp2 Textfält Statusrad Val1 Val2 Val3
Layout 6: Annan storlek än önskad? 20 En komponent får inte alltid begärd storlek! Kan få mer (fönstermaximering) eller mindre (ont om plats) Layouthanteraren har regler för hur utrymmet ska användas Just nu: Extra utrymme på höjden: Ska användas till textarean Extra utrymme på bredden: Menyrad: Extra plats mellan Edit och Help Knapprad: Allt vänsterjusterat Textfält, statusrad: Använder hela bredden
Exempel: MigLayout
MigLayout 1: Introduktion 22 MigLayout rekommenderas starkt! Nu: De enklaste funktionerna Se Baserad på oregelbundet rutnät
MigLayout 2: Rutor 23 Vi anger antal rader och kolumner, men (normalt) ingen storlek Vi anger vilka celler en komponent måste hålla sig inom Ungefärlig design kanske inte kommer att använda hela utrymmet! B I U Left Center Right Print Textarea Statusrad
MigLayout 3: En första layout 24 Wrap: Radbyte Span: Antal celler
MigLayout 4: Rutanpassning 25 MigLayout frågar komponenter efter önskad storlek Rutstorlek anpassas Växer för att få plats B I U Left Center Right Print Status: OK OK om komponenter inte täcker alla sina rutor!
MigLayout 5: Outnyttjat utrymme 26 Om vi drar ut fönstret: Ingen cell är bredare eller högre än absolut nödvändigt!
MigLayout 6: Hur får cellerna växa? 27 Vi förstorar fönstret Extra utrymme fördelas mellan cellerna B I U Left Center Right Print Status: OK Detta ändrar inte komponenternas storlek!
MigLayout 7: Avstånd, komponentstorlek 28 Separation Grow: Komponenter
B I U Left Center Right Print TextArea Status: OK B I U Left Center Right Print Print saknar grow TextArea Status: OK
Scrollning 30 Textfältet måste kunna scrollas Inte "inbyggt" i lägg den i en Fönster Knappar JScrollPane Statusrad Textfält
Händelsehantering: Principer 32 Hur vet vi när någon tryckte på en knapp? Tidigare kurs: Vänta på ett klick Måste veta när det kan hända Måste hantera allt själva koordinater,
Händelsehantering: Principer (2) 33 I många grafiska gränssnitt: Säg till systemet vad det ska göra vid en händelse (ex: musklick) Fortsätt själv med något annat När händelsen inträffar hanteras detta asynkront i en annan tråd Som om du har en assistent Du säger: "Om någon klickar, gör detta" Assistenten håller koll på inmatning Ser att ett klick kommer, gör vad du bad om
Lyssnare 0: Callbacks 34 Hur vet assistenten vad som ska göras? Låt knappen lagra en uppgift kod att utföra I vissa språk: Ge komponenten en funktion en callbackfunktion def task(): print( Someone pushed the button ) Vanlig funktion frame.callback = task Lagra en pekare till själva funktionen! Assistenten: Varje gång knappen trycks: frame.callback() I Java: Ge komponenten ett objekt som har funktioner (metoder) I Swing: Lyssnare (objekt som lyssnar efter händelser)
Lyssnare 1: Gränssnitt, listor 35 Typsäkerhet: Komponenten definierar gränssnitt Vad måste ett callback-objekt kunna göra? Ta hand om ett klick! Har en lista på lyssnare av denna typ
Lyssnare 2: Implementation, registrering 36 Vi implementerar konkreta lyssnare Adderar lyssnare till komponenter Detta är ett objekt Objekt kan göra saker
Lyssnare 2b: Lagring 37 Ett ClickPrinter-objekt!
Lyssnare 3: När något händer 38 När någon klickar med musen: Assistenten (händelsehanteringstråden) får info från operativsystemet Skapar ett objekt som beskriver händelsen:,
Lyssnare 4: När något händer 39 När någon klickar med musen: Assistenten (händelsehanteringstråden) får info från operativsystemet Skapar ett objekt som beskriver händelsen:, Tar reda på vilken komponent det gäller: Assistenten informerar varje lyssnare hos den relevanta komponenten Listan inkluderar vår registrerade
Lyssnare 5: Nästlad klass 40 Bekvämlighet: Kan lägga en klass inuti en annan, nästlat Färre filer att hålla reda på Lyssnarklassen behöver inte "synas" utåt
ActionListener 1: Introduktion 41 Vanlig och enkel lyssnare på högre nivå: ActionListener Anger vad som ska göras när någon vill "utföra en handling" Menyval Knapptryck Dubbelklick i lista
ActionListener 2: Exempel 42 Skapa knapp Ge den en lyssnare Lägg till den i fönstret Menyer hanteras på samma sätt Håll reda på textkomponenten Om/när vi anropas: Manipulera textkomponenten
ActionListener 3: Förenklat mellansteg 43 Inre klasser kan komma åt fält i yttre klasser
ActionListener 4: Metodreferens 44 1. ActionListener har en enda metod 3. Ange en referens till den metoden! Kompilatorn ser till att det skapas ett objekt av ActionListener-typ, som anropar makebold() 2. Implementera en metod med samma parametrar
Några viktiga lyssnarklasser 45 Knapp tryckt, menyval gjort, Slider eller scrollbar flyttad Markering i lista Musknappar Förflyttning av muspekare Tangent tryckt / släppt, tecken skrivet Skickas till komponenten som har tangentbordsfokus Komplicerat ofta är key bindings bättre Mer info på vanliga lösningar