![]() |
Graafinen käyttöliittymä (AWT) |
Seuraavaksi tutustumme erilaisiin Windows-ohjelmien käyttöliittymäkomponentteihin kuten painikkeisiin, tekstikenttiin, listoihin jne.
Java 1.1 -ohjelmissa käyttöliittymän osat luodaan AWT-kirjaston (Abstract Window Toolkit) olioiden avulla. Java 2:ssa on myös käytössä Swing-käyttöliittymäkirjasto, joka tarjoaa AWT-kirjastoa monipuolisemmat käyttöliittymäelementit. Kuten jo aiemmin on tullut ilmi, on Java 2:n käyttö Applettien toteutuksessa arveluttavaa huonon selaintuen vuoksi.
Tässä yhteydessä tutustumme AWT-kirjaston käyttöön.
Painonapit
Painonappi on ehkä yleisin käyttöliittymän komponentti.
Javassa painonapit luodaan luokan Button avulla.
Seuraava esimerkki havainnollistaa painonappiolion käyttöä:



Kun painonappiolion ilmentymä on luotu, se täytyy vielä tuoda näkyviin add-metodin avulla esimerkin mukaisesti.
Painonapin kokoa ja sijaintia voidaan muuttaa painonappiolion reshape-metodilla.
Painonapille voidaan tarvittaessa myös antaa uusi teksti olion omalla setLabel-metodilla ja vastaavasti painonapin teksti voidaan lukea getLabel-metodilla.
Painonapin tapahtumakäsittelystä:
Kuten aiemmin on jo tullut ilmi, on Java-ohjelmointi windows-ohjelmoinnille tyypillistä tapahtumaohjattua ohjelmointia.
Tapahtumien käsittelyä varten on olemassa joukko valmiita metodeja eli ns. tapahtumakäsittelijöitä. JDK 1.0 ja 1.1 eroavat toisistaan juuri tapahtumakäsittelyn osalta melko paljon.
JDK 1.0:n tapahtumakäsittelystä oli aiemmin tässä kurssimateriaalissa muutama esimerkki. Jatkossa keskitymme kuitenkin JDK 1.1-tyyppiseen tapahtumakäsittelyyn.
Painonappien painamisesta aiheutuvat tapahtumat välitetään ActionListener-rajapinnan kautta.
Lisäksi täytyy kullekin komponentille (painonapille) asettaa kuuntelija addActionListener-metodin avulla, jolloin tapahtumat otetaan vastaan.
Varsinainen tapahtumakäsittelyn koodi kirjoitetaan takaisinkutsuttavaan funktioon actionPerformed.
Painonapin voi enabloida ja disbloida metodeilla nappi.enable() ja nappi.disable().
Lisäksi painonapin voi piilottaa metodilla nappi.hide() ja tuoda taas näkyviin metodilla nappi.show().
Tekstikentät
Normaalit tekstikentät luodaan luokan TextField avulla ja näytetään add-metodin avulla.
TextField-oliolla on neljä erilaista muodostinta riippuen siitä, minkätyyppinen tekstikenttä kulloinkin halutaan:
| TextField() | Luo tyhjän tekstikentän |
| TextField(int) | Luo tyhjän tekstikentän jolla on haluttu pituus |
| TextField(String) | Luo tekstikentän, johon sijoitetaan alkuarvo |
| TextField(String, int) | Luo tekstikentän, jossa on alkuarvo ja jolla on tietty pituus |
Tekstikenttäolion tärkeimmät tekstinkäsittelymetodit ovat:
| getText() | Palauttaa tekstikentän tekstin |
| setText(String) | Sijoittaa tekstiä tekstikenttään |
| getSelectedText() | Palauttaa maalatun tekstin |
| getSelectionEnd() | Palauttaa maalatun tekstin lopun |
| getSelectionStart() | Palauttaa maalatun tekstin alun |
| select(int, int) | Aktivoi tekstin halutulta väliltä |
| selectAll() | Aktivoi koko tekstin |
| isEditable() | True, jos tekstikenttää voi editoida |
| setEditable(boolean) | Asettaa editoinnin päälle/pois |
| getColumns() | Tekstikentän koko sarakkeina |
Salasanojen yhteydessä voi lisäksi valita halutun kaiutusmerkin metodilla:
| setEchoCharacter(char) |
Seuraava esimerkki havainnollistaa tekstikenttien käyttöä:



Tekstialueet
Tekstialueet toimivat melko tarkasti tekstikenttien tapaan.
Tekstialueet luodaan oliotyypin TextArea avulla.
TextArea-oliolla on neljä erilaista muodostinta riippuen siitä, minkätyyppinen tekstialue kulloinkin halutaan:
| TextArea() | Luo tyhjän tekstialueen |
| TextArea(int, int) | Luo tyhjän tekstikentän, jolla on haluttu korkeus ja leveys |
| TextArea(String) | Luo tekstialueen, johon sijoitetaan alkuarvo |
| TextArea(String, int,int) | Luo tekstialueen, jossa on alkuarvo ja jolla on tietty korkeus ja leveys |
Tekstialueelle on käytössä aivan samat metodit kuin tekstikentällekin (ks. tekstikentän metodit).
Lisäksi tekstialueella on muutama aivan oma erityinen metodi:
| appendText(String) | Lisää tekstin tekstialueen loppuun |
| getRows() | Palauttaa rivien määrän |
| insertText(String, int) | Lisää tekstin haluttuun kohtaan |
| replaceText(String, int, int) | Korvaa tekstin tekstialueelle kirjoitetulla tekstillä haluttujen merkkien väliseltä alueelta |
Seuraava esimerkki havainnollistaa tekstialueen käyttöä:




Valintaruudut ja radionapit
Valintaruudut luodaan olion Checkbox avulla aivan kuten radionapitkin, mutta valintaruudut eivät muodosta ryhmää vaan ovat itsenäisiä olioita.
Seuraava esimerkki havainnollistaa valintaruutujen käyttöä:



Radionappeja voidaan lisätä aivan vastaavasti Java-sovellukseen CheckboxGroup- ja Checkbox-olioiden avulla seuraavan esimerkin mukaisesti:



Sekä radionapit että valintaruudut voivat käyttää seuraavia metodeja:
| getLabel() | Palauttaa radionapin/valintalaatikon tekstin |
| setLabel() | Sijoittaa radionapille/valintalaatikolle tekstin |
| getState() | Palauttaa radionapin/valintalaatikon tilan |
| setState() | Sijoittaa radionapin/valintalaatikon tilan |
Luettelot ja valintalistat
Erilaiset luettelot toteutetaan Javassa olioiden Choice (valintalista) ja List (luettelo) avulla.
Choice (valintalista):
Valintalistan käyttökelpoisimmat metodit ovat:
| addItem(String) | Lisää uuden alkion listaan |
| countItems() | Palauttaa valintalistan alkioiden lukumäärän |
| delItem(int) | Poistaa alkion listasta |
| getItem(int) | Lukee halutun alkion (otsikon) nimen |
| getSelectedItem() | Palauttaa valitun alkion nimen |
| getSelectedIndex() | Palauttaa valitun alkion järjestysluvun |
| select(int) | Valitsee halutun alkion ohjelmallisesti indeksin avulla |
| select(String) | Valitsee halutun alkion ohjelmallisesti tekstin avulla |
List (luettelo):
Luettelon käytetyimmät metodit ovat:
| addItem(String) | Lisää uuden alkion listaan |
| allowsMultipleSelections() | True, jos monivalintaisuus on sallittu |
| clear() | Tyhjentää listan |
| countItems() | Palauttaa listan alkioiden lukumäärän |
| delItem(int) | Poistaa alkion listasta |
| delItems(int, int) | Poistaa alkiot annetulta väliltä |
| getItem(int) | Lukee halutun alkion (otsikon) nimen |
| getSelectedItem() | Palauttaa valitun alkion nimen |
| getSelectedItems() | Palauttaa valitujen alkion nimet |
| getSelectedIndex() | Palauttaa valitun alkion järjestysluvun |
| getSelectedIndexes() | Palauttaa valittujen alkioiden järjestysluvut |
| isSelected(int) | Palauttaa arvon true, jos ko. alkio on valittu |
| select(int) | Valitsee halutun alkion ohjelmallisesti indeksin avulla |
| select(String) | Valitsee halutun alkion ohjelmallisesti tekstin avulla |
Seuraava esimerkki havainnollistaa valintalistan käyttöä:




Vierityspalkit
Vierityspalkit voidaan toteuttaa Javassa oliotyypin Scrollbar avulla. Osassa käyttöliittymäelementtejä, kuten tekstialueella ja listoissa, vierityspalkit ovat sisäänrakennettuna ominaisuutena.
Vierityspalkki luodaan seuraavankaltaisella muodostimella:
| Scrollbar(suunta, hissi, sivun koko, min, max) |
Vierityspalkin arvot voidaan asettaa myös ajon aikana metodilla:
| setValues(suunta, hissi, sivun koko, min, max) |
Hissin sijainti voidaan muuttaa metodilla:
| setValue(sijainti) |
Vierityspalkin tilaa voidaan tutkia seuraavilla metodeilla:
| getMaximum() | Palauttaa max-arvon |
| getMinimum() | Palauttaa min-arvon |
| getOrientation() | Palauttaa suunnan |
| getValue() | Palauttaa hissin sijainnin |
Seuraava esimerkki havainnollistaa vierityspalkin käyttöä:



Käytimme handleEvent-metodia vierityspalkin tapahtumakäsittelyyn, koska action-metodia ei voi käyttää vierityspalkkien tapahtumiin.
Vakiotekstit
Otsikkotyyppisiä pysyviä merkkijonoja voidaan luoda näytölle Java-kielessä Label-olion avulla.
Tietenkin otsikkotiedot voidaan tulostaa myös suoraan aiemmin esitellyillä merkkijonojen tulostusmenetelmillä.
Seuraava esimerkki havainnollistaa Label-olion käyttöä:



Kaksi tapaa sijoittaa komponentteja
Mikäli halutaan rakentaa Java-sovelluksiin kunnollisia käyttöliittymiä, täytyy käyttöliittymän komponentit saada sijoitettua juuri halutuille paikoille.
Komponenttien sijoitteluun on olemassa kaksi tapaa:
| Komponenttien omat sijoitusmetodit |
| Layoutit |
Komponenttien sijoitusmetodit
Aikaisemmissa esimerkeissä olemme sijoitelleet käyttöliittymän komponentit halutulle kohdalle käyttäen niiden omia metodeja.
Tällaisia sijoitus-/koonmuutosmetodeja ovat:
| reshape(x,y,leveys,korkeus) | Siirtää komponentin määrättyyn paikkaan ja muuttaa komponentin määrätyn kokoiseksi (JDK 1.0) |
| setLocation(x,y) | Siirtää komponentin määrättyyn paikkaan |
| setBounds(x,y,korkeus, leveys) | Toimii kuten reshape (JDK 1.1) |
| setSize(leveys,korkeus) | Muuttaa komponentin kokoa |
Seuraava esimerkki havainnollistaa komponenttien sijoittelua:

Layoutit
Kun graafiset komponentit sijoitetaan näytölle, käytetään tiettyä ennalta määriteltyä mallia, kuten olet jo huomannut tapahtuvan silloin, jos et ole käyttänyt reshape-metodia sijoittaaksesi komponentteja juuri haluttuun kohtaan.
Tähän oletussijoitteluun voidaan vaikuttaa Java-kielessä käyttämällä erilaisia Layout-käsittelijöitä.
Layout-käsittelijät ovat: FlowLayout (oletus), GridLayout, BorderLayout, CardLayout ja GridBagLayout.
FlowLayout:
FlowLayout on oletusmuotoilu ellei muotoilua erikseen määritellä.
FlowLayoutin luomiseen voidaan käyttää kolmea erityyppistä muodostinta:
| FlowLayout() | Luo oletus Layoutin |
| FlowLayout(int) | Luo tasatun Layoutin (CENTER,LEFT tai RIGHT) |
| FlowLayout(int, int, int) | Luo käyttäjän määrittelemän
Layoutin, jossa parametrit ovat: * tasaus * vaakasuora tyhjä väli * pystysuora tyhjä väli |
Seuraava esimerkki havainnollistaa FlowLayout-muotoilun käyttöä:



Eli FlowLayout-käsittelijä sijoittaa komponentit vasemmalta oikelle sekä lisää tarvittessa myös uusia rivejä.
BorderLayout:
BorderLayout sijoittaa komponentit näytön reunoille käyttäen apunaan ilmansuuntia (North, South, East, West) sekä arvoa Center.
Kaikki ylimääräinen tila annetaan alueelle Center.
BorderLayoutin luomiseen voidaan käyttää kahta erilaista metodia:
| BorderLayout() | Komponentit täyttävät alueet |
| BorderLayout(int, int) | Käyttäjä voi vaikuttaa
komponenttien väleihin * vaakasuora tyhjä väli * pystysuora tyhjä väli |
Seuraava esimerkki havainnollistaa BorderLayoutin käyttöä:



GridLayout:
GridLayoutissa komponentit sijoitetaan samankokoisista ruuduista muodostuvaan ruudukkoon. Rivien ja sarakkeiden määrä täytyy ilmoittaa.
Jokainen komponentti vie ruudukon alkiosta niin paljon tilaa kuin vain voi.
GridLayout-oliolla on kaksi muodostinta:
| GridLayout(int, int) | Luo layoutin siten, että parametreinä annetaan rivien ja sarakkeiden lukumäärät |
| GridLayout(int,int,int, int) | Luo layoutin siten, että solujen väliin jää tyhjää tilaa. Parametreinä annetaan rivien ja sarakkeiden lukumäärä sekä vaakasuora- ja pystysuora tyhjä väli. |
Seuraava esimerkki havainnollistaa Gridlayout-komponentin käyttöä:



GridBagLayout:
GridBagLayout on kaikkein monipuolisin layout-käsittelijä, jonka avulla voidaan tasata erikokoisia komponentteja vaaka- ja pystysuunnassa.
Erikokoisten komponenttien tasaukset saadaan aikaiseksi käyttämällä komponenttien yhteydessä ns. rajoittimia.
Rajoitinten määrittämiseksi on määriteltävä ilmentymä oliolle GridBag-Constrains. Tämän olion ominaisuudet ovat:
| gridx, gridy | Komponentin x- ja y-sijainti piirtoalueella. Käyttämällä arvoa GridBagConstraints.RELATIVE saadaan komponentti sijoitettua edellisen komponentin oikealle puolelle tai alapuolelle. |
| gridwidth, gridheight | Komponentin näyttöpinnan sarakkeiden ja rivien lukumäärä |
| fill | Käytetään kun komponentti on
suurempi kuin sen näyttöalue: * NONE = ei täyttöä (oletus) * HORIZONTAL = täyttö vaakasuunnassa * VERTICAL = täyttö pystysuunnassa * BOTH = täyttö molemmissa suunnissa |
| ipadx,ipady | Ilmoittaa, kuinka paljon tilaa kunkin komponentin ympärille lisätään |
| insets | Ilmoittaa kuinka paljon komponentin ja sen näyttöalueen reunojen väliin jätetään vähintään tilaa |
| anchor | Käytetään, jos komponentti on pienempi kuin sen näyttöalue: CENTER (oletus), NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NOTHWEST |
| weightx, weighty | Käytetään määrittelemään tilan jako komponentin ja piirtoalueen reunan välissä. Vähintään yhdellä komponentilla kullakin rivillä ja sarakkeessa kannattaa olla painoarvo, etteivät kaikki komponentit keskittyisi |
Seuraava esimerkki havainnollistaaa GridBagLayout-käsittelijän käyttöä:




CardLayout:
Tätä layout-käsittelijää käytetään silloin, kun näytölle halutaan eri tilanteissa erilaisia komponentteja.
CardLayoutin muodostimet ovat:
| CardLayout() | Oletusasetus |
| CardLayout(int, int) | Käyttäjän määrittelemä layout, jossa parametreinä annetaan vaakasuora tyhjä väli ja pystysuora tyhjä väli |
Eri näyttöjä (kortteja) voidaan kelata seuraavien metodien avulla:
| first(this) | Ensimmäinen kortti |
| last(this) | Viimeinen kortti |
| next(this) | Seuraava kortti |
| previous(this) | Edellinen kortti |
| show(this,String) | Näyttää tietyn kortin |
CardLayout-sijoittelua käytetään erittäin harvoin.
Useamman layoutin yhdistäminen:
Käytännössä joudutaan usein haluttuun lopputulokseen pääsemiseksi yhdistämään useita eri layout-käsittelijöitä seuraavan esimerkin mukaisesti:



Harjoituksia:
| 1. | Toteuta yksinkertainen nelilaskin Javalla. |
| 2. | Toteuta jonkin kuvitellun tuotteen tilauslomake Javalla. Tiedot vastaanottavaa serveripään ohjelmaa ei tarvitse tehdä eli pelkkä käyttöliittymä riittää. |
| 3. | Toteuta Javalla valuuttamuunnin, joka muuttaa euroja markoiksi sekä päinvastoin. Selvitä vaihtokurssi internetistä. Voit ottaa mukaan myös muita valuuttoja. |
| 4. | Toteuta jokin yksinkertainen muutaman vaihtoehtokysymyksen tietokilpailu Javalla. Eikö olisi aika tyylikästä antaa kilpailijalle palautetta äänen avulla (puhe/musiikki). |