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 -=.