Ensimmäinen JavaFX-ohjelma

JavaFX-ohjelma koostuu kahdesta keskeisestä säiliöstä (engl. container): stagesta eli näyttämöstä (engl. stage) ja skenestä eli maisemasta (engl. scene).

  • Stage on ylimmän tason säiliö eli se esittää koko ikkunaa.

  • Scene on säiliö, joka sisältää kaiken ikkunassa esitettävän sisällön.

Skenen sisältö koostuu ruudun sisällöstä. Ruudulle piirrettävät elementit (engl. node) lisätään juurielementtiin, esim. StackPane tai FlowPane, joka määrittää niiden sijainnin ruudulla. JavaFX-ohjelma, jossa tapahtuma, on yksinkertaisimmillaan siis:

package example;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;


public class App extends Application {

    @Override
    public void start(Stage stage) {

        // Luodaan käyttöliittymään nappula
        Button printButton = new Button();
        // ja sille teksti "Print"
        printButton.setText("Print");

        // Luodaan lisäksi tekstikenttä
        TextField output = new TextField();
        // ja sille toivottu leveys pikseleinä
        output.setPrefWidth(250);

        // Luodaan näyttöelementeille ruutu (engl. pane)
        // FlowPane asettaa elementtinsä vaakaan tai pystyyn,
        // oletuksena vaakaan
        var group = new FlowPane();
        // Lisätään elementit ruutuunsa
        group.getChildren().add(printButton);
        group.getChildren().add(output);
        // voi lisätä myös useamman kerralla group.getChildren().addAll(printButton, output);

        // Luodaan skene ja lisätään luotu ruutu siihen.
        Scene scene = new Scene(group, 300, 150);
        // lisätään skene stagelle
        stage.setScene( scene );
        stage.setTitle("All the world's a stage");
        // ja näytetään se
        stage.show();
    }

    public static void main(String[] args) {
        launch( args );
    }

}

Tässä kohtaa ohjelmamme näyttää tältä:

JavaFX-ikkuna, jossa nappula ja tekstikenttä

Yksinkertainen JavaFX-ohjelma, jossa nappula ja tekstikenttä.

Ohjelmamme ei kuitenkaan vielä tee mitään eli meidän pitää lisätä tapahtumakäsittelijä nappulallemme. Tapahtuma käsitellään rajapinnan EventHandler toteuttamalla oliolla. Nappulan painalluksen tyyppi on ActionEvent. Lisätään koodiin ennen scenen luomista tapahtumakäsittelijä nappulalle printButton:

// tapahtumakäsittelijä määritellään aina käyttöliittymäelementille
// se kertoo, mitä toiminnallisuutta tapahtuman tapahtuessa tarvitaan
// tässä napin painallus kirjoittaa tekstikenttään tekstiä näkyviin
printButton.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        // Huom! olioiden, joita käytetään käsittelijässä,
        // tulee olla määriteltyjä ennen käsittelijän toteutusta
        output.setText("And all the men and women merely players;");
    }

});

Kun käyttöliittymäelementti, johon tapahtumakäsittelijä on liitetty, suorittaa jonkin toiminnon, elementtiin liitetty tapahtumakäsittelijä suoritetaan. Nyt ohjelmamme näyttää nappulan painalluksen jälkeen:

JavaFX-ikkuna, jossa nappula, jota painettu, ja tekstikenttä, jossa näytetään sisältöä

Tapahtuman suorituksen tulos näkyy tekstikentän sisältönä

Tapahtumakäsittelijä voidaan halutessa määritellä lambda-funktiolla:

printButton.setOnAction((event) -> {
    output.setText("And all the men and women merely players;");
});

Kuten aiemmin todettiin tapahtumakäsittelijän tyyppi riippuu käyttöliittymäelementistä, johon se liitetään. Näppäimen painallusta käsittelee KeyEvent, jolloin tekstikentän enterin painalluksella tyhjentävä tapahtuma saataisiin lisäämällä nappulalle käsittelijä:

printButton.setOnKeyPressed( new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent k) {
        if (k.getCode().equals(KeyCode.ENTER)) {
            output.clear();
        }
    }
});

Lisäksi, jos halutaan tarkkailla muutoksia jonkin elementin jossain ominaisuudessa, siihen voidaan liittää changeListener tapahtumakäsittelijäksi. Esimerkiksi liukuvalitsimen arvon muutoksia kuunneltaisiin slider.valueProperty.addListener( new ChangeListener<Number>)-käsittelijässä, jossa toteutettaisiin @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue)

Ohjelmointidemo (kesto 16:01)

JavaFX:ssa tapahtumakäsittelijä