Javan Swing-tekniikan perusteet: Muistutus: Tarvitset seuraavia komponentteja harjoituksissa: otsikkoteksti (label) muokkausruutu (text field) komentopainike (button) yhdistelmäruutu (combo box) paneeli (panel) muuttumattoman tekstin esittäminen tekstitiedon esittäminen ja sen muuttaminen käyttäjän toimesta sovelluksen toiminnon aktivointi käyttäjä voi valita syöttötiedon alasvetovalikosta tai kirjoittaa sen ruutuun näytöllä oleva alue, jossa voidaan esittää muita käyttöliittymäkomponentteja
Javan Swing-tekniikan perusteet Swing-tekniikan GUI-komponentteihin liittyy kolme peruskäsitettä: komponentit (components) tapahtumat (events) kuuntelijat (listeners)
Javan Swing-tekniikan perusteet Javan tapahtumankäsittely perustuu Observer design pattern malliin observer = tarkkailija design pattern = suunnittelumalli Suunnittelumalli on toteutustapa, jota voidaan soveltaa uudelleen saman tyyppisen ongelman ratkaisuun
Javan Swing-tekniikan perusteet Observer design pattern tapahtumien lähde-objektissa tapahtuu muutoksia joukko tarkkailijoita seuraa tapahtuvia muutoksia lähde-objekti ei vastaa tarkkailijoiden aktivoinnista lähde-objekti sisältää listan, johon muutoksista kiinnostuneet voivat listautua listautuneet tarkkailijat voivat kuunnella tapahtuneita muutoksia tarkkailija liittää haluamansa muutoksen kuuntelijaan tarvittavan toiminnallisuuden
Lähde-objekti Tapahtuma deregister register notify Kuuntelija Tarkkailija Kuuntelija Tarkkailija
Javan Swing-tekniikan perusteet Tapahtuma (event) on objekti, joka kuvaa jotakin käyttäjän tekemää toimenpidettä hiirtä siirretään (mouse move) hiirtä raahataan (mouse drag) hiiren painiketta painetaan (a mouse button is clicked) näppäimistöltä näppäillään merkki (a keyboard key is pressed) ajastimen aika päättyy (a timer expires)
Javan Swing-tekniikan perusteet Tapahtumiin liittyy kolme peruskäsitettä (itse asiassa olioita): Tapahtuma itse (event) Tapahtuman lähde (event source) Tapahtuman kuuntelija (event listener)
Javan Swing-tekniikan perusteet Tapahtuma itse (event) luodaan Lähde-objektin yhteydessä on objekti, joka periytetään java.util paketin EventObject-luokasta kuvaa tapahtunutta tapahtumaa
Javan Swing-tekniikan perusteet Tapahtuman kuuntelija (event listener) on objekti, jonka rajapinta periytetään java.util paketin EventListenerrajapinnasta rekisteröityy kuuntelijaksi tapahtuman lähde-objektille
Javan Swing-tekniikan perusteet Tapahtuman lähde (event source) ylläpitää listaa tapahtuman kuuntelijoista listaan rekisteröidytään addlistener-metodilla ja siitä poistutaan removelistener-metodilla lähde luo event-objektin ilmentymän lähde ilmoittaa kullekin listan kuuntelijalle tapahtumasta notify-metodilla notify-metodi sisältää parametrinaan viitteen event-objektiin
Javan Swing-tekniikan perusteet Tapahtumiin voi liittyä eri tyyppisiä kuuntelijoita: Käyttäjä näpäyttää komentopainiketta, painaa Return-näppäintä kirjoittaessaan muokkausruutuun tai valitsee menu-valikosta toiminnon Käyttäjä sulkee ikkunan ActionListener WindowListener Käyttäjä näpäyttää hiirtä komponentin päällä Käyttäjä siirtää kohdistimen komponentin päälle Komponentti tulee näkyväksi Komponentti saa fokuksen Taulun tai listan valinnan muuttuminen MouseListener MouseMotionListener ComponentListener FocusListener ListSelectionListener
Javan Swing-tekniikan perusteet Käyttäjän toimenpide Komponentti Event Komentopainikkeen painaminen JButton ActionEvent Tekstin muuttaminen JTextComponent TextEvent Lista-alkion kaksoisnäpäytys JList ActionEvent Alkion valinta näpäyttämällä kerran JList ItemEvent Alkion valinta tai valinnan poisto JComboBox ItemEvent
Event-objekti Laukaisee tapahtuman (event) Kohdekomponentti Kuuntelija Listener Aktivoi Tapahtumankäsittelijä
Kuuntelija voidaan toteuttaa tähän tapaan: tallennajbutton = new JButton ("Tallenna"); tallennalistener = new tallennalistenerclass(); tallennajbutton.addactionlistener(tallennalistener); class tallennalistenerclass implements ActionListener { public void actionperformed (ActionEvent e) { // tähän tulee toiminnallisuus } );
Kuuntelija voidaan toteuttaa anonyymina sisäluokkana (anonymous inner class) tähän tapaan: tallennajbutton = new JButton ("Tallenna"); tallennajbutton.addactionlistener( new ActionListener () { public void actionperformed ( ActionEvent event) { // tähän tulee toiminnallisuus } );
Mikä olikaan anonyymi sisäluokka? erikoistapaus luokan määrittelystä luokka määritellään ilman nimeä (tästä sana anonymous) luokan määrittely esiintyy tyypillisesti metodin sisällä (tästä sana inner) koska luokalla ei ole nimeä, on yksi objekti luotava välittömästi määrittelyn yhteydessä seuraus: kullakin kontrollilla on oma kuuntelija
Vaihtoehtoinen tapa: public class ButtonDemo extends JFrame implements ActionListener { public ButtonDemo () {. JButton tallennajbutton = new JButton ( Tallenna ); tallennajbutton.addactionlistener(this); JButton poistajbutton = new JButton ( Poista ); poistajbutton.addactionlistener(this); } public void actionperformed (ActionEvent e) { if (e.getactioncommand().equals( Tallenna )) // tallennatoiminta ; else if (e.getactioncommand().equals( Poista )) // poistatoiminta ; else //virhetoiminta ; } }
Erona anonyymiin sisäluokkaan: nyt painikkeilla on yhteinen kuuntelija molemmat painikkeet aktivoivat saman kuuntelijan tapahtumaobjektista selviää, kumpi painike on kuuntelijan aktivoinut sen mukaan valitaan toiminta huomaa, että kontrollista ja käyttäjän toimenpiteestä riippuu tapahtuma, joka aktivoituu
Kumpaa kuuntelijatyyppiä kannattaa käyttää? Tässä tapauksessa tavoitteena on yhdistää usean eri tekijän osakokonaisuuksien toiminnallisuus samaan ikkunaan Silloin on parempi käyttää anonyymiä sisäluokkaa, jolloin jokaisella kontrollilla on oma kuuntelija Yhdistäminen on helppoa mutta ikkunan koodi pitenee Yleisessä tilanteessa vertailu ei ole näin helppo
Toiminnallisen eheyden käsite esimerkissämme sama toiminto voidaan aktivoida sekä valikkoriviltä että komentopainikkeesta kummallakin kontrollilla on oma kuuntelija kuuntelijoiden tulee aktivoida sama toiminta (toteutettuna esim. luokan sisäisenä metodina) ilman ylimääräisiä toimenpiteitä metodissa toteutetaan se toiminnallisuus, joka toimintoon halutaan liittää seuraus: kumpikin toiminnon aktivointitapa johtaa täsmälleen samaan suoritukseen seuraus: käyttäjän oppimista tuetaan
Javan Swing-tekniikan perusteet Miten viikon 4 ryhmäharjoitustehtävä kannattaa toteuttaa: Otetaan lähtökohdaksi edellisellä viikolla toteutettu osasovellus Lisätään sovellukseen kuuntelijat anonyymina sisäluokkana Toteutetaan jokaiseen kuuntelijaan sanomaikkuna, joka kertoo aktivoidun komennon nimen Testataan osasovellus Kootaan testatuista osasovelluksista toimiva ikkuna Lisätään ikkunaan kutakin toimintoa vastaava metodi Aktivoidaan ko. metodi sekä valikkorivin toiminnosta että komentopainikkeen toiminnosta Testataan toteutus
Javan Swing-tekniikan perusteet Miten viikon 4 ryhmäharjoitustehtävä voi laajentaa Etsitään arkistoista tosite-luokan toteutus Liitetään tosite-luokan toteutus sovellukseen niin, että uuden tositteen tiedot saadaan ikkunasta Tallenna-toiminnon painamisen jälkeen Talletetaan ikkunan tiedot tosite-luokkaan sen metodien avulla Tarkistetaan tietojen kelvollisuus. Tähän olisi hyvä olla metodi tositeluokassa Jos tiedot kelpaavat, tuodaan siitä viesti käyttäjälle Testataan toteutus Toteutuksen onnistuessa saadaan hyvä arvosana
Keskusteluikkunan (Dialog window) toteuttaminen Keskusteluikkuna voidaan toteuttaa kahdella vaihtoehtoisella tavalla käytetään JDialog-luokkaa, jolloin dialogi-ikkuna kiinnitetään vastaavaan JFrame-ikkunaan käytetään JFrame-luokkaa, jolloin toteuttajan on muunnettava ikkunan käyttöliittymä otsikkorivin komentopainikkeiden osalta (ei suositeltavaa)
JDialog-luokka muodostin vaatii sen ikkunan kahvan, johon dialogi-ikkuna liittyy tuhoamalla ikkuna tuhoutuu myös siitä riippuva dialogi-ikkuna dialogi-ikkuna modaalisuus voidaan valita modaalinen dialogi-ikkuna on pakko käsitellä ennen muita ikkunoita modaaliton muiden ikkunoiden samanaikainen käsittely onnistuu (harvinaisempi tapaus) Swingissä on valmiita dialogi-ikkunoita: JFileChooser JColorChooser jne.
Dialogin toteuttaminen JFrame-luokan avulla asiakirjaikkuna kutsuu dialogi-ikkunaa kutsun yhteydessä päätetään myös modaalisuudesta (sopimuskysymys) dialogi-ikkunan riippuvuus asiakirjaikkunaan syntyy vasta kutsuhetkellä dialogi-ikkuna voidaan liittää useampaankin asiakirjaikkunaan
Työn iloa! Osio 4: Graafinen käyttöliittymä