Vesisika metsiemme työmyyrä http://www.billybear4kids.com/animal/whose-toes/capybara.jpg
Faktat Vesisika tykkää vedestä ja näyttää (ja kuulemma maistuu) hieman sialta. Käyttää myös nickiä kapybara. kapiÿva (guaranin kieltä), ruohikon valtias kaapĩ ûara (tupin kieltä), ruohonsyöjä Voi nukkua veden alla, kunhan sieraimet ei oo siellä. Tykkää ihmisistä, suosittu lemmikki Etelä-Amerikassa. ei kuitenkaan Brasiliassa, missä se levittää Kalliovuorten pilkkukuumetta :( http://upload.wikimedia.org/wikipedia/commons/b/bc/bristol.zoo.capybara.arp.jpg
Maailman suurin jyrsijä. Mieti sitä. vesisika 150 cm 80 kg majava 100 cm 25 kg orava 28 cm 0,4 kg
Luokkarakenne Nisäkäs Jyrsijä Sorkkaeläin Orava Cavy (marsueläin) Majava Sikaeläin Nautaeläin Marsu Vesisika!instanceof Sika Virtahepo Sikanautaeläin
Levinneisyys Jamaika (rastafareja) vesisikoja http://upload.wikimedia.org/wikipedia/commons/9/9d/capybara-range.png
Pakkaukset Pieni Java-projekti: kaikki luokat kiltisti samassa hakemistossa, ei ongelmaa. Iso Java-projekti: luokkien määrän kasvaessa kovin suureksi yksi kansio ei enää riitä. Ongelma ihmiselle, ei tietokoneelle. Muista ihmisen tiedonkäsittelyn rajat, enintään 7±2 hahmotettavaa yksikköä kerrallaan tietoisessa tarkastelussa. Luokkakokonaisuus pysyy hallittavana jakamalla se osakokonaisuuksiin, pakkauksiin (engl. package). Yhdessä pakkauksessa yhteen asiaan liittyvät luokat. Toimintalogiikan malli omassa pakkauksessaan, käyttöliittymä omassaan, jne. Nämä voidaan puolestaan edelleen jakaa useaan erikoistuneeseen pakkaukseen. Käytännössä saman pakkauksen luokat sijoitetaan aina samaan hakemistoon.
Pakkausten nimeäminen ja nimihierarkiat java.awt.event javax.swing.border org.w3c.dom org.omg.corba.portable virallinen Java (by Sun Microsystems) järjestöt (W3C, OMG,...) fi.tkk.inf.studio1.turnaus.labyrintti Egoboosti- ja brändäysprefiksit. (Huomaa päinvastainen logiikka kuin www-palvelinten osoitteissa: maa organisaatio osasto jne.) + Asettavat ohjelmiston suurempaan kontekstiin, luovat tunnistettavuutta. - Syventävät (muutenkin jo syvää) hakemistohierarkiaa. Robottiturnaussoftan labyrinttien esittämiseen käytetyt luokat voisivat sijaita tällaisessa pakkauksessa. Käytännössäkin luokat sijaitsisivat tuollaisen hakemistopolun päässä, esimerkiksi: C:\Javaproggikset\fi\tkk\inf\studio1\turnaus\labyrintti\ Labyrinttiruutu.java
Pakkausten käyttö 1 Pakkaus, johon luokka sijoittuu, määritellään: 1. Avainsanalla package aivan luokan lähdekoodin alussa: package fi.tkk.inf.studio1.turnaus.labyrintti; import java.util.arraylist; public class Labyrinttiruutu { 2. Tallentamalla luokkatiedosto oikeaan paikkaan hakemistohierarkiassa. Pakkaus rajaa luokkien näkyvyyttä niin, että vain samaan pakkaukseen kuuluvat luokat nähdään suoraan muiden pakkausten luokat on importoitava kuten Javan valmiit luokatkin.
Pakkausten käyttö 2 Eclipsessä pakkausten käyttö on helppoa ja visuaalista. Uusia pakkauksia luodaan samasta valikosta kuin uusia luokkiakin. Oletuksena kaikille projekteille luodaan oletuspakkaus (default package), mutta Eclipse ei arvosta, jos käytät sitä. Luokkia voi myöhemmin siirtää pakkauksesta toiseen Refactor-valikon Move-toiminnolla. Tämä päivittää automaattisesti kaikki viittaukset kyseiseen luokkaan ja lisää tarvittavat importit. Komentoriviympäristössä pakkaukset tuovat hieman enemmän haastetta. Kääntäminen ja ajaminen vaativat nyt ensin ns. classpathin määrittelemisen. set CLASSPATH=path1;path2;path3 (Windows) setenv CLASSPATH path1:path2:path3 (Unix) Näissä path1 jne. ovat hakemistopolkuja, joista (ja joiden alta) luokkia etsitään. Usein riittää nykyiseen hakemistoon osoittava polku eli pelkkä piste. Se on suhteellinen polku, eli muuttuu valitun hakemiston mukaan. Lisäksi luokkia ajaessa täytyy kertoa, mistä pakkauksesta (määritellyn classpath-hakemiston alta) kyseinen luokka löytyy: esim. java fi.tkk.inf.studio1.turnaus.turnaus &
Säikeet ja Swing Swingissä on yhden säikeen sääntö : realisoituneita käyttöliittymäkomponentteja tulee käsitellä ainoastaan yhdestä säikeestä, Swingin tapahtumankäsittelijäsäikeestä (event dispatching thread). Tapahtumankäsittelijäsäie on siis se, joka suorittaa kuuntelijoiden sopivien metodien kutsumisen vastaavien tapahtumien yhteydessä sekä kaikkien Swingkomponenttien piirtämisen ruudulle. Realisoitunut tarkoittaa sitä, että komponentti on tehty näkyväksi ruudulla. Ylimmän tason säiliöille (kuten JFrame) tämän tekee jokin metodikutsuista setvisible(true), show() tai pack(). Alemman tason komponentit realisoituvat, kun ne lisätään näkyvään säiliöön tai ne sisältävä säiliö tulee näkyväksi. Toisin sanoen vielä näkymättömän käyttöliittymän alustus voi periaatteessa tapahtua missä säikeessä tahansa, näkyvien komponenttien tilan tutkiminen ja muuttaminen sen sijaan vain tapahtumankäsittelysäikeessä. Yleensä on tyylikkäintä rajata kaikki GUI-toiminta tuon säikeen vastuulle. Joskus raskaiden uusien käyttöliittymäosakokonaisuuksien alustus voidaan kuitenkin tehdä omassa säikeessään, jottei tapahtumankäsittely hidastu tarpeettomasti.
Entäs sit ku oikeesti tarviin Swingissä muitaki säikeitä? Vai tarviinks? Case 1: Ajasta riippuvat tapahtumat ja javax.swing.timer Usein haluamme Swing-ohjelmaan myös käyttäjän tekemisistä riippumatonta toimintaa, esimerkiksi tietyin aikavälein toistuvia tapahtumia. Tällaiseen oma säie olisi luonteva ratkaisu, mutta hankala, koska se ei saisi käsitellä GUIkomponentteja suoraan. Toimiva ratkaisu on käyttää Swingin Timer-luokkaa. Se siirtää vastuun ajastetuista tapahtumista suoraan tapahtumankäsittelijäsäikeelle, joka toteuttaa ne uusina ActionEvent-tapahtumina määrätylle kuuntelijalle. Vähän kuin tapahtuman käynnistykseen olisi olemassa oma nappi, jota joku kävisi klikkaamassa vaikkapa sekunnin välein.
Entäs sit ku oikeesti tarviin Swingissä muitaki säikeitä? Vai tarviinks? Case 2: Työläissäie ja SwingUtilities.invokeLater()-metodi Raskaita ja aikaavieviä työtehtäviä, kuten vaativaa laskentaa tai suurten oliokokonaisuuksien alustusta, ei kannata suorittaa tapahtumankäsittelysäikeessä, koska tämä näkyisi suoraan käyttäjälle vuorovaikutuksen hidastumisena. Nämä kannattaa delegoida erityisille työläissäikeille, jotka rouskuttelevat omaa urakkaansa huomaamattomasti taustalla. Usein työläissäikeenkin on tarpeen saada aikaan jotakin näkyvää, esimerkiksi ilmoittaa työnsä tuloksista käyttöliittymän kautta. Tätä se ei kuitenkaan saa tehdä suoraan, vaan työläissäikeen pitäisi jotenkin saada vihjattua tapahtumankäsittelysäikeelle, että tämän olisi aika tehdä jotakin. Ratkaisu tähän kommunikaatio-ongelmaan on SwingUtilities-luokan metodi invokelater(runnable r), joka ottaa parametrinaan jotakin suoritettavaa (siis olion, jolla on metodi run()) ja siirtää sen suoritettavaksi tapahtumankäsittelysäikeessä myöhemmin, käytännössä hyvinkin pian. run()-metodissa on tyypillisesti koodia, joka yhdistää työläissäikeen työn tulokset ja graafisten käyttöliittymäkomponenttien käsittelyn sopivalla tavalla.