270 likes | 388 Views
Grundlæggende programmering Forår 2002. Forelæsning 9 onsdag 10/4 2002 kl. 9:15 – 12:00. Dagens program. Det praktiske Java applets Grafiske komponenter og hændelsesstyret programmering (SGUI) Grafiske standardkomponenter i Java (AWT). Det praktiske.
E N D
Grundlæggende programmeringForår 2002 Forelæsning 9 onsdag 10/4 2002 kl. 9:15 – 12:00
Dagens program • Det praktiske • Java applets • Grafiske komponenter og hændelsesstyret programmering (SGUI) • Grafiske standardkomponenter i Java (AWT)
Det praktiske • Kursusevaluering: Husk at deltage i kursusevalueringen. Tidsfristen for besvarelse er fredag d. 12 april klokken 18.00. Nærmere oplysninger har I fået per email.
Appletter er lavet for at man giver web sider fuld programmeringsmæssig generalitet. Kunne vise andre fil formater på HTML sider, f.eks. tekniske tegninger, regneark, ... Lave mere fleksibelt indput fra en hjemmeside end det er muligt med almindelige indput knapper i HTML Animationer Appletter virker ved at browseren henter en ”.class” fil fra web serveren, laver et objekt ud fra den klasse, og kalder dette objekts metoder. Begrænsninger Ikke noget System.out. Ikke noget med filer o.lign. Generelt ikke adgang til den maskine den kører på Kan kun kommunikere med web serveren. Appletter behøves ikke at være skrevet i Java. En del andre programmeringssprog kan i dag oversættes til ”.class” filer. Appletter
I HTML er der en tag der hedder APPLET. Den skal have 4 argumenter. Højde&bredde CODE angiver navnet på ”.class” filen CODEBASE angiver hvor der skal ledes hvis man skal finde andre hjælpe klasser. <HTML> <HEAD> <TITLE>KlikKlak Applet</TITLE> </HEAD> <BODY> <H1>KlikKlak Applet</H1> <HR> <APPLET CODE="KlikKlak.class" WIDTH=200 HEIGHT=100 CODEBASE=.> </APPLET> <HR> </BODY> </HTML> HTML for appletter
Appletter – Java programmer i WWW Fra browseren beder man om siden http://www.it-c.dk/people/kasper/minSide.html Browseren henvender sig til www.it-c.dk, og beder om siden people/kasper/minSide.html Browseren fortolker der enkelte dele i html siden. Der er blandt andet en applet, der angiver at den skal bruge ”minApplet.class” Browseren henvender sig til www.it-c.dk, og beder om people/kasper/minApplet.class • Browseren checker at den klasse den får er en applet klasse. Browseren skaber et objekt, og kalder så: • Dens init metode • Dens start metode • Dens paint metode www.it-c.dk web server people/kasper minApplet.class minSide.html
import java.applet.Applet; import java.awt.*; public class AppletTest extends Applet { public void paint(Graphics g) { // simple text displayed on applet g.setColor(Color.white); g.fillRect(0, 0, 200, 100); g.setColor(Color.black); g.drawString("Sample Applet", 20, 20); g.setColor(Color.blue); g.drawString("created by BlueJ", 20, 40); } } Browseren skaber et objekt, og kalder så init metoden start metoden paint metoden Appletter – Et eksempel
Server objekter stiller en række metoder til rådighed som andre objekter (kaldet klient objekter) kan benytte sig af. Klient objekter har instansvariable der refererer til andre objekter (server objekter). I klientens metoder kalder server objektets metoder. Begreb: klient og server objekter Klient objekt Server objekt Server serverObjekt; ... void klientMetode(){ ... serverObjekt.service(); ... } void service(){ ... serverObjekt.service(); ... } Et klient objekt starter enten ved at det bliver lavet og startet fra main, eller ved at det er server for en anden klient. Appletten er et server program, og browseren er klienten. Bemærk at man ikke selv skriver klienten.
Et grafisk objekt repræsenterer en tegneflade. Browseren giver appletten en tegneflade som appletten kan lave sit output på. Dvs. det er ikke appletten der ”har” et graphics objekt, det er applettens klient (Browser eller AppletViewer) Tegnefladen er et server objekt set fra paint metoden. Den stiller metoder til rådighed der kan tegne linjer ovaler (og dermed cirkler) kasser tekster Man kan også sætte tegne farven mv. Der er en oversigt over Graphics på side 96, og en fyldigere på side 681. Graphiske objekter Applet object void paint(Graphics g){ ... g.drawLine(10,10,12,12); ... }
Bemærk: Det er klienten der kalder paint på server objektet. Det gør den når klienten mener at der er behov for det, f.eks. hvis klientens vindue har været dækket og nu bliver blotlagt, eller hvis klientens vindue har været lukket og bliver åbnet eller ... Du kan altså ikke fra en applet vide hvornår paint metoden bliver kaldt. paint metoden skal være istand til at gentegne hele den tegning man har lavet. paint events
I sgui er der den komponent type der hedder SCanvas. SCanvas indeholder som sit væsentligste et Graphics objekt, og kan derfor bruges til at lave tegneflader i en brugergrænseflade. import edu.it.sgui.*; import java.awt.Graphics; import java.awt.event.MouseEvent;public class KanvasTest extends SFrame { SCanvas kanvas = new SCanvas("kanvas", 200,250); SButton clear = new SButton("clear", "Clear"); public void kanvas_paint(Graphics g){ g.drawOval(20,20,100,200); g.drawString("Hello there", 40, 125); } } Grafik med sgui Man skal importere Graphics og MouseEvent klasserne. På samme måde som paint metoden bliver kaldt i forbindelse med appletter, så bliver kanvas_paint metoden kaldt når bruger grænsefladen har brug for at kanvas komponenten bliver tegnet op.
Når man klikker med musen på en SCanvas bliver metoden ID_clicked(MouseEvent ev) aktiveret. MouseEvent indeholder forskelligt, men specielt to metoder: int getX() int getY() som kan bruges til at finde ud af hvor på kanvassen der er klikket med musen. Når man skal tegne noget på kanvassen uden for paint metoden må man skaffe sig adgang til Graphics objektet med metoden getGraphics() public voidkanvas_clicked (MouseEvent ev){ int x = ev.getX(); int y = ev.getY(); Graphics gr = kanvas.getGraphics(); gr.drawOval(x-5, y-5, 10, 10); } public void clear_click(){ Graphics gr = kanvas.getGraphics(); gr.clearRect(0,0,300,400); } Reagere på museklik på en kanvas
BlueJ indeholder en række faciliteter der kan hjælpe med at lave Appletter Man kan angive, når man laver en ny klasse at det skal være en applet. Det giver en køreklar applet template. Desuden indeholder højre menuen for Appletter et punkt der hedder at køre appletten. Enten i Appletviewer Eller i Browser Appletter i BlueJ Øhh, det er ikke klart hvad det er. Man vil normalt ikke lave instanser af en applet. Men nyttig ved fejlfinding i større appletter
BlueJ – run applet BlueJ giver os tre valg når vi vælger ”Run Applet”. Hvis vi vælger ”Run Applet in Browser”, laver BlueJ en html side som så indlæses i Browseren. Man kan overføre parametre fra en HTML side til en applet. Det er ikke en del af dette kursus.
public void paint(Graphics g) public void start() public void stop() public void init() public void destroy() public String getAppletInfo() public String[][] getParameterInfo() BlueJ applet template Den vigtigste metode er paint, som kaldes af Browseren for at få appletten til at tegne sig på skærmen Hvis man har lavet en animation, så skal den ikke stå og køre når man forlader siden. start og stop metoderne bruges til at styre dette. init metoden bliver kaldt umiddelbart efter at applet objektet er skabt. Det svarer til en slags konstruktør, idet det er her man initialiserer applettens instansvariable. Når browseren lukkes, kaldes destroy. Disse to metoder anvendes til at man kan finde finde ud af noget om en applet alene ud fra dens ”.class” fil – f.eks. i appletviewer
Fundamentalt er der to slags metoder man kan arve fra en klasse. klient metode. Metoder som super klassen kalder, for derved at aktivere kode i subklassen. Altså superklassen er klient for subklassen.Man kan kalde en sådan metode for en klient metode. Det er (som regel) ikke meningen at man skal kalde en sådan metode i subklassen. service metode. Metoder som superklassen stiller til rådighed for at lette programmeringen af subklassen. Altså superklassen er server for subklassen.Man kan kalde en sådan metode for en service metode, og det er meningen at man kan kalde den fra subklassen. I Applet tilfældet optræder begge typer. init, paint, osv. er klient metoder. getParameter, getImage, osv er service metoder. Hvad arver man fra Applet klassen
Browseren, Applet og din applet Applet void paint(Graphics g) void start() void stop() void init() void destroy() Image getImage(URL location) String getParameter (String parName) Applet app; Browseren har en reference af typen Applet. Den kan derfor aktivere metoder der er defineret i Applet. I subklasser af applet kan der tilføjes nye metoder, men de vil ikke blive aktiveret fra browseren, idet denne ikke kender til deres eksistens. Bemærk, typen af variablen er Applet, mens objektet i variablen er lavet ud fra en subklasse af Applet . VoresApplet void paint(Graphics g) { Image img = getImage(...); g.drawImage(img,...); g.drawString(getParameter(p1),..); .. }
Abstract Windowing Toolkit (AWT) Programmer med grafiske bruger-grænseflader skal importere disse. import java.awt.*; import java.awt.event.*; class ClosableFrame extends Frame { public ClosableFrame(String name) { super(name); addWindowListener (new CloseListener()); } } Frame er et selvstændigt vindue på skærmen ClosableFrame import java.awt.*; import java.awt.event.*; class CloseListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); }} En Lytter, lytter efter hændelser, her hændelsen at der trykkes på ”close window” ikonen.
ClosableFrame i BlueJ På højre menuen af et ClosableFrame objekt kan man finde metoden show() som viser objektet (som jo er et vindue) på skærmen. show() arves fra Window (via Frame). Dette bringer følgende lillebitte vindue frem et eller andet sted på skærmen. Hvis man trykker på ”X” knappen vil CloseListeneren fra forrige slide aktiveres, og lukke vinduet ned. Efter at det er lukket kan man åbne det igen ved at vælge show() metoden fra højre menuen en gang mere.
Hændelsesstyret programmering med AWT Et Java program med en grafisk brugergrænseflade (Graphical User Interface = GUI), er et eksempel på at man har et hændelsesstyret program. Det betyder at programmet ikke laver noget andet end når brugeren af programmet trykker på en knap, vælger fra en menu, eller skriver i et tekst felt eller lignende. Det betyder at ens egne objekter er server objekter til Java maskinen, der kalder udvalgte metoder i ens eget program som resultat af brugerens muse klik og tastatur tryk (det er det der er hændelserne). I Java kaldes server objekter der aktiveres i forbindelse med GUI for lytter objekter.
CloseListener WindowAdapter indeholder en række metoder som svarer til de hændelser der kan ske med et vindue (lukkes, minimaliseres, ikonificeres, strække, osv) import java.awt.*; import java.awt.event.*; class CloseListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); }} Vores WindowAdapter overskriver blot en metode, nemlig den der kaldes når vinduet skal lukkes. Som parameter send Java nogle oplysninger med via hændelses parameteren. F.eks. hvilket vindue der er tale om. System.exit(0) afslutter programmet. I BlueJ sker der ikke så meget. Dispose fjerner vinduet fra skærmen.
Grafiske komponenter og beholdere En GUI består typisk af en række komponenter (tryk knapper, input felter, osv), som brugeren kan interagere igennem. Vinduet er ikke en komponent, men et eksempel på en container, et objekt der indeholder komponenter. Ud over vinduer er Appletter også containere, og man kan derfor også opbygge en brugergrænseflade i en applet.
Knap Eksemplet, indre klasser public class KnapTæller extends ClosableFrame{ Button knap = new Button("Tryk her"); TextField resultat = new TextField(10); private int antalTryk; public KnapTæller() { super("Knap Tæller"); antalTryk = 0; setLayout( new FlowLayout() ); setSize(100,100); knap.addActionListener( new KnapLytter() ); add(knap); add(resultat); show(); } } class KnapLytter implements ActionListener { public void actionPerformed (ActionEvent e) { antalTryk = antalTryk + 1; resultat.setText("Antal tryk: " + antalTryk); } } • KnapLytter er erklæret inde i klassen KnapTæller: • fra metoden kan man tilgå resultat direkte • Hvis en anden Klasse skulle bruge en KnapLytter bliver de ikke blandet sammen • KnapLytter er en indre klasse.
public KnapTæller() { super("Knap Tæller"); antalTryk = 0; setLayout( new FlowLayout() ); setSize(100,100); knap.addActionListener( new KnapLytter() ); add(knap); add(resultat); show(); } Forklaring af KnapTæller konstruktøren Angiv navn på vinduet i super klassens konstruktør. Bestemmer hvordan komponenterne lægges i containeren. Ikke pensum. angiv vinduets størrelse Lav et nyt KnapLytter objekt, og sæt det til at lytte på knap objektet. tilføj knap og resultat til denne container, dvs. dette vindue. Vis dette vindue. Indtil nu har vi lavet vindues objektet, men der er ikke vist noget på skærmen.
KnapTæller eksemplet igen Frame objekt Button objekt KnapTæller objekt Button knap; TextField resultat; int antalTryk: 4 Tekstfelts objekt Server del Klient del Problemstillingen i lytter objekter er, at venstre del skal fungere som klient del, mens vores egen del til højre skal være service del. Venstre delen består af standard komponenter, hvordan får vi den til at påvirke vores services? I alle andre tilfælde er dette løst ved at service delen skal have faste metoder som klienten kan kalde – sådan er det også her.
Den forkerte løsning Frame objekt Button objekt KnapTæller objekt Button knap; TextField resultat; int antalTryk: 4 void buttonAction(){ ...} Tekstfelts objekt Man kan ikke lade knap tæller objektet have en standard metode der bliver kaldt hvis en knap bliver aktiveret. Det leder nemlig til at denne metode bliver kaldt uanset hvilken knap der bliver trykket på (der kunne jo være en GUI med mere end en knap). Man kunne så give en parameter med om hvilken knap det var, men det leder erfaringsmæssigt til kode der er klumpet og ustruktureret.
Lytter løsningen – den rigtige. Frame objekt KnapTæller objekt Button objekt KnapLytter objekt void actionPerformed() {resultat.setText... } Button knap; TextField resultat; int antalTryk: 4 Tekstfelts objekt Nu kan Button objektet referere til et lytte objekt som har en standard metode (actionPerformed). Dvs, at klient delen kan kalde service delen som den skal. Idet KnapLytter objektet er lavet ud fra en indre klasse har dens metoder, herunder actionPerformed, adgang til KnapTæller objektets variable. Den kan derfor direkte arbejde på resultat og antalTryk.