![]() |
Javan tapahtumankäsittely |
Ehkä suurimmat muutokset JDK 1.0:n ja JDK 1.1:n välillä liittyvät juuri tapahtumankäsittelyyn. Näiden versioiden tapahtumankäsittely eroaa toisistaan melkoisesti.
JDK 1.1:ssä ei tapahtumia edusta enää yksistään java.awt.Event-luokka, vaan käytössä on useiden tapahtumaluokkien hierarkia. Jokaisella tapahtumatyypillä on ns. pääluokka ja sen alla on tietyntyyppisten tapahtumien joukko.
Esimerkiksi pääluokka voi olla hiiritapahtuma tai vaikkapa näppäintapahtuma. Hiiritapahtuma -pääluokan alla ovat sitten kaikki mahdolliset hiiritapahtumat ja vastaavasti näppäintapahtuma -pääluokan alla kaikki näppäintapahtumat.
Seuraavassa tapahtumien pääluokat:
| ActionEvent | Kun käyttäjä valitsee jonkin graafisen elementin |
| AdjustmentEvent | Kun käyttäjä siirtää esim. hissiä vierityspalkissa |
| ComponentEvent | Kun käyttäjä muuttaa esim. komponentin kokoa tai sijaintia |
| ContainerEvent | Kun containeriin lisätään tai poistetaan komponentteja |
| FocusEvent | Kun komponentti saa/menettää fokuksen |
| InputEvent | Päätapahtuma kaikille komponenteista aiheutuneille tapahtumille, eli tämä generoidaan ennen varsinaista tapahtumaa |
| ItemEvent | Kun käyttäjä valitsee arvon esim. listasta |
| KeyEvent | Kun käyttäjä painaa jotain näppäintä |
| MouseEvent | Kun käyttäjä tekee jotain hiiren kanssa |
| TextEvent | Kun käyttäjä editoi tekstikomponentin sisältöä |
| WindowEvent | Kun käyttäjä muuttaa ikkunan ominaisuuksia |
Näppäimistötapahtumat:
Näppäimistön luku toteutetaan tapahtumaluokalla KeyEvent. Tapahtumaluokkaan kuuluu joukko valmiita funktioita (metodeja), joiden avulla voidaan lukea tapahtuman aiheuttaneen näppäimen tiedot. Funktiot ovat:
| getKeyChar() | Painettua näppäintä vastaava merkki |
| getKeyCode() | Painetun näppäimen koodi |
| getKeyModifiersText(int) | Palauttaa erikoisnäppäimet |
| getKeyText(int) | Palauttaa merkkijonon, jossa on näppäimen nimi (esim. F5) |
| isActionKey() | Tosi, jos näppäin kytketty johonkin toimintoon |
Lisäksi seuraavilla funktioilla voidaan muokata painetun näppäimen ominaisuuksia:
| setKeyChar(char) | Asettaa painetun näppäimen merkin |
| setKeyCode(int) | Asettaa painetun näppäimen koodin |
| setModifiers(int) | Asettaa erikoisnäppäimet |
Seuraavassa on lueteltu vielä näppäintapahtumiin liittyvät takaisinkutsuttavat funktiot:
| public void keyPressed (KeyEvent e) | Kutsutaan, kun käyttäjä painaa jotain näppäintä |
| public void keyReleased (KeyEvent e) | Kutsutaan, kun käyttäjä vapauttaa jonkin näppäimen |
| public void keyTyped (KeyEvent e) | Kutsutaan, kun käyttäjä painaa jotain näppäintä ja vapauttaa sen välittömästi |
Parametrina välitettävä KeyEvent-olio sisältää näppäintapahtuman kaikki tarvittavat tiedot näppäintapahtuman aiheuttaneesta näppäimestä. Seuraavassa on lueteltuna muutamia näppäinkoodeja, jotka voidaan tutkia vertaamalla niitä tapahtuman jälkeen getKeyCode()-funktiolla saatavaan arvoon:
| VK_UP | ylänuoli |
| VK_DOWN | alanuoli |
| VK_RIGHT | oikea nuoli |
| VK_LEFT | vasen nuoli |
| VK_HOME | <Home>-näppäin |
| VK_INSERT | <Ins>-näppäin |
| VK_DELETE | <Del>-näppäin |
| VK_PGDN | <PageDown> |
| VK_PGUP | <PageUp> |
| VK_F1-VK_F12 | funktionäppäimet |
| VK_A-VK_Z | Isot kirjaimet |
| VK_END | <End>-näppäin jne ... |
Nämä näppäinkoodien määrittelyt löytyvät Javan API-luokasta java.awt.event.KeyEvent.
Erikoisnäppäinten (esim. Shift, Alt ja Ctrl) luku tapahtuu myös getKeyCode()-funktiolla. Tämän funktion tulos ohjataan edelleenkin getKeyText()-funktiolle, jolloin saadaan tekstimuodossa painetun näppäimen nimi. (esim. SHIFT, ALT tai CTRL).
Seuraava esimerkki havainnollistaa näppäimistötapahtumien käsittelyä JDK 1.1:ssä:



keyPressed-funktio olisi voitu myöskin toteuttaa seuraavasti:

Seuraavassa pieni selvitys edelliseen esimerkkiin liittyvistä tekniikoista:
Tapahtumien sallinta ja kuuntelijat:
Toisin kuin JDK 1.0:ssa, täytyy JDK 1.1:ssä olioiden sallia tapahtumat ennen kuin ne lähetetään ko. oliolle käsiteltäväksi.
Tapahtumat voidaan sallia olioiden setListener- ja addListener-funktioilla (metodeilla).
setListener-funktiolla sallitaan yksittäisjaettu tapahtuma, mikä tarkoittaa sitä, että vain yksi olio voi kuunnella tapahtumaa.
addListener-funktiolla puolestaan sallitaan ns. monijaettu tapahtuma, mikä tarkoittaa sitä, että useampi olio voi kuunnella tapahtumaa.
Kaikki AWT-komponentit tukevat ainoastaan monijaettuja tapahtumia, joten jatkossa käytämme lähes yksinomaan addListener-funktiota tapahtumien sallimiseen.
Jotta JDK 1.1:ssä voisi jokin olioluokka vastaanottaa viestejä, täytyy siitä tehdä ns. kuuntelija. Kuuntelija olio toteutetaan Listener-tajapinnan avulla. Jokaiselle päätapahtumalle on olemassa oma Listener-rajapinta. Listener-rajapintajako noudattaa yleistä tapahtumaluokkajakoa JDK 1.1:ssä) (vrt. aiemmat yleiset tapahtumaluokat).
Seuraavassa on lueteltu Listener-rajapintojen nimet:
| ActionListener | KeyListener |
| AdjustmentListener | MouseListener |
| ComponentListener | MouseMoveListener |
| FocusListener | TextListener |
| ItemListener | WindowListener |
Edellisessä esimerkissä toteutimme Appletille ActionListener- ja KeyListener-rajapinnat, koska olimme kiinnostuneita näiden tapahtumaluokkien tapahtumista (ActionListener => Painonapin painalluksen käsittely ja KeyListener => Näppäinten käsittely).
Lisäksi sallimme ensimmäiselle painonapille (nappi1) näppäintapahtumat ja toiselle painonapille normaalit aktivointi-viestit (Click).

| HUOMAA !!!, että kuuntelijarajapinnan (tässä esimerkissä Appletti) on toteutettava kaikki kuuntelemansa Listener-rajapinnan tapahtumafunktiot. |
Esimerkiksi KeyListener-rajapinnalla on seuraavat tapahtumafunktiot:
| keyPressed, keyReleased ja keyTyped |
Eli kaikki nämä on toteutettava, vaikkei niitä käyttäisikään kuten meidänkin esimerkissämme.
ActionListener-rajapinnalla on ainoastaan yksi tapahtumafunktio:
| actionPerformed |
ActionListener-rajapintaa käytetään nimenomaan eri komponentteihin kohdistuneiden tapahtumien käsittelyyn (esim. tämän esimerkin painonapin tapahtumakäsittelijä).
Hiiritapahtumat:
Hiiritapahtumien käsittelyyn on JDK 1.1:ssä tarkoitettu tapahtumaluokat MouseEvent ja .
Seuraavassa on lueteltu em. olioiden funktiot (metodit), joiden avulla voidaan tutkia hiiritapahtumaan liittyvää tietoa:
| getClickCount() | Palauttaa klikkausten määrän |
| getPoint() | Palauttaa hiiren koordinaatit Point-oliossa |
| getX() | Hiiren X-koordinaatti |
| getY() | Hiiren Y-koordinaatti |
| isPopupTrigger | Tosi, jos Popup-menun valinta |
JDK 1.1:ssä hiiritapahtumien käsittely toteutetaan kahdella kuuntelijalla:
| MouseListener | Vastaa hiiren nappien painalluksista/ vapautuksista |
| MouseMotionListener | Vastaa hiiren raahaamisesta ja liikuttamisesta |
Seuraavassa on kaikki MouseListener rajapinnan sisältämät funktiot ja niiden tarkoitus (muistathan, että kaikki nämä täytyy määritellä).
| public void mousePressed (MouseEvent e) { } | Reagoi hiiren vasemman näppäimen painallukseen |
| public void mouseClicked (MouseEvent e) { } | Reagoi Komponenttien klikkauksiin (esim. painonapin painamiseen) |
| public void mouseReleased(MouseEvent e) { } | Reagoi hiiren vasemman näppäimen vapautukseen |
| public void mouseEntered (MouseEvent e) { } | Reagoi siihen että hiirikursori siirretään jonkin komponentin päälle |
| public void mouseExited (MouseEvent e) { } | Reagoi siihen, että hiirikursori poistuu jonkin komponentin päältä |
| public void mouseDragged (MouseEvent e) { } | Reagoi siihen, että hiirtä liikutetaan vasen näppäin pohjassa |
| public void mouseMoved (MouseEvent e) { } | Kun hiirtä liikutetaan ilman vasemman napin painamista |
Seuraavat esimerkit havainnollistavat hiiritapahtumien käsittelyä JDK 1.1:ssä.
Kun hiirtä liikutetaan, tulostetaan selaimen tilapalkkiin aina kulloisetkin hiiren koordinaatit:



Tässä esimerkissä toteutamme jo aiemmin esillä olleen piirrustusohjelman JDK 1.1:n mukaisella tavalla:



Tässä kappaleessa käsittelimme tapahtumankäsittelyä JDK 1.0:ssa ja JDK 1.1:ssä pääasiassa vain näppäimistö- ja hiiritaphtumien osalta.
Ainakin yhtä tärkeä tapahtumankäsittelyn osa-alue on erilaisiin käyttöliittymän komponentteihin kohdistuneet tapahtumat (esim. painonapin painaminen). Nämä tapahtumathan yleensä muodostavat nykyaikaisissa tapahtumaohjatuissa ohjelmissa pääosan niistä tapahtumista, joihin ohjelmassa reagoidaan (=kirjoitetaan käsittelijät)
Käyttöliittymäkomponentteihin kohdistuvien tapahtumien käsittelyyn tutustumme myöhemmin tässä opintojaksossa samassa yhteydessä grraafisten käyttöliittymäkomponenttien ohjelmoinnin kanssa.
Harjoituksia:
| 1. | Toteuta piirto-ohjelmaan (Esim21) käyttäjälle mahdollisuus valita piirtoväri muutamasta vaihtoehdosta. Toteuta myös mahdollisuus muuttaa vaikkapa rullausjanan avulla pensselin paksuutta. |
| 2. | Joissain kännykkämalleissa on ns. "matopeli". Ota tämän kappaleen ensimmäinen esimerkki (Esim19) lähtökohdaksi ja ohjelmoi siitä yksinkertainen "matopeli" tai jokin muu vastaava nuolinäppäimillä ohjattava peli. Kokeile myös muiden näppäinten (kuin nuolinäppäimet) ohjelmointia. |