OOP e uge kursusgang: Grafik (II) class Scribble (Tegnebrættet) Frihåndstegning: repræsentation

Relaterede dokumenter
Hvordan organiseres et programs grafik-elementer? OOP e uge kursusgang. Advarsel! Component-objekter

OOP e uge kursusgang. Disposition for (gennemgang af) afleveringsopgave. Deck.shuffle() 'Problemformulering', Indledning

et enkelt kontrol flow sætningerne i programmet afvikles en ad gangen flowet følger dels den tekstlige rækkefølge

Kursusgang 11. Oversigt: Sidste kursusgang Værktøjer til udvikling og implementering af HCI-design Oversigt over Java Swing

Grundlæggende Programmering ITU, Efterår Skriftlig eksamen i Grundlæggende Programmering

Kursusgang 12. Oversigt: Sidste kursusgang Layout-manager Event-håndtering. Design af brugerflader 12.1

Videregående programmering i Java

import java.awt.event.*; import java.awt.*; Container <- Panel <- Applet Component <- Button <- Checkbox <- ScrollPane <- Label

Tree klassen fra sidste forelæsning

Singleton pattern i Java

Civilingeniøreksamen januar Skriftelig prøve den 12. januar 2001 Kursusnummer 49104

A Profile for Safety Critical Java

Over Forelæsning omponenter ogrammering sigt 14, 1999 freda containere 15. oktober 1999 Eksempel: out GUI til beregning fakultet.

class subklasse-navn extends superklasse-navn { } NorwaySpruce har superklassen Spruce, som igen har superklassen Tree.

OOP e uge kursusgang: Samtidighed (II) Safety = sikkerhed. Safety

Videregående programmering i Java

b) Udvid din implementation af forme til at understøtte.equals. To objekter af samme form er ens hvis de har samme værdier i felterne.

Threads i Java. Denne artikel giver en introduktion til threads i Java. Den beskriver hvad tråde er og forklarer hvordan de bruges i Java

Serialization i Java

1. Flyreservationssystem. OOP e uge 37 - første kursusgang. OO-paradigmet jf. XP s. 10f

Hvad er Objekter - Programmering

Forelæsning Uge 13 Torsdag

Kapitel 6 Events i C#

Dag 10 Flertrådet programmering

Abstrakte datatyper C#-version

Videregående programmering i Java

Ugeseddel 4 1. marts - 8. marts

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

DANMARKS TEKNISKE UNIVERSITET

Forelæsning Uge 13 Mandag

Java Klasse nedarvninger

Lektion 6. Grundlæggende programmering i VR

Martin Geisler. Uge 49, 2001

Introduktion til ActionScript, fortsat

Lav din egen forside i webtrees

DM507 Algoritmer og datastrukturer

SWC eksamens-spørgsmål. Oversigt

Forelæsning Uge 6 Mandag

5 ARBEJDE MED EDITOREN

Singleton pattern i C#

import java.applet.applet; import java.awt.*; public class MinApplet extends Applet { // diverse metoder her - til grafik er det nok med "paint":

class Time { int hours, min; } } Time t1; // Erklær variabel af type Time class Time1 { public static void main(string[] args) { Time t1; t1.

Kursus i OOP og Java. Kursus i Objektorienteret programmering i Java

Vejledning til Photofiltre nr. 105 Side 1

RMI introduktion. Denne artikel beskriver Java RMI (Remtote Method Invocation).

Illustrator CC F u F ture tur Co C mpany an - y www. w future tur co c mpany an. y dk

Udskriv kort. Før udskrivning af et kort kan du eventuelt vælge at indtegne et/flere udskriftsområder. (I PLUS versionen kun ét).

DM502. Peter Schneider-Kamp

Forelæsning Uge 3 Torsdag

Få det bedste fra Windows 10

Tag smarte skærmskud

DM507 Algoritmer og datastrukturer

5. Teknisk beskrivelse af programmet 5.1 Programmets primære strukturer Datastruktur Datastruktur

Hvad er et distribueret objekt? Plan Objekter, objektreferencer, metoder, parameteroverførsel. Objekter: notation

Aftenskole i programmering sæson Registrering af tid. Sæson 2 - Lektion 5

Jacob Nordfalk. Ingeniørhøjskolen i København. Nykøbing F itvisioncenter 24. februar 2004

6. Eventstyret programmering og Windows

Objektorienteret Programmering

Online billede filtrering

En lille vejledning i at bruge Paint Win 98 og Win XP Indhold

Grafiske brugergrænseflader II

Adobe Titel Designer

ONSCREENKEYS 5. Windows XP / Windows Vista / Windows 7 / Windows 8

Tegne- og billedbehandlingsprogrammer tilbyder mange forskellige værktøjer og funktioner. Denne mini-manual giver en hjælpende hånd.

få en ny og bedre hjemmeside på få minutter Quick guide Del denne quick guide med alle som har glæde af en ny og bedre hjemmeside

Aftenskole i programmering sæson Watch Me. Sæson 2 - Lektion 19

Programmering. Udvidet Programmering. Kurserne. Kurset: programmering i sproget Java. Lærerne: Morten Larsen og Peter Sestoft

Grafiske brugergrænseflader II!

Forelæsning Uge 3 Torsdag

Datatekniker med programmering som speciale

Indledning. Hvorfor det forholder sig sådan har jeg en masse idéer om, men det bliver for meget at komme ind på her. God fornøjelse med læsningen.

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 3

DM507 Algoritmer og datastrukturer

Til at starte med vil jeg lige vis nogle små ændringer på opsætningen som jeg har lavet.

Miniguide for redaktører. Miniguide for redaktører. Leveret af DFF-EDB.dk

Eksempel på en database: studenter, kurser, eksamener

Programmering 1999 KVL Side 5-4. Klassen Time: metoder. Metoder i objektet giver mulighed for at ændre tilstanden, eller kigge på tilstanden.

Exceptions i Delphi. Try except

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

Specifikation Abstrakt OO OS-API Rev Specifikation. Abstrakt, objektorienteret operativsystem-api

JSP, Tomcat. Tutorial lavet af Jákup W. Hansen TSU semester 10.october 2007

Arkitektur for begyndere

Polymorfi. Arv (inheritance) Abstrakte klasser, substitutionsprincippet, overriding, statisk og dynamisk type. Coercion

DM507 Algoritmer og datastrukturer

Miniguide. Illustrator. Kom godt i gang med Illustrator. Kursusfabrikken

Videregående programmering i Java

Database for udviklere. Jan Lund Madsen PBS10107

Unity Guide 1 CONTENTS

Objektorienterede metoder

Guide til oprettelse/redigering af events på bornholm.info

Brugervejledning for Microstation til OpenSceneGraph konverter

Dag 10 Flertrådet programmering

Scratch. - introduktionshæfte

Greenfoot En kort introduktion til Programmering og Objekt-Orientering

University of Southern Denmark Syddansk Universitet. DM503 Forelæsning 11

Klasser og Objekter i Python. Uge 46 Learning Python: kap 15-16,

DM507 Algoritmer og datastrukturer

DM01 DM Obl. Afl. Jacob Christiansen, , D12, Elias 18/ Side 1 af 11

Eksempel: Skat i år 2000

Prezi. Aldrig mere gammeldaws slideshows!? Version: December 2012

Transkript:

OOP e2002 - uge 43 class Scribble (Tegnebrættet) Det simplest mulige tegnebræt kun en funktion: tegn streger med musen ingen kontrolknapper/valgmuligheder skal dog kunne "holde til" at ændre størrelse Frihåndstegning: Tegnebrættet har ikke objekter der repræsenterer de streger etc., der er tegnet canvas GUI designes som bestående alene af et canvas Det tegnede ligger kun repræsenteret som pixels i et Image-objekt. Modsat boldappletten, hvor boldene er repræsenteret med x/ykoordinater etc. (evt. som selvstændige objekter) Xiaoping implementerer iteration 2-3-4 ved tilføjelser, herunder subklasning. Bogen bliver lettere at læse Den samlede kode bliver sværere at læse, da den indeholder overflødige dele.

Det primære objekt er en grafik-"dobbelt"-buffer Skabelse af buffer Objekterne: grafik-bufferen og dens hjælper: class ScribbleCanvas extends JComponent { Graphics offscreengraphics; // Rummer platformsafh. data/metoder Image offscreenimage; // De rå data i platformsuafh. format Tegning i bufferen (når brugeren giver tegne-input) scribblecanvas.offscreengraphics.drawline(..); Visning af bufferen på skærmen: scribblecanvas.repaint();.. update(graphics g) { g.drawimage(offscreenimage,..); // bufferen vises via hjælperen setbounds(int x, int y, int width, int height) { // kaldes af kontekst når canvas bliver synlig offscreenimage = creageimage(width, height); offscreengraphics = createimage.getgraphics();.. Graphics/Image: For at skabe et ny Graphics-objekt, skal vi først skabe et Image-objekt Metoder til at tegne opererer på Graphics-objektet (f.eks. drawline), men opdaterer automatisk det Image-objekt, der er brugt til at skabe det! OOP e2002 - uge 43 Skabelse af canvas ved at nedarve fra (J)Component?? class ScribbleCanvas extends JComponent {.. eller uden : class ScribbleCanvas extends Component {..

OOP e2002 - uge 43 Hændelser der kan opfange brug af "pen" Brug af pen udløser: hændelse = brugerens tegne-bevægelser handling = programmet tegner på brættet Vores musehændelse: museknappen trykkes ned, musen bevæges mens knappen holdes nede, til sidst slippes knappen igen Alle former for musebevægelser, ikke kun lige streger. Men tegn kun streg hvis musen er inde over brættet når knappen trykkes ned (og pen er valgt) Hændelsesstyret programmering - hvilken hændelse? Fremgangsmåde ved implementation af penværktøj Hændelseskilde Hændelse Lytter Vi skal Hændelser repræsenteres af et hændelsesobjekt indeholder hændelsens kilde og helst mange flere oplysninger Handlinger repræsenteres af lyttere (listeners): klasser hvis metoder skal udføres Konteksten lytter til. For at konteksten kan aktivere en lytter i tilfælde af en hændelse, skal lytteren registreres hos hændelseskilden. 1. finde en eller flere passende (dvs. subklasse(r) af class AWTEvent) og 2. implementere værktøjet som en lytter (en klasse, der implementerer et/flere Listener-interfaces) der kan modtage ne.

Implementation af penværktøj (ideelt) Hændelses-klasse: class MouseDraggedEvent Lytter-interface: interface MouseDraggedListener { public void MouseDragged(MouseDraggedEvent e); hvor et MouseDraggedEvent-objekt indeholder alle punkter, musen har bevæget sig henover, mens museknappen har været holdt nede. Findes desværre ikke! class java.awt.event.mouseevent Kan repræsentere følgende simple og sammensatte muse: pressed: museknap trykket released:.. sluppet clicked: trykket + sluppet entered: musen er kommet ind over komponenten exited:.. væk.. moved: mus bevæget dragged: mus bevæget med knap holdt nede Indeholdt information: hvilke(n) af ovenstående er indtryffet 1 sæt koordinater (x,y): her foregik (sluttede) hændelsen Opgave: hvordan kan disse kombineres til den hændelse, vi har defineret skal repræsentere en streg? OBS: Hændelser genereres med visse mellemrum (brøkdele af et sekund) Løsning: mouse pressed + dragged + dragged.. mouse pressed ("her") mouse dragged ("hertil") linjestykker der tegnes på tegnebrættet musens virkelige bevægelser Lyttere, som kan modtage et java.awt.event.mouseevent Der findes to "musehændelses-lyttere". De modtager hver sin type af muse-: De "statiske" : interface MouseListener{ mousepressed(mouseevent e);.. De "dynamiske" : interface MouseMotionListener{ mousedragged(mouseevent e);..

Pen implementeret som lytter (frit efter XP s323 f) class PenTool implements MouseListener, MouseMotionListener { Point mouse; // musens "gamle" position mousepressed(mouseevent e) { mouse = e.getpoint(); mousedragged(mouseevent e) { Point p = e.getpoint(); tegn_streg_fra_mus_til_p(); mouse = p; canvas.repaint();.. plus tomme definitioner af resten af lytter-metoderne Ikke nødvendigt at "spørge" et MouseEvent-objekt hvilken slags hændelse, det repræsenterer, da dette fremgår af den kaldte lytter-metode. Men nødvendigt at registrere PenTool-objekt som Mouse- og MouseMotion-lytter OOP e2002 - uge 43 Grafik-opdatering: modificer så lidt som muligt repaint() --> update(), paint() Når konsteksten kalder update() efter applikations-genereret repaint(): mousedragged(mouseevent e) { Point p = e.getpoint(); tegn_streg_fra_mus_til_p(); mouse = p; canvas.repaint(<kun den del der er blevet ændret>); CPU-kraften må ikke spildes til at gentage den del af kanvas, der ikke har ændret sig. Ellers bliver reaktionstiden på musebevægelser langsommere. repaint(x, y, width, height) kan bruges uden man behøver lave en særlig definition af update()/paint() 0. Muligvis ventes der lidt først. 1. Graphics g = det nuværende billede (det sidst tegnede); 2. kald af update(g); // altid hele g! (svarende til components størr.) 3. tegn(g); // repaint(<rect>) => tegn(g,<rect>) Container superklasse opfanger kald af update() hvis ikke overskrivet i subklasser: public void update(grahpics g) { g.setcolor(getbackground()); // vælger baggrundsfarven g.clearrect(0, 0, width, height); // udfylder g med farven g.setcolor(getforeground()); // vælger forgrundsfarven paint(g); public void paint(graphics g) { {stort set tom definition {man kan kalde paint() i alle subkomponenter

OOP e2002 - uge 43 Skabelse/ af buffer (XP s 232) Større canvas => nødvendigt med større buffer til at repræsentere tegningerne. Vi vil gerne overføre eksisterende tegning til ny større canvas Der findes ikke en metode til at lægge pixels til i yderområdet. Løsning: overskrivning af setbounds() (XP s. 323) setbounds(int x, int y, int width, int height) { // kaldes også når kanvas ændrer størrelse (system- eller appl.-udløst).. Image resizedimage = creageimage(width, height); // midlertidigt Image offscreengraphics = resizedimage.getgraphics(); clearcanvas(); if (offscreenimage!= null) // overfør "gamle" tegning til buffer offscreengraphics.drawimage(offscreenimage,..); offscreenimage = resizedimage; // Image-objektet opdateres super.setbounds(..); // repaint(); Graphics/Image: den gamle tegning af lagret i offscreenimage den "resizede" tegning er lagret i newimage derfra overføres den til sidst til offscreenimage OOP e2002 - uge 43

Kombineret En applet kan køres som applikation, hvis appletten udvides til at definere en main()-metode main() opretter et yderste vindue som applettens panel kan anbringes i init() og andre metoder, der kaldes automatisk af appletkonteksten, skal kaldes eksplicit, hvis de er re-defineret i appletten. public class Scribble extends JApplet { init();... start();.. stop();.. ; public static void main(string[] args) { (a) skab yderste vindue med passende titel (b) skab Scribble-objekt (c) anbring Scribble-objekt (et panel) i vinduet To Scribble-konstruktorer: Applet: konteksten kalder Scribble() Applikation: vi kalder Scribble(..) som eksplicit kalder init() m.m. main() i applet public static void main(string[] args) { // (a) Det yderste vindue JFrame frame = new JFrame(); frame.settitle("scribble Pad"); frame.addwindowlistener(..); // registrer en lytter til at reagere på "sluk" // (b) Skabelse af nyt Scribble-panel i vinduet Scribble scribble = new Scribble(false); // (c) Anbringelse af Scribble-panel i vinduet frame.getcontentpane().setlayout(new BorderLayout()); // JComponent.getContentPane() // giver reference til JRootPane-objekt // som kan bruges til "Container-opgaver" frame.getcontentpane().add(scribble, BorderLayout.CENTER); // plus div. detaljer frame.setsize(..);..; OOP e2002 - uge 43 java.awt contra javax. javax. indeholder JButton, JFrame,.. med funktion svarende til Button, Frame,.. Features mange med nye features, f.eks. ikoner og ledetekst i knapper. man kan vælge at bruge indbygget dobbelt-bufring hurtigere? pænere? nye typer grafik-komponenter bl.a. JScrollBar nye typer events (og events-lyttere) Implementation "Letvægtskomponenter" forstået som at de er alene repræsenteret internt i Java og har lavniveaugrænseflade til platform modsat "sværvægtskomponenter" som har en "peer" komponent implementeret vhja. platformens højniveau-grafik-faciliteter ikke en erstatning af java.awt men en udvidelse JButton m.fl. nedarver fra java.awt.component overgang til at bruge javax. kan ske skridtvis

OOP e2002 - uge 43 WEST : Specifikation af krav til GUI: Bjælker med knapper ude langs siden af selve brættet Et bjælke til valg af "værktøj" (pen, viskelæder,..) Et bjælke til generelle/tværgående valg (farve, slet alt,..) SYD CENTER BorderLayout bruges til inddeling af panel CENTER et canvas til brættet WEST container til knapper SYD container til knapper Håndtering af class EraserTool implements MouseListener,.. { // minder om PenTool // skriver små hvide rektangler i stedet for streger Det primære problem er at skifte mellem forskellige værktøjer. 1) Man kan af-registrere den gamle lytter og registrere den nye. (Besværligt). 2) Man kan registrere en super-lytter, som fanger alle, og giver den videre til det aktuelle værktøj. Nemt løbende at ændre ToolListener-en. Bruger "State" design pattern. Kilde: canvassen Muse- Hændelse ToolListener (XP p 338) Muse- Hændelse Værktøj 1 Værktøj 2 OOP e2002 - uge 43

Xiaopings BouncingBall3 (s. 282f) (sidste iteration!) Animerings- og dobbeltbufrings-funktionalitet genbruges fra class Animator og class DoubleBufferHandler Der er tale om genbrug af funktionalitet ved delegering ikke som tidligere ved nedarvning (f.eks. BouncingBall2 s. 193) Før: nedarvning AnimationApplet tager sig af alt vedr. animering (dog ikke dobbelt-bufring) Oprettelse af en separat tråd, kald af sleep()/repaint() fra trådens run(), m.m. Subklasser skal blot definere paint() samt evt. justere delay. DBAnimationApplet har sin egen final update(), der kalder paintframe(), der er en abstrakt metode. Nu: delegering Fordelen delegering af animeringsfunktionalitet Generelt er fordelen ved delegering fremfor nedarvning: bruger-klassen kan nedarve fra andre klasser I tilfældet med Applet-animering er dette ikke relevant, da AnimationApplet i forvejen nedarver fra den klasse, vi vil nedarve fra (class Applet) Her drejer fordelen sig om: I BouncingBall ønsker vi ikke at animere/dobbeltbufre hele Appletten/panelet, kun canvas-et med boldene Hvilke fordele kan der være herved? Det ville være muligt at lave en class AnimationCanvas, der nedarver fra class Canvas, men løsningen med class Animator er mere generel

FinalBouncingBall med delegering af animering + dobbeltbufring (XP s. 282) DBHandler (XP s. 280) class DBHandler { DBHandler (DBComponent comp) { this.comp = comp; DBComponent comp; void update(graphics g) { comp.paintframe(offscreengraphics); {overfør offscreengraphics til g; Graphics offscreengraphics; BouncingBallCanvas (XP s. 281) class BouncingBallCanvas { void update(graphics g) { dbhandler.update(g); void paint(graphics g) { update(g); // hvorfor? DBHandler dbhandler; update() vs. paint(): hvilke(n) skal overskrives i Applet-subklasser? Hvis subklasser overskriver update(): skal de selv sørge for at gentegne hele baggrunden men så slipper de for at vente på at appletkonteksten gentegner baggrunden. Hvis man bruger dobbelt-bufring: bør man overskrive update() fordi man alligevel selv skal tegne baggrunden (da man jo ikke tegner i det grafikobjekt der er skabt i konteksten, men tværtimod overskriver det med ens egen "buffer") Definitionen af paint() skal fange "usædvanlige" kald af paint() fra konteksten, der sker uden om update().

OOP e2002 - uge 43 Anonyme klasser Bruges ofte til definition af lytter-klasser, hvor man kun skal bruge en instans, og ikke skal referere til instansen. En anonym klasse er en form for indre klasse. En indre klasse er en klasse defineret i en anden klasses indre. Definitionen af en anonym klasse er et udtryk, hvis værdi er en instans af den anonyme klasse. I stedet for - class StartStopHandler implements ActionListener {.. ActionListener handler = new StartStopHandler(); addactionlistener(handler); kan man skrive - addactionlistener(new ActionListener() {..);