Muutettu viimeksi 29.4.2010 / Sivu luotu 26.4.2010 / [oppikirjan esimerkit] / [Scala]
Sivun sisältöä:
Tässä luvussa luodaan pikakatsaus graafisen käyttöliittymän toteuttamisen vaivattomuuteen Scalalla - vaivatonta se on ainakin Javaan verrattuna. Monet Javassa kömpelöt ilmaukset on saatu luonnollistettua Scalan funktioparametrien ja operaattorimerkeiltä näyttävien metodikutsujen ansiosta. Eikä lopulta ole lainkaan yhdentekevää, voiko ohjelmoija ajatella selkein ja luontevin käsittein!
import scala.swing._ object FirstSwingApp extends SimpleGUIApplication { def top = new MainFrame { title = "First Swing App" contents = new Button { text = "Click me" } } }Kuten näkyy, MainFrame-luokassa on mukavia muuttujia, joille voi antaa arvoja! Sama tekniikka löytyy myös luokasta Button. Hyvä idea!
MainFrame myös sisältää pääohjelman, joka mm. kutsuu top-metodia. MainFrame on sellainen Frame, joka osaa päättyessään lopettaa koko graafisen sovelluksen.
import scala.swing._ object SecondSwingApp extends SimpleGUIApplication { def top = new MainFrame { title = "Second Swing App" val button = new Button { text = "Click me" } val label = new Label { text = "No button clicks registered" } contents = new BoxPanel(Orientation.Vertical) { contents += button contents += label border = Swing.EmptyBorder(30, 30, 10, 30) } } }Taas tätä Scala tyylikkyyttä: contents-muuttujaan lisätään nappula ja teksti lisäysoperaatiolla "+=".
Huom: Tuossa BoxPanelin luonnissa on uutuus: new-ilmauksen yhteydessä muutetaan luotavan olioin kenttien arvoja. Pienempi esimerkki: Hmm.scala.
Tapahtumia kuunnellaan (listenTo(source)) ja niihin reagoidaan (reactions += ...):
import scala.swing._ import scala.swing.event._ object ReactiveSwingApp extends SimpleGUIApplication { def top = new MainFrame { title = "Reactive Swing App" val button = new Button { text = "Click me" } val label = new Label { text = "No button clicks registered" } contents = new BoxPanel(Orientation.Vertical) { contents += button contents += label border = Swing.EmptyBorder(30, 30, 10, 30) } listenTo(button) var nClicks = 0 reactions += { case ButtonClicked(b) => nClicks += 1 label.text = "Number of button clicks: "+ nClicks b.text = nClicks +". time. Again?" // oma lisäys } } }Kuuntelu voidaan myös lopettaa (deafTo(source)). Tapahtumista saadaan case-class-oliota (ei käsitelty kurssilla!), joihin reagointi eli tapahtuman käsittely lisätään top-kehyksen reactions-ominaisuuteen. Tuo b tuolla ButtonClicked(b)ssä antaa käyttöön AbstractButton-tyyppisen komponentin, jolle tapahtui jotakin ja jota voidaan toki myös itse käyttää.
Yhdessä lisättävässä reaktiossa saa olla useampiakin case-osia. Sekä itse lisätyistä että perityistä case-osista suoritetaan kaikki sopivat järjestyksessä: viimeisimmäksi lisätty, toiseksi viimeisimmäksi lisätty, jne. Regoinnit siis viedään pinoon.
Reagointeja voi myös poistaa reactions-kokoelmasta. Ja sehän tietenkin tehdään operaatiolla -=.