Uke9. mars 2005 rafisk brukergresesitt med Swig og awt Litt Modell Utsy - Kotroll Del I Stei jessig Ist for Iformatikk Uiv. i Oslo UI (raphical User Iterface)-programmerig I dag Hvorda få laget et vidu på skjerme Hvorda legge ulike kompoeter i viduet (trykkapper, tekstfelter, tekst, bilder,) Kort om layout av viduer Litt om hvorda Java-programmet vårt fager opp kappetrykk Et meget ekelt Model-Utsy-Kotroll-eksempel Etter påske: rudigere om evetmodelle og oppfagig av, tastaturtrykk, musterykk, musebevegselser. Mer om hvorda få iput fra brukere via viduer (Brukere trykker på kapper, fyller ut data,..) Hvorda får brukere tak i disse data? rafikk (tegig i viduet) Om rafiske Bruker-resesitt (UI) Hvorda gjør vi det, to typer av viduer? Data i og ut i DOS-viduet oftest ikke aturlig. UI: Vi dekker bare litt, me ok til å gå videre selv. Neste alle klassee har mer e 300 metoder, me bare ett uhyre lite atall av disse yttes i praksis. Ofte tar vi utgagspukt i et eksempel som virker og utvider dette. Når ma jobber i idustrie, bruker ma ofte verktøy for dragad-drop kostruksjo av UI. Dere skal lære UI fra grue og løse oppgavee med Swig og awt. Java system bestå av et litt eldre system awt, og et litt yere system swig som er bygget på awt. Me Ikke alt er skrevet om, så vi treger i este alle programmer å importere begge (-merk javax): import javax.swig.*; import java.awt.*; (Det som begyer på J er swig, reste er awt.) Kalsse JFrame lager viduer. Ka ete bruke JFrame som de er, eller Lage e subklasse av JFrame og legge til de spesielle kode vi øsker i subklasse. Eksempel: Viduet før og etter vi dro i de
Bruke klasse JFrame som de er Subklasse av JFrame (mest valig) import javax.swig.*; import java.awt.*; class RammeDemo { public static void mai(strig[] args) { JFrame ramme = ew JFrame("JFrameDemo"); ramme.setdefaultcloseoperatio(jframe.exit_on_close); ramme.pack(); ramme.setvisible(true); ramme ramme!" # $%# & ' ( ) * $+!" +% &*',*- $!"./01232-45.% 6$% 7'$ *% *'$5 9: %# $% Stadard avslutig Et litt bedre Vidu (me fortsatt tomt) Dette bør med i alle viduer,*- $!"./01232-45.% 5 ) 6 6$% 4 *$66< 6 % 7'$ *%. <, *6, ) 6 "< *, = >666 ==),? <* 6 ; " 7*!" # &A *6< 4, * " 7*$%# 1$+"< *+% &, 6)* &5< *6 ) 6,*- $!"./01232-45.% 7'$ *% *'$5 9: %# " 7*$% B, 66C6$%DE @
Det er mage kompoeter i et vidu C-?D $*,% $6 % Hva gjør vi år vi lager et vidu foreklet versjo (flere pukter for mer kompliserte viduer seere). 1. Vi lager et objekt for viduet, subklasse av JFrame og setter av på ramme 2. Ka sette størrelse setsize(300, 200); 3. Får tak i e peker til viduesflate Cotaier lerret = getcotetpae(); 4. Lager objekter for alle de kompoetee vi vil ha i viduet og legger alle disse i i vidusflate lerret.add(..<peker til et objekt for e kompoet >,...) 5. Setter i av avslutigskappe skal virke: setdefaultcloseoperatio(jframe.exit_on_close); 6. Sier fra at viduet skal vise seg fram setvisible(true); Alle kompoete legges på vidusflate F H Noe kompoeter vi ka legge i Vi lager et pael og legger alt først i i det, deretter legger vi paelet i i vidusflate JButto: JButto kapp = ew JButto("Trykk her") E kapp som brukere ka trykke på. Parametere i kostruktøre agir tekste på kappe. JLabel: JLabel etikett = ew JLabel("Skriv i av") E etikett som ka ieholde ete tekst eller bilder. Brukes ofte som merkelapp til JText-Field. JTextField: JTextField tekstfelt = ew JTextField(30) Et tekstfelt hvor brukere ka skrive i tekst. Metode gettext() returerer tekste i feltet. JTextArea: JTextArea tekstvidu = ew JTextArea(10, 30) Et tekstvidu hvor programmet ka vise fram tekst. Metode gettext() returerer tekste i viduet. JScrollPae: JScrollPae rullevidu = ew JScrollPae(tekstvidu) Lager horisotale og vertikale rullefelt rudt et elemet. Brukes ofte i sammeheg med JTextArea som legges i i rulleviduet. Parametere er elemetet vi øsker lagt i i rulleviduet. JPael: JPael pael = ew JPael() Et pael som ka ieholde adre kompoeter. // start og avslutig som før, dette er ie i kostruktore // Først lages elemetee: JButto kapp = ew JButto("Trykk her"); JLabel etikett = ew JLabel("Skriv i av"); JTextField tekstfelt = ew JTextField(30); JTextArea tekstvidu = ew JTextArea(10, 30); JScrollPae rullevidu = ew JScrollPae(tekstvidu); // Lager et pael og legger elemetee til dette. JPael pael = ew JPael(); pael.add(kapp); pael.add(etikett); pael.add(tekstfelt); pael.add(rullevidu); // tekstviduet er ie i rulleviduet //Får tak i peker til vidues lerret og legger paelet i Cotaier lerret = getcotetpae(); lerret.add(pael);
vidu med kompoeter (ikke bra utseede) To viktige begreper Slik det blir år det kommer opp Etter å ha dradd i det (laget midre bredde). Rullefeltet frakommer år vi fyller tekstfetet Cotaier Klasse(r) som ka ieholde kompoeter og adre Cotaiere (som igje ka ieholde...) JFrame har e iebygd Cotaier som alt skal legges i som skal i i viduet, og vi får tak i de med: getcotetpae(); Pael er e (subklasse av) Cotaier Layoutmaagere Er klasser som automatisk sørger for at det vi legger i (add () ) i e Cotaier blir ordet i e bestemt rekkefølge. og at plasserige av kompoetee blir OK hvis brukere edrer størrelse på viduet. Alle Cotaiere har e bestemt stadard layoutmaager (hvis vi ikke edrer de) JPael har FlowLayout (fra vestre mot høyre i e rekke) De iebygde Cotaiere i JFrame har BoarderLayout ( fem felter : NORTH,WEST,SOUTH,EAST og CENTER) eks: pael.add(kapp,borderlayout.north); NB: Ulike LayoutMagere har add()-metoder med ulikt atall parametre. Husk å bruk de riktige (eller skjer ige tig) Layoutmaagers: Layoutmaagere: Bordelayout BoxLayout CardLayout FlowLayout ridbaglayout ridlayout SprigLayout http://java.su.com/docs/books/tutorial/uiswig/layout/layoutlist.html Bruk av BorderLayout (start og slutt som før) Cotaier lerret = getcotetpae(); lerret.setlayout(ew BorderLayout()); lerret.add(ew JButto("NORD"), BorderLayout.NORTH); lerret.add(ew JButto("SØR"), BorderLayout.SOUTH); lerret.add(ew JButto("ØST"), BorderLayout.EAST); lerret.add(ew JButto("VEST"), BorderLayout.WEST); lerret.add(ew JButto("SENTER"),BorderLayout.CENTER);
rid Layout (start og slutt som før) Vi edrer til FlowLayout (start og slutt som før) Cotaier lerret = getcotetpae(); lerret.setlayout(ew ridlayout(3, 2)); // 3 rader, 2 koloer lerret.add(ew JLabel("Forav")); lerret.add(ew JTextField(20)); lerret.add(ew JLabel("Etterav")); lerret.add(ew JTextField(20)); lerret.add(ew JLabel("Telefo")); lerret.add(ew JTextField(20)); 7 ' I = 6 66* ) $, 66 6 6% ; Cotaier lerret = getcotetpae(); lerret.setlayout(ew FlowLayout()); lerret.add(ew JLabel("Forav")); lerret.add(ew JTextField(20)); lerret.add(ew JLabel("Etterav")); lerret.add(ew JTextField(20)); lerret.add(ew JLabel("Telefo")); lerret.add(ew JTextField(20)); 7 @ Kombier flere layout i ett vidu Ferdigprogrammerte viduer for é opplysig settitle("kombilayout"); // Lager kompoetee JButto kapp = ew JButto("Trykk her"); JLabel etikett = ew JLabel("Skriv i av"); JTextField tekstfelt = ew JTextField(30); etikett.setlabelfor(tekstfelt); JTextArea tekstvidu = ew JTextArea(10, 30); JScrollPae rullevidu = ew JScrollPae(tekstvidu); // Beytter ridlayout. JPael tekstpael = ew JPael(); tekstpael.setlayout(ew ridlayout(2, 1)); tekstpael.add(etikett); tekstpael.add(tekstfelt); // Legger paelet og reste av kompoetee i JFrame-e Cotaier lerret = getcotetpae(); lerret.add(tekstpael, BorderLayout.NORTH); lerret.add(rullevidu, BorderLayout.CENTER); lerret.add(kapp, BorderLayout.WEST); Lag ett eller flere JPael, gi dem hver si layout Adder kompoetee i de ulike paelee og evt. også rett i lerret Adder Paelee i lerret import javax.swig.*; import java.awt.*; JOptioPae ieholder e rekke ferdige små-viduer De er alle modale (systemet heger til vi har svart) Klasser som ytter disse bør være subklasse av JCompoet Disse fies i ulike variater, ekle og mer omfattede parametre Problem: Vaskelig (mulig) å skrive ree orske viduer class Dialog1Test exteds JCompoet{ public static void mai(strig[] args) { Dialog1Test d = ew Dialog1Test(); Strig s = JOptioPae.showIputDialog(d, "Skriv i av."); JOptioPae.showMessageDialog(d, "Du oppga:"+ s); F H
Skal alt på orsk må vi bruke OptioDialog E kappe med reaksjo import javax.swig.*; import java.awt.*; class Dialog2Test { public static void mai(strig[] args) { Strig [] valg = { "Ja", "Nei" ; it i = JOptioPae.showOptioDialog(ull, Klikk Ja for å fortsette", Advarsel",JOptioPae.DEFAULT_OPTION, JOptioPae.PLAIN_MESSAE, ull, valg, valg[0]); Vi skal lage det aller ekleste programmet vi ka teke oss med é kapp som reagerer på at vi trykker på de ved å gi e utskrift i dos-viduet: Strig [] svar = { "reit"; C:\javaprog> javac Vidu.java JOptioPae.showOptioDialog(ull, "Du oppga: " + valg[i], Meldig", C:\javaprog> java Vidu JOptioPae.DEFAULT_OPTION, oe sa hei til meg JOptioPae.INFORMATION_MESSAE, ull, svar, svar[0]); oe sa hei til meg System.exit(0); oe sa hei til meg Hvorda lage e kapp som lytter Hva skjer ved et kappetrykk? JButto kapp; kapp= ew JButto("Hei"); kapp Hei Dette objektet vil syes på skjerme (som e kapp) Legger kappe i i viduet kapp Dette objektet syes på skjerme (som e kapp) Hei kappelytter kapp.addactiolisteer(kappelytter); forteller kjøresystemet at objektet som kappelytter peker på skal ha beskjed år oe skjer med kappe kapp. Objektet som kappelytter peker på blir satt opp som lytter ( actiolisteer ) for kappe kapp. getcotetpae().add(kapp); Koblig i kjøre-systemet kapp.addactiolisteer(kappelyttter); NYTT: Sier fra hvem som skal lytte etter trykk på dee kappe (mer på este side) actioperformed( ) Når oe trykker på kappe, kaller kjøresystemet metode actioperformed i det objektet som er satt opp som lytter for dee kappe.
objekt av de ferdiglagde klasse JButto Hei objekt av klasse Vidu (subklasse av JFrame,) Klassedatastrukture til class Vidu Vidu ( ) kapp kapp= ew JButto("Hei"); getcotetpae().add(kapp); kappelytter = ew Lytter( ); kapp.addactiolisteer(kappelytter); getcotetpae() setvisible(); setsize(... ) kappelytter mai (...) Frame vidu = ew Vidu(); vidu Vidu-objektet (kostruktøre) order så reste selv. objekt av klasse Vidu (se forrige side) objekt av klasse Lytter (implemets actiolisteer) actioperformed (... ) System.out.pritl("Noe sa hei til meg"); Fullstedig mii-program med bare e kapp (og utskrift i DOS-viduet) import java.awt.*; import java.awt.evet.*; import javax.swig.*; public class Vidu exteds JFrame { private JButto kapp; private Lytter kappelytter; public Vidu( ) { super("hei test"); Cotaier samlig = getcotetpae(); samlig.setlayout(ew FlowLayout()); setsize(300,200); kapp= ew JButto("Hei"); samlig. add(kapp); setdefaultcloseoperatio(jframe.exit_on_close); setvisible(true); kappelytter = ew Lytter( ); kapp.addactiolisteer(kappelytter); // slutt Vidu kostruktør Metode getcoteetpae() i JFrame returerer bildeflate til dette viduet Her lager vi et lytterobjekt Her kobles kappe opp mot dette lytterobjektet ; Program forts. public static void mai(strig[] args) { JFrame vidu = ew Vidu(); //slutt mai class Lytter implemets ActioListeer { public void actioperformed(actioevet e) { System.out.pritl("Noe sa hei til meg"); // slutt class Lytter // slutt class Vidu C:\javaprog> javac Vidu.java C:\javaprog> java Vidu Noe sa hei til meg Noe sa hei til meg Noe sa hei til meg C:\javaprog> Kjørig (Widows) Dette er lytterklasse! @
Nytt, viktig og ekelt eksempel: Mii-program med tre deler Kotroll Sørger for at datastrukture blir maipulert på riktig måte (økt med é hver gag kappe tykkes) Sørger for at foradriger i datastrukture blir skrevet ut. Utsy E kapp som gir beskjed til kotrolle hver gag de blir trykket på Ka skrive ut e tekst som agir hvorda datastrukture å ser ut (hvor stort tallet er blitt) Modell Datastrukture er bare ett tall med to operasjoer (legg til é og les av) kapptrykket() datastrukt Objekt av class Kotroll Kotroll(){ datastrukt = ew Modell(4); vidu = ew Utsy(this); it tall; datastrukt.oppdater(); tall= datastrukt.hetnyverdi(); vidu.skrivut(tall); it atall; Modell (it tall) { atall = tall; vidu Objekt av class JButto kapp Utsy (Kotroll kotrl) super("tre deler eksempel 1"); ktrl = kotrl; ktrl tekst = ew JLabel("Her kommer.. "); getcotetpae(). add(tekst); kapp= ew JButto("Øk"); getcotetpae(). add(kapp); Objekt av class JLabel tekst it hetnyverdi() { retur atall; kapp.addactiolisteer(ew KappLytter); oppdater() { atall ++; skrivut(it tall) { tekst.settext( Tallet er + tall); F Objekt av class Modell Objekt av class Utsy H public class Kotroll { Modell datastrukt; Utsy vidu; Kotroll(){ datastrukt = ew Modell(4); vidu = ew Utsy(this); public static void mai(strig[] args) { ew Kotroll(); //ed mai public void kapptrykket(){ it tall; datastrukt.oppdater(); tall= datastrukt.hetnyverdi(); vidu.skrivut(tall); // slutt Kotroll - mai er miimal - Kotroll-kostruktøre lager de to adre objektee - actioperformed gjør hadligee (i et eget objekt som lages i Utsyet) class Utsy exteds JFrame { JButto kapp; JLabel tekst; Peker tilbake til Kotroll-objektet Kotroll ktrl; class KappeLytter implemets ActioListeer { // idre klasse public void actioperformed(actioevet e) { ktrl.kapptrykket(); public Utsy(Kotroll kotrl){ og her brukes de super("tre deler eksempel 1"); setfot(ew Fot("Serif",Fot.PLAIN,1)); setsize(400,100); getcotetpae().setlayout(ew FlowLayout()); // slutt class Utsy tekst = ew Label("Her kommer e meldig"); getcotetpae().add(tekst); kapp= ew Butto("Øk"); getcotetpae().add(kapp); kapp.addactiolisteer(ew KappeLytter()); setdefaultcloseoperatio(jframe.exit_on_close); setvisible(true); // slutt Utsy kostruktør public void skrivut(it tall){ tekst.settext( Tallet er å: + tall + );
Datastruktur Kjøresystemet Objekt av class JButto J6 Objekt av class JLabel class Modell{ private it atall; Modell (it tall) { atall = tall; public it hetnyverdi( ) { retur atall; public void oppdater( ) { atall ++; // slutt klass Modell; Som sagt: Ekleste datastruktur vi ka teke oss Objekt av class Kotroll Kotroll() datastrukt = ew Modell(4); vidu = ew Utsy(this); kapptrykket() public void kapptrykket(){ it tall; datastrukt.oppdater(); tall= datastrukt. hetnyverdi(); vidu.skrivut(tall); datastrukt vidu kapp tekst Utsy (Kotroll kotrl)... tekst = ew JLabel("Her kommer e meldig"); getcotetpae().add(tekst); ktrl kapp= ew JButto("Øk"); getcotetpae().add(kapp); kapp.addactiolisteer(ew KappLytter()); objeket av class KappLytter actioperformed (ActioEvet e) { ktrl.kapptrykket(); skrivut(it tall) { lab.settext( Tallet er : + tall); class KappLytter (idre klasse) Objekt av class Utsy " ) >) 6$ % Flere kapper: Flere lytterklasser: 1. Lag e metode som beskriver hva som skal gjøres år e bestemte hedelser itreffer. Eksempel: public void actioperformed(actioevet e) {... Metodee skal kalles av Java og må ha et helt bestemte av som er forhådsbestemt av Java-biblioteket (polymorf metode).!"# $%%&'(" #)# $%%&'( 2. Deklarer e lytterklasse ( class MiLytter ) som ieholder hedelsesmetode - dette sikres ved at lytterklasse implemeterer et bestemt iterface. 3. Lag et objekt av lytterklasse og sed referase til dette objektet til de kompoete (f.eks. kappe) som dette objektet skal lytte på. Eksempel: kappe.addactiolisteer(ew MiLytter()); este et frittsvevede objekt (bare kotakt fra Rutime-systemet) *)' *6 6 K4 (= ) 66 ' >66) $% class Stopp implemets ActioListeer { public void actioperformed(actioevet e) { setvisible(false); // omliggede vidu System.exit (0); // ed ReB class NoeSkjer implemets ActioListeer { public void actioperformed(actioevet e) {..... // ed WaitB
*, - ( +2 33 class Forskjellig implemets ActioListeer { public void actioperformed(actioevet e) { if (e.getsource( ) = = stoppkapp) { setvisible(false); System.exit (0); else if (e.getsource( ) = = ekapp) {... &'(* +!"# $%%&'( #)# $%%&'( ; &'(* +( $$$./*%!!0 $1% $%%&'( class ForskjelligLytter implemets ActioListeer { public void actioperformed(actioevet e) { // år CR i tekstfeltet if (e.getsource( ) = = atall) { Strig st = atall.gettext( ); st.seteditable(false); else if... // slutt actio Performed // slutt lytterklasse @ Rullegardier: JComboBox!-'L> M!-'L$% > 0$C+% > 0$C3+% > 0$C7 +% > 0$CB<> +% >.'$,% > 04 $*4> % -*4> 04 # *'5-$0.%# 5 M$5 %0$%,$N*$C+%% #, OO,$N*$C3+%% #, ((,$N*$CB<> +%% # M>,$N*$C7 +%% # M F