Eclipse & WindowBuilder Yleistä asiaa WindowBuilder on Eclipsessä oleva työkalu, jolla voi graafisesti tehdä käyttöliittymiä. Käyttö perustuu siihen, ettei varsinaista ohjelmakoodia tarvitse itse tehdä, vaan WindowBuilder generoi sen automaattisesti, kun ohjelman käyttäjä asettelee eri käyttöliittymäelementtejä. Huom! Näissä ohjeissa oletetaan, että Eclipsen käyttö on edes jokseenkin tuttua. Jos ei, niin äkkiä opettelemaan. Syventävämmät ohjeet löytyvät Ohjelmointi 2:sen sivuilta. Siellä neuvotaan tarkemmin esimerkiksi WindowBuilderin asentaminen, jos sitä ei olekaan Eclipsen mukana, ja muita hyödyllisiä hienosäätöjä. Linkki: https://trac.cc.jyu.fi/projects/ohj2/wiki/windowbuilder WindowBuilderin käyttöönotto askel askeleelta Avaa Eclipse. Jos olet asentanut uusimman version, WindowBuilderin pitäisi olla valmiiksi jo asennettuna. Jos sitä ei jostain syystä ole (tai omaat vanhemman version Eclipsestä), seuraa näitä asennusohjeita: https://trac.cc.jyu.fi/projects/ohj2/wiki/ohj2eclipse#windowbuilder Jos kaikki on kunnossa, on aika siirtyä eteenpäin. Käyttöliittymäsuunnittelua varten Eclipsessä pitää tehdä JFrame-luokan instanssi. Tämä onnistuu valitsemalla projektin kohdalla oikealla hiiren klikkauksella New -> ja sitten Other jolloin näyttöön avautuu seuraavanlainen ikkuna:
Ylläolevassa ikkunassa siis valitaan JFrame ja painetaan Next >. Luotavalle käyttöliittymäikkunalle pitää valita Eclipsen projekti, johon se kuuluu ja nimetä se jotenkin soveltuvasti. Tässä esimerkissä annamme sille nimen TestiIkkuna. Paina sitten Finish-nappulaa. Tämän jälkeen ohjelma luo geneerisen käyttöliittymäikkunan, joka avautuu koodinäkymään tällaisena: Tässä vaiheessa ohjelmakoodista ei tarvitse välittää, mutta on syytä ymmärtää, että siinä on vain käyttöliittymäikkuna koodipohjaisesti ja ettei WindowBuilder tee muuta kuin parsi tämän koodin graafiseen muotoon ja graafisen muodon vuoroin koodimuotoon. Parsiminen onnistuu ja WindowBuilder-näkymä avautuu, kun kuvan mukaisesti klikkaa vasemmassa alakulmassa olevaa Design-nappulaa. Silloin aukeaa varsinainen WindowBuilder-näkymä, joka näyttää tältä:
Käyttöliittymän rakennus tapahtuu ylläolevan näkymän kautta. Peruskäytöltään siis valitaan keskimmäisestä paletista elementtejä, joita pistetään oikealla olevaan käyttöliittymänäkymään, joka on vielä tässä vaiheessa pelkkä tyhjä ikkuna. HUOM! Kaikki käyttöliittymäelementit ovat itsestään jo olioita, esimerkiksi kun pistät näkymään uuden JButton-nappulan, se luo myös ohjelmakoodiin uuden JButton-olion. Paletin eri elementit jakautuvat ryhmiin, joista seuraavat ovat käyttöliittymän kannalta olennaisia: Containers Nämä ovat nimensä mukaisesti säiliöitä, eli niiden sisälle ladotaan kaikkia muita komponentteja ja vähemmänkin monimutkaisemmissa käyttöliittymissä myös sisäkkäisiä säiliöitä. Perusilmentymä on JPanel, johon vain yksinkertaisesti sisällytetään muita elementtejä. Käyttöliittymän rakenteesta huomaa, että siellä on jo valmiiksi yksi JPanel nimeltä contentpane. Tämän tulee olla käyttöliittymäikkunassa, muuten mitään muuta ei saa laitettua! Layouts Määrittelevät asettelutyylin sille elementille, johon ne asetetaan. Asettelutyyli tarkoittaa sitä, miten elementit asemoituvat: esimerkiksi jos JPaneliin asettaa Absolute layoutin, elementit asemoituvat tasan tarkalleen siihen, mihin käyttäjä ne sijoittaa. Jos on tarkoituksena tehdä pelkkä staattinen näkymä, voi asettelu hyvinkin olla absoluuttinen. Tällöin tulee vain ottaa huomioon, etteivät elementit skaalaudu ruudun mukana, jos sen kokoa tai muotoa muutetaan. Components Nämä ovat keskeisimpiä elementtejä. Otsikon alta löytyvät muun muassa nappulat, tekstikentät ynnä muut toiminnallisemmat elementit, joita käyttöliittymänäkymään ladotaan. Menu Tästä valikosta löytyy kaikenlaisia käteviä valikkoelementtejä. Esimerkiksi JMenuBar on helppo tapa tehdä useimmista ohjelmista löytyvä ylävalintapalkki.
Asetetun komponentin ominaisuuksia pääsee muokkaamaan valitsemalla sen käyttöliittymänäkymässä, jolloin sen tiedot avautuvat vasemman alakulman Properties-ikkunaan. Siinä voi tarkemmin määritellä esimerkiksi värejä ja elementin reunan tyylejä. Seuraavaksi esitellään lyhyesti joitain yleisimpiä komponentteja: JButton Painike, jota käyttäjä voi painaa ja joka käynnistää jonkin toiminnon, eli esimerkiksi avaa uuden ikkunan tai mitä vaan keksiikään sillä tehdä. JTextField Yhden rivin tekstikenttä, johon käyttäjä voi kirjoittaa jotakin. JTable Taulukko, jossa on tietty määrä rivejä ja sarakkeita. Erittäin kätevä monimuotoisemman datan esittämiseksi. JLabel Kenttä, johon voi laittaa tekstiä tai kuvan, mutta jota käyttäjä ei pääse muokkaamaan ja jota painamalla ei voi toteuttaa toimintoja. Koodinäkymään pääsee takaisin klikkaamalla vasemman alakulman Source-nappulaa Muutama sana layouteista ja asetteluista Kun lähtee tekemään käyttöliittymäsuunnittelua, saattaa olla jo melko selkeä kuva siitä, mitä haluaa saavuttaa. Hyvä käytäntö onkin, että ensin hahmottelee paperille, miltä haluaisi käyttöliittymän näyttävän. WindowBuilder ei välttämättä ole kaikista helppokäyttöisin työkalu, sillä asetteluissa tarvitsee käyttää välttämättä layouteja, joista mainittiin jo aiemminkin. Layoutin pystyy asettamaan vain ja ainoastaan johonkin Container-komponenttiin (kuten JPanel) ja se määrittelee, miten tuon säiliön alaiset komponentit asemoituvat. Yllä on havainnollistava kuva GridLayoutin käytöstä. Tämä jakaa säiliön yhtä suuriin, neliönmuotoiin osioihin, jolloin neljä laitettua komponenttia (kaksi painiketta, yksi tekstikenttä ja yksi kirjoituskenttä) asemoituvat siististi neliömuodostelmaan.
Vähänkään monimutkaisimmissa käyttöliittymässä asettelu ei kuitenkaan ole näin yksinkertaista, vaan säiliöihin pitää laittaa sisäkkäisiä säiliöitä, joissa vuorostaan määritellään omat layoutinsa! Alla karkea esimerkki: Ylimpänä komponenttina ylläolevassa ikkunassa on JPanel, joka on jaettu BorderLayoutilla viiteen eri sektoriin (constraints): north, south, west, east ja center. Keskimmäiseen sektoriin on pistetty vielä sisäkkäinen JPanel, joka sekin käyttää BorderLayoutia. Tämä ei ole mikään esimerkki hyvästä saati esteettisestä käyttöliittymäsuunnittelusta, mutta perusidea toivottavasti tulee ilmi: laittamalla elementtejä sisäkkäin eri säiliöihin saadaan aikaan monimutkaisempia rakenteita. Tai sitten voi käyttää AbsoluteLayoutia, jolloin ei tarvitse ollenkaan miettiä, miten jonkin palkin saa juuri siihen, mihin haluaisi, sillä AbsoluteLayoutilla komponentti asemoituu tasan siihen, mihin se pistettiin. MUTTA! Tämä ei ole suvaittava käytäntö, sillä käyttöliittymäikkuna ei ole silloin ollenkaan skaalautuva ja aiheuttaa aivan varmasti varsinaisen ohjelman toiminnassa ongelmia. Unohda siis suosiolla tällaiset petolliset oikopolut ;-) Oraclella on varsin kätevä ohjeistus layouteista: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html Toiminnallisuuden lisääminen (sisältää hieman koodausta) Tehdään malliksi aiemmin luotuun käyttöliittymäikkunaan painike, jota painamalla ohjelma toivottaa käyttäjälle hyvää päivää. Valitaan siis keskimmäisestä paletista Components-osiosta JButton ja asetetaan se käyttöliittymänäkymään:
Ylläolevassa kuvassa huomaa, että ikkunaan on ilmestynyt uusi elementti, JButton, jossa lukee teksti New button. Lisätyn painikkeen näkee myös rakenneikkunassa, ja uusi nappula on myös valittuna vasemman alakulman Properties-ikkunassa. Toiminnallisuutta varten painikkeeseen pitää lisätä niin kutsuttu tapahtumankäsittelijä (event handler), joka osaa välittää nappulan painelut ohjelmakoodille. Tapahtumankäsittelijän lisääminen painikkeelle onnistuu seuraavasti: 1. Klikkaa painiketta joko rakenne- tai käyttöliittymänäkymässä hiiren oikealla näppäimellä. 2. Valitse Add event handler 3. Huomaat, että on lukuisia erilaisia tapahtumankäsittelijöitä, jotka rekisteröivät tapahtumia eri tavoin, mutta tässä tapauksessa valitaan ylin, eli action -> Action performed Tämän tehtyäsi ikkuna vaihtuukin takaisin koodinäkymään: Yllä näkee, että ensinnäkin siinä on laittamasi JButton-olio, alustettuna muuttujaan btnnewbutton. Lisätty tapahtumankäsittelijä ilmenee metodissa actionperformed, jota vain yksinkertaisesti kutsutaan aina, kun painiketta painetaan. Tällä hetkellä metodi ei toteuta mitään, joten lisätään siihen toiminto, joka avaa pienen ikkunan, joka toivottaa Hyvää päivää :
Nyt painiketta painamalla pitäisi tapahtua jotakin. Yllä olevan JOptionPane-luokan metodi showmessagedialog vain näyttää halutun tekstin. Pistä ohjelma käyntiin ja paina painiketta. Pitäisi tapahtua suurin piirtein näin: Aina, kun nappia painaa, se siis tekee pienen ikkunan, joka toivottaa hyvää päivää. Kaiken toiminnallisuuden lisääminen perustuu tähän samaan periaatteeseen: lisätään elementille jonkinlainen tapahtumankäsittelijä, sitten koodissa määritellään tarkemmin, mitä halutaan tehdä.