Pensum SWING/MCV delen av TDT4180- MMI. Vår 2009 Dag Svanæs, IDI

Like dokumenter
JList, JTree, JTable. JList

MVC Model, View, Controller

EKSAMEN I FAG TDT MMI Lørdag 11. august 2012 Tid: kl

MVC i Swing, trinn for trinn

Eksamensoppgave i TDT4180 Menneske-Maskin- Interaksjon (MMI)

EKSAMEN I FAG TDT4180 MMI Torsdag 27. mai 2010 Tid: kl

EKSAMEN I FAG TDT4180 MMI Onsdag 28. mai 2008 Tid: kl

EKSAMEN I FAG TDT MMI Mandag 4. august 2008 Tid: kl

EKSAMEN I FAG TDT MMI Lørdag 4. juni 2005 Tid: kl

EKSAMEN I FAG TDT4180 MMI Mandag 18. mai 2009 Tid: kl

EKSAMEN I FAG TDT4180 MMI Lørdag 15. august 2009 Tid: kl

EKSAMEN I FAG TDT MMI Mandag 15. august 2011 Tid: kl

EKSAMEN I FAG TDT MMI Lørdag 26. mai 2012 Tid: kl

Grafisk Brukergrensesnitt

EKSAMEN I FAG TDT4180 MMI Torsdag 27. mai 2010 Tid: kl

NORGES TEKNISK-NATURVITENSKAPELIGE UNIVERSITET INSTITUTT FOR DATATEKNIKK OG INFORMASJONSVITENSKAP. Løsningsforslag

INF1010 Grafisk brukergrensesni3 med Swing og awt del 1 INF1010

EKSAMEN I FAG TDT4180 MMI Lørdag 21. august 2010 Tid: kl

Læringsmål for teknikk forelesningene. Når brukergrensesnittet er designet, så skal dere vite hvordan det skal konstrueres

EKSAMEN I FAG TDT4180/IT2401 MMI Onsdag 23. mai 2007 Tid: kl

Konseptuell modell, skjermdesign og konstruksjon

Eksamensoppgave i TDT4180 Menneske-maskin-interaksjon

Oppgave 1 (30%) Grensesnittdesign

NORGES TEKNISK-NATURVITENSKAPELIGE UNIVERSITET INSTITUTT FOR DATATEKNIKK OG INFORMASJONSVITENSKAP

NORGES TEKNISK-NATURVITENSKAPELIGE UNIVERSITET INSTITUTT FOR DATATEKNIKK OG INFORMASJONSVITENSKAP LØSNINGSFORSLAG

Grafiske brukergrensesnitt med Swing og AWT

EKSAMEN I FAG TDT4180 Menneske-maskin-interaksjon. Lørdag 27. juni 2006 Kl

INF Våren Li' repe$sjon om Tråder og GUI. Stein Gjessing, Ins$tu' for informa$kk, Universitetet i Oslo. Ins$tu' for informa$kk

EKSAMEN I FAG TDT4180 MMI Onsdag 18. mai 2009 Tid: kl

import javax.swing.*; import java.awt.*;

INF Notater. Veronika Heimsbakk 10. juni 2012

Løsningsforslag (Løsningene i kursiv)

LO191D/LC191D Videregående programmering

Gjennomgang av eksamen H99

AVDELING FOR INGENIØRUTDANNING EKSAMENSOPPGAVE

JPanel. Komponent hieraki. Window/JWindow. Applet/JApplet. JDialog. JFrame

INF1010 Grafisk brukergrensesni3 (GUI) med Swing/awt. del 1

EKSAMEN I FAG SIF MMI OG GRAFIKK Lørdag 16. august 2003 Tid: kl

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring AITeL

GUI-programmering, del 3 Vinduslyttere Dialogvinduer GUI-komponenten JTable Egne datamodellklasser. En oversikt over kapittel 19 i boka

AVDELING FOR INGENIØRUTDANNING EKSAMENSOPPGAVE

LC191D/LO191D Videregående programmering mai 2010

INF1010. Grafisk brukergrensesni. med Swing og awt del 2. INF Grafisk brukergrensesni4 II

Object interaction. Innhold. Abstraksjon Grunnleggende programmering i Java Monica Strand 3. september 2007.

EKSAMEN I FAG TDT MMI Tirsdag 1. juni 2004 Tid: kl

Gjøre noe i hele treet = kalle på samme metode i alle objekten. Java datastruktur Klassestruktur

6108 Programmering i Java. Leksjon 8. GUI: Grafisk brukergrensesnitt. Del 2: Roy M. Istad 2015

Vi lærte sist å lage vinduer. Om å lage et vindu. GUI (Graphical User Interface)-programmering. Inf GUI - del 2

UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet

case forts. Alternativ 1 Alternativer Sammensetning Objekt-interaktor med valg

Eks 1: Binærtre Binærtretraversering Eks 2: Binærtre og stakk

Eksamensoppgave i TDT4180 Menneske-maskin-interaksjon

AMS-case forts. Eksemplifisering av modellbasert. tilnærming til design av brukergrensesnitt

EKSAMEN I FAG TDT4100 Objekt-orientert programmering. Fredag 3. juni 2005 KL

Løsningsforslag Test 2

. Ved sensur vl1 ahe bokstaverte deloppgaver (a, b, c,...) telle like mye.

Eksamensoppgave Vår 2012 Ordinær eksamen Bokmål. Videregående programmering. Eksamensdato: Studium/klasse: 2. klasse

NB!!! Veldig korte svar er gitt her. Disse burde det vært skrevet mer på ved en eksamen..

UNIVERSITETET I OSLO

< T extends Comparable<T> > Indre klasser mm. «Det du bør ha hørt om før oblig 4»

Mål med kurset. Java i INF Dagens tema. GUI med Swing. Dokumentasjon

Kalkulator-leksjonen (nesten ferdig)

TDT4100 Objektorientert programmering

INF1010. Grafisk brukergrensesni. med Swing og awt del 2

(MVC - Model, View, Control)

UNIVERSITETET I OSLO

INF1010. Grensesnittet Comparable<T>

Løsningsforslag fra faglærere

Kapittel 13 Advanced Hypertext Implementation. Martin Lie Ole Kristian Heggøy

GUI - del 2. Stein Gjessing Inst for Informatikk Univ. i Oslo

Antall sider (inkl. forsiden): 7. Alle trykte og håndskrevne

GUI («Graphical User Interface») del 2

Algoritmer og datastrukturer Kapittel 3 - Delkapittel 3.1

INF1010 våren 2006 Uke 19: 9. mai 2006 Et større eksempel: Solitaire (kabal)

Post-it spørsmål fra timen (Arv og subklasser)

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Eksamen Oppgave a) public class DayTime { public final int hours, minutes;

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

Tittel Objektorientert systemutvikling 1. Eksamenstid, fra-til Ant. oppgaver 6

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

INF1010 MVC i tekstbaserte programmer

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

INF1010, 21. februar Om å gå gjennom egne beholdere (iteratorer) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

IN våren 2019 Onsdag 16. januar

1 t:n'v'\ekode LO325E. Alle ~vne og trykte. GOd'"j(jent kalkulator

IN våren 2018 Tirsdag 16. januar

GUI 3 JavaFX. Mer interaksjon Hvordan gi input :l programmet. INF1010 Stein Michael Storleer

INF våren 2017

Repitisjonskurs. Arv, Subklasser og Grensesnitt

EKSAMEN. TILLATTE HJELPEMIDLER: Alle trykte og skrevne. INNFØRING MED PENN, evt. trykkblyant som gir gjennomslag

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

GUI («Graphical User Interface») del 2

TDT4100 Objektorientert programmering

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

BOKMÅL Side 1 av 7. KONTINUASJONSEKSAMEN I FAG TDT4100 Objektorientert programmering / IT1104 Programmering, videregående kurs

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

IN2010: Algoritmer og Datastrukturer Series 2

Transkript:

Pensum SWING/MCV delen av TDT4180- MMI Vår 2009 Dag Svanæs, IDI

Pensum Kun de sentrale delene av det som er gjennomgått er direkte eksamensrelevant. Andre deler er relevant for øvinger, men vil ikke bli gitt til eksamen. Eksamensrelevant pensum begrenser seg til følgende: 1. ActionListener. - Ideen om en callback for å håndtere hendelser. 2. Modeller i MVC. - Skille data fra presentasjon. - Kunne lage sin egen modell ved å subklasse en default modell. 3. Bruk av JavaBeans sine mekanismer for å lage en egen modell. - Riktig bruk av (bounded) properties og support klassen. 4. Kunne lage et eget View til en egen beans-basert modell v.h.a. JPanel. - Riktig bruk av oppdateringer. 5. JList. - List modell og seleksjonsmodell. - LineRenderer Kunne lage sin egen. 6. Modeller kan ha modeller. Kunne lage en modell til en modell, og forstå hvorfor dette er nyttig.

1. En enkel knapp /** * A simple JButton in a JPanel * The JPanel lives in the contentpane of a JFrame. * DS 2005, TDT4180 */ import javax.swing.*; public class ButtonExample extends JPanel { /** * Constructor for objects of class ButtonExample */ public ButtonExample() { add(new JButton("Press here")); public static void main (String args[]) { JFrame frame = new JFrame("Button example"); frame.getcontentpane().add(new ButtonExample()); frame.pack(); frame.setvisible(true); JFrame ContentPane JPanel subclass JButton

1. Interface ActionListener Klippet fra Sun s AWT/SWING dokumentasjon: java.awt.event Interface ActionListener The listener interface for receiving action events. The class that is interested in processing an action event implements this interface, and the object created with that class is registered with a component, using the component's addactionlistener method. When the action event occurs, that object's actionperformed method is invoked. Methods public void actionperformed(actionevent e) Invoked when an action occurs.

1. ActionListener. Det finnes flere måter å løse problemet med hvilke objekter som skal implementere ActionListener interfacet og motta action hendelser fra f.eks. en JButton. Følgende strategier er persum: A. Meldingen mottas av selve det JPanel som kjører grensesnittet. B. Indre klasser i JPanel. C. Det opprettes en eksplisitt ekstern klasse.

1A. Action listener i JPanel /** Example 1A, TDT4180-2005. This example shows the use of an action listener by letting the JPanel implement the ActionListener interface. This is done by implementing the method "actionperformed". */ import javax.swing.*; import java.awt.event.*;... JPanel implements ActionListener public class ButtonExample_Panel extends JPanel implements ActionListener { private JTextField mytextfield; // The text field. private JButton mybutton; // The button. // Constructor for objects of class ButtonExample_Panel public ButtonExample_Panel() { mybutton = new JButton("Press here"); // Create new JButton object. mybutton.addactionlistener(this); // Add this JPanel as action listener. add(mybutton); // Add the JButton to the panel. mytextfield = new JTextField(); // Create and add new textfield.. mytextfield.setcolumns(20); add(mytextfield); mytextfield.settext("..."); mybutton.addactionlistener(this); public void actionperformed(actionevent e) /** Actions for mybutton **/ public void actionperformed(actionevent e) { // This method is called by JButton. mytextfield.settext("hello world."); public static void main (String args[]) { JFrame frame = new JFrame("Button example"); frame.getcontentpane().add(new ButtonExample_Panel()); frame.pack(); frame.setvisible(true);

1A. Detaljer /** Constructor for objects of class ButtonExample_Panel **/ public ButtonExample_Panel() { mybutton = new JButton("Press here"); // Create new JButton object. mybutton.addactionlistener(this); // Add this JPanel as action listener. add(mybutton); // Add the JButton to the panel. mytextfield = new JTextField(); // Create and add new textfield.. mytextfield.setcolumns(20); add(mytextfield); mytextfield.settext("..."); /** Actions for mybutton **/ public void actionperformed(actionevent e) { mytextfield.settext("hello world."); // Called by JButton.

1B. ActionListener i indre klasse /** Example 1B, TDT4180-2005. This example shows the use of an action listener by letting the JPanel have an innner class "MyButtonAction" that implements the ActionListener interface. **/ import javax.swing.*; import java.awt.event.*;... JPanel public class ButtonExample_Innerclass extends JPanel { private JTextField mytextfield; private JButton mybutton; /** Constructor for objects of class ButtonExample_Innerclass */ public ButtonExample_Innerclass() { mybutton = new JButton("Press here"); mybutton.addactionlistener(new MyButtonAction()); add(mybutton); mytextfield = new JTextField(); mytextfield.setcolumns(20); add(mytextfield); mytextfield.settext("..."); /** Actions for mybutton **/ class MyButtonAction implements ActionListener { public void actionperformed(actionevent e) { mytextfield.settext("hello world."); mybutton.addactionlistener( new MyButtonAction()); class MyButtonAction implements ActionListener public static void main (String args[]) { JFrame frame = new JFrame("Button example"); frame.getcontentpane().add(new ButtonExample_Innerclass()); frame.pack(); frame.setvisible(true);

1B. Detaljer /** Constructor for objects of class ButtonExample_Innerclass */ public ButtonExample_Innerclass() { mybutton = new JButton("Press here"); mybutton.addactionlistener(new MyButtonAction()); add(mybutton); mytextfield = new JTextField(); mytextfield.setcolumns(20); add(mytextfield); mytextfield.settext("..."); /** Actions for mybutton **/ class MyButtonAction implements ActionListener { public void actionperformed(actionevent e) { mytextfield.settext("hello world.");

1C. Action listener i egen klasse /** Example 1C, TDT4180-2005. This example shows the use of an action listener by making an explicit "controller" class for the JButton. */ import javax.swing.*; import java.awt.event.*; public class ButtonExample_WithController extends JPanel { public JTextField mytextfield; private JButton mybutton; /** * Constructor for objects of class ButtonExample_WithController */ public ButtonExample_WithController() { mybutton = new JButton("Press here"); mybutton.addactionlistener(new ButtonExample_Controller(this)); add(mybutton); mytextfield = new JTextField(); mytextfield.setcolumns(20); add(mytextfield); mytextfield.settext("..."); public JTextField mytextfield; mybutton.addactionlistener(new ButtonExample_Controller(this)); public static void main (String args[]) { JFrame frame = new JFrame("Button example"); frame.getcontentpane().add(new ButtonExample_WithController()); frame.pack(); frame.setvisible(true);

1C. Egen controller klasse /** Explicit controller class. */ import java.awt.event.*; public class ButtonExample_Controller implements ActionListener { private ButtonExample_WithController mypanel; private ButtonExample_WithController mypanel; /** * Constructor for objects of class ButtonExample_Controller */ public ButtonExample_Controller(ButtonExample_WithController thepanel) { mypanel = thepanel; /** Actions for mybutton **/ public void actionperformed(actionevent e) { mypanel.mytextfield.settext("hello world."); mypanel.mytextfield.settext("hello world.");

2. MVC arkitektur Skiller data fra presentasjon. View lese vha. get-metoder Modell Controller endre vha. set/ add-metoder endringshendelser

SliderSliderExample Design to slidere, verdiområde 0-20 når den ene beveges, følger den andre etter i motsatt retning Kode Hendelse i slider2: slider1.value = 20 slider2.value og omvendt ved hendelse i slider1: slider2.value = 20 slider1.value

SliderSliderExample Konstruksjon SliderSliderExample arver fra (extends) JPanel to JSlider-instanser SliderSliderExample implementerer ChangeListener, og lytter på de to JSliderinstansene

SliderSliderExample Konfigurering legger til lytter Flytter på slider1 mottar endringshendelse leser slider1 sin verdi setter slider2 sin verdi Tilsvarende dersom slider2 flyttes på

SliderSlider Example sequence vs. collaboration diagram

SliderSliderSliderExample Design tre slidere, verdiområde 0-20 når ene av dem beveges, følger de andre etter Slider1_verdi = Slider2_verdi = Slider3_verdi

SliderSliderSliderExample Konstruksjon SliderSliderSliderExample arver fra (extends) JPanel to JSlider-instanser SliderSliderSliderExample implementerer ChangeListener, og lytter på de tre JSliderinstansene Vil denne konstruksjonen skalere til 4+ antall slidere?

Problem med konstruksjonen Ved endring av en må alle de andre oppdateres n x n krysskoblinger gjør koden komplisert Når én til legges til, må logikken for de andre endres Essensielt samme data spredd på flere objekter Alle til/fra alle

Alternativ konstruksjonen Innføre eget objekt for lagring av data, en såkalt modell Komponentene viser frem og endrer dataene i dette modellen Hver komponent forholder seg bare til modellen, ikke de andre Modellen administrerer oppdatering av registrerte avhengige objekter Alle til/fra én

Sammenligning Tydeligere rollefordeling Mer robust og skalerbar kode Alle til/fra alle vs. Alle til/fra én n <= 3 n >= 3

SlidersCommonModelExample Innfører et skille mellom visning og endring av data og selve dataene visning og endring gjøres av komponenten dataene lagres i en såkalt modell og håndteres gjennom et veldefinert grensesnitt (API) De tre sliderne har en felles modell

SlidersCommonModelExample Swing inneholder en rekke standardmodeller Hver modell er tilpasset en eller flere standardkomponenter Det finnes en standardmodell kalt BoundedRangeModel for intervall i intervall: minimum- og maksimum-verdier verdi-interval innenfor min- og maks-verdiene min value value + extent max DefaultBoundedRangeModel implementerer BoundedRangeModel JSlider-klassen bruker allerede en slik modell!

Felles modell for slider-objektene slider1:jslider slider2:jslider slider3:jslider model: BoundedRangeModel

Kode for delt modell public class SlidersCommonModelExample extends JPanel { // internal components: private JSlider slider1; private JSlider slider2; private JSlider slider3; private BoundedRangeModel model; // Shared model public SlidersCommonModelExample() { // create and configure model: model = new DefaultBoundedRangeModel(10, 0, 0, 20); // value, extent, min, max slider1 = new JSlider(model); slider2 = new JSlider(model); slider3 = new JSlider(model);. // create with shared model // create with shared model // create with shared model // remember to add them to the panel add(slider1); add(slider2); add(slider3); slider1:jslider slider2:jslider model: BoundedRangeModel slider3:jslider

SlidersCommonModelExample JPanel Dette skjer bak kulissene : SliderCommonModelExample slider2 slider1 slider3 JSlider model <<Interface>> BoundedRangeModel

2B. Egen modellklasse /** /** A JList with a self made model. */ import javax.swing.*; import java.awt.*; public class JListModelExample_0 extends JPanel { private JList myjlist; private MyListModel_0 model; /** * Constructor for objects of class JListModelExample_1 */ public JListModelExample_0() { model = new MyListModel_0(); myjlist = new JList(model); private MyListModel_0 model; myjlist = new JList(model); JScrollPane myjscrollpane = new JScrollPane(myJList); myjscrollpane.setverticalscrollbarpolicy(jscrollpane.vertical_scrollb AR_ALWAYS); setlayout(new BorderLayout()); add(myjscrollpane,borderlayout.north); public static void main (String args[]) { JFrame frame = new JFrame("JList example"); frame.getcontentpane().add(new JListModelExample_0()); frame.pack(); frame.setvisible(true);

2B. Egen modellklasse /** Egen modellklasse */ import javax.swing.abstractlistmodel; public class MyListModel_0 extends AbstractListModel { /** * Constructor for objects of class PersonListModel */ public MyListModel_0() { public int getsize() { return 100; extends AbstractListModel (AbstractListModel implements ListModel) Interface ListModel: getsize public int getsize() Returns the length of the list. getelementat public Object getelementat(int index) Returns the value at the specified index. public Object getelementat(int i) { return ((i+1)+"*"+(i+1)+"="+(i+1)*(i+1));

3 & 4. Egen komponent og modell View lese vha. get-metoder SWING komponent Modell Controller endre vha. set/ add-metoder endringshendelser

Typisk modell Klasse med uavhengige attributter kalt properties, basert på domenemodell F.eks. PersonModel-klasse: name og adresse, begge String-objekter Modellen må ha to egenskaper metoder for å lese og skrive attributtene kunne sende ut endringshendelser

Typisk komponent Basert på JPanel JLabel med tekst tilsvarende attributtnavn komponent tilpasset attributtets klasse/ datatype F.eks. PersonPanel: JTextField for name og address JPanel-komponenten har en modell-property leser og skriver modellens attributter lytter til endringer i modellens attributter

JavaBeans-baserte modeller En JavaBean har visse egenskaper og følger visse navngivingskonvensjoner Alle JavaBeans har et sett såkalte properties av ulike kategorier Alle JavaBeans er kodet iht. visse konvensjoner navngiving av metoder for å lese og skrive properties, read-metode: public <type> get<property>, f.eks. public String getname() write-metode: public void set<property>(<type> p), f.eks. public void setname(string name) generering av hendelser ved endringer av properties hendelsesklasse: PropertyChangeEvent metoder for å registrere PropertyChangeListener-lyttere: add/removepropertychangelistener

Typisk kallsekvens 1. Komponenter legger seg til som lytter på modell 2. Modellen legger lytteren inn i liste 3. Komponenten (eller annet objekt) endrer på en property i modellen 4. Modellen lager en endringshendelse og kaller endringsmetoden til alle lytterne 5. Lytterne reagerer på endringshendelsen. Lytterne får endringshendelsen uavhengig av hvilket objekt som endret property en

Bound properties En bound property genererer en PropertyChangeEvent ved endring Hver endring av property må skje gjennom setmetode, også interne endringer dersom property ens nye verdi er ulik den gamle, må endringen kringkastes lyttende objekter (dvs. registrerte objekter som implementerer PropertyChangeListener-grensesnittet) Mekanikken kan delegeres til et PropertyChangeSupport-objekt, som håndterer registrering av lyttere og kringkasting av hendelser add/removepropertychangelistener firepropertychange

Klassediagram PropertyChangeSupport JPanel 1 PersonPanel getmodel() : PersonModel setmodel(personmodel) 0..n model 1 PersonModel getname() : String setname(string) addpropertychangelistener(propertychangelistener) 0..n pcs 1 listeners <<Interface>> PropertyChangeListener 0..n propertychange()

Typisk kallsekvens panel : PersonPanel person : PersonModel addpropertychangelistener(listener) Add the listener User inputs new name string John setname( John ) firepropertychange propertychange

PersonModel-klassen To attributter/property er: name, address Metoder for lese og skrive attributtverdier get/set-metodepar for hvert felt get-metodene er parameterløse og returnerer objekt av type tilsvarende attributtets set-metoden tar ett parameter av type tilsvarende attributtets og returnerer ingenting (void) Property-navn-konstanter objekt (String) som identifiserer property, f.eks. public final static ADDRESS_PROPERTY_NAME = address ; konstantverdien brukes bl.a. i endringshendelsesobjekter for å angi hvilken property som er endret lyttere sjekker typisk hvilken property som er endret, for å kunne reagere riktig, f.eks. oppdatere tilsvarende tekstfelt

PersonModel-klassen Metoder for håndtere endringslyttere addpropertychangelistener(propertychangelistener) removepropertychangelistener(propertychangelistener) Beskyttet metode for å fyre av endringshendelser protected firepropertychange(property, oldvalue, newvalue) Delegerer til privat PropertyChangeSupport-instans private PropertyChangeSupport pcs = new PropertyChangeSupport(this);... public void addpropertychangelistener(propertychangelistener listener) { pcs.addpropertychangelistener(listener);... protected void firepropertychange(string prop, Object old, Object ny) { pcs.firepropertychange(prop, oldvalue, newvalue);

PersonPanel-klassen Modell-referanse et modell-attributt av typen Person all visning og editering skjer på dette objektet merk at modellen kan være null Property-orienterte subkomponenter JLabel tilsvarende property-navnet Tekstfeltene name og address Skjema-aktig layout GridLayout gir tabell-utlegg av subkomponentene

PersonPanel-klassen Lytter til property-endringer implements PropertyChangeListener public void propertychange(propertychangeevent evt) {... hvilken property som er endret avgjør hvilken sub-komponent som blir oppdatert

Typisk kallsekvens panel : PersonPanel person : PersonModel pcs : PropertyChangeSupport addpropertychangelistener addpropertychangelistener User inputs new name string John setname( John ) firepropertychange propertychange getname Set text field = John

JList 3. JList-komponenten viser liste av data-verdier iht. ListModel støtter seleksjon iht. ListSelectionModel (single, single-interval, multiple-interval) visning av enkeltverdi iht. ListCellRenderer public Component getlistcellrenderercomponent

Objekt- diagram : ListDataListener modell : ListModel list : JList model : ListSelectionListener renderer renderer : ListCellRenderer selectionmodel : ListSelectionModel

JList og ListModel JList er et view mot en eksisterende modell (datastruktur) ListModel er modell-grensesnittet int getsize() Object getelementat(int) JList lytter etter endringer i modell-objektet add/removelistdatalistener(listdatalistener) contentschanged(listdataevent) ListDataEvent-hendelser er utgangspunktet for oppfriskning av skjermbildet

JList og ListModel... Sentrale teknikk delegering Hendelse-lytter-pattern XxxEvent-klasse XxxListener-interface add/removexxxlistener Sentrale klasser/objekter ListModel ListDataListener ListDataEvent Sentrale metoder addlistdatalistener og contentschanged getsize og getelementat

JList og ListCellRenderer... Omtrentlig sekvens av operasjoner spør ListModel om størrelse getsize() itererer over alle elementene spør om verdi getelementat(int) ber renderer konfigurere og returnere komponent spør om størrelsen og gir plass ber komponenten tegne seg selv posisjon og størrelse huskes slik at en vet hvilke linjer som er hvor for hver linje som endres, gjentas dette, f.eks. verdi, seleksjon og fokus

Seleksjon ListSelectionModel-klassen håndterer logikken SINGLE_SELECTION Valg av kun ett elemenent Valg av nytt element fjerner eksisterende valg SINGLE_INTERVAL_SELECTION Valg av flere etterfølgende elementer Shift-klikk for å utvide seleksjonen i begge retninger MULTIPLE_INTERVAL_SELECTION Valg uten begrensninger på antall eller intervaller Control-klikk toggler enkelt-elementer Shift-klikk utvider seleksjonen

...seleksjon Sentrale teknikker delegering Hendelse-lytter-pattern XxxEvent-klasse XxxListener-interface add/removexxxlistener Sentrale klasser/objekter ListSelectionModel ListSelectionListener ListSelectionEvent Sentrale metoder JList.addListSelectionListener ListSelectionListener.valueChanged

JList og ListCellRenderer JList delegerer tegning av hver element i lista til en ListCellRenderer getcellrenderer ListCellRenderer configurerer og returnerer en Component getlistcellrenderercomponent Component-objektet har en (foretrukket) størrelse og kan tegne seg selv getpreferredsize paintcomponent Siste Swing-versjon støtter layout i flere kolonner

JList og ListCellRenderer... Sentral teknikk delegering Sentrale klasser/objekter ListCellRenderer Component Sentrale metoder getlistcellrenderer ListDataListener.contentsChanged getsize getelementat

6. Modeller kan ha modeller Noen ganger ønsker man å ha en felles datamodell for SWING komponenter som har forskjellig type modeller. De kan følgelig ikke ha samme modell direkte. For hver type komponent må det da lages en mellommodell som videreformidler meldinger ned til den egentlige modellen.

SliderSpinnerModelExample Design JSlider og JSpinner instanser Når den ene manipuleres følger de andre etter Konstruksjon basert på MVC og SliderSpinnerModel Example-koden JSlider JSpinner

AbstractSpinnerModel public abstract class AbstractSpinnerModel extends Object implements SpinnerModel This class provides the ChangeListener part of the SpinnerModel interface that should be suitable for most concrete SpinnerModel implementations. Subclasses must provide an implementation of the minimum, maximum, and value properties and the getnextvalue and getpreviousvalue methods.

SpinnerModel A SpinnerModel has three properties, only the first is read/write. Value The current element of the sequence. nextvalue The following element or null if value is the last element of the sequence. previousvalue The preceeding element or null if value is the first element of the sequence. When the the value property changes, ChangeListeners are notified. SpinnerModel may choose to notify the ChangeListeners under other circumstances.

DefaultBoundedRangeModel

Forskjellige grensesnitt JSlider JSpinner DefaultBoundedRangeModel getmaximum() getminimum() getvalue() getvalueisadjusting() setmaximum(int n) setminimum(int n) setrangeproperties( ) setvalue(int n) setvalueisadjusting(..) firestatechanged() AbstractSpinnerModel getnextvalue() getpreviousvalue() getvalue() setvalue(object value) firestatechanged()

SliderSpinnerModelExample Konfigurere instanser felles IntervalValueModel-instans IntervalValueBoundedRangeModel og IntervalValueSpinnerModel lytter begge på IntervalValueModel-instansen JSlider- og JSpinner-instansene lytter på sine modeller SliderSpinnerModelExample lytter ikke på noe! JSlider-instansen manipuleres modellens verdi endres underliggende og felles modell endres hendelser om endring i felles modell sendes til lytterne

IntervalValueSpinnerModel Oversetter kall og hendelser mellom JSpinner og IntervalValueModel get-metoder, f.eks. getvalue set-metoder, f.eks. setvalue Hendelser: firepropertychange propertychange JSpinner IntervalValue SpinnerModel IntervalValue Model IntervalValue BoundedRange Model Tilsvarende for IntervalValueBoundedRangeModel JSlider

IntervalValueSpinnerModel getvalue JSpinner getvalue IntervalValue SpinnerModel getvalue IntervalValue Model setvalue JSpinner setvalue IntervalValue SpinnerModel setvalue IntervalValue Model propertychange til firestatechanged JSpinner firestatechanged IntervalValue SpinnerModel propertychange IntervalValue Model

Forskjellige grensesnitt JSlider JSpinner DefaultBoundedRangeModel getmaximum() getminimum() getvalue() getvalueisadjusting() setmaximum(int n) setminimum(int n) setrangeproperties( ) setvalue(int n) setvalueisadjusting(..) firestatechanged() IntervalValueModel getmaximum() getminimum() getvalue() setmaximum(int n) setminimum(int n) setvalue(int n) AbstractSpinnerModel getnextvalue() getpreviousvalue() getvalue() setvalue(object value) firestatechanged()

slider : JSlider boundedrangemodel : IntervalValueBoundedRangeModel spinner : JSpinner spinnermodel : IntervalValueSpinnerModel intervaluevalue : IntervalValueModel addpropertychangelistener() addchangelistener(changelistener) addpropertychangelistener() addchangelistener(changelistener) Bruker drar slider setvalue(int) setvalue(int) propertychange() statechanged(changeevent) propertychange() statechanged(changeevent)

SliderSpinnerModelExample 2: addpropertychangelistener() 5: setvalue(int) slider : JSlider 8: statechanged(changeevent) boundedrangemodel : IntervalValueBoundedRangeModel 1: addpropertychangelistener() 6: setvalue(int) 7: propertychange() 3: addintervalvaluelistener(intervalvaluelistener) intervaluevalue : IntervalValueModel 4: addchangelistener(changelistener) 9: propertychange() spinner : JSpinner spinnermodel : IntervalValueSpinnerModel 10: statechanged(changeevent)