Legare dati e oggetti UI

Quinta lezione del corso sun sulla creazione di applicazioni GUI con JavaFX, dedicata al data binding, ovvero il meccanismo secondo cui il cambiamento di una variabile determina l'aggiornamento di un'altra variabile in accordo con la relazione che si é definita tra le due.

E' una necessità comune dello sviluppo software, aggiornare un certo parametro ogni qual volta un altro parametro cambia. Nella programmazione con JavaFX, si può ottenere questo effetto col meccanismo del data binding. Si definisce una relazione tra due variabili qualunque in modo che ogni volta che una cambia, l'altra venga aggiornata. Ci pensa JavaFX a tener traccia di ogni cambiamento e di fare ogni aggiornamento necessario.

Per vedere come il data binding funziona creiamo una semplice applicazione il cui scopo é visualizza una sorta di emulazione di una eclisse: un cerchio il cui bordo é evidenziato in giallo ha il suo contenuto sfumato e colorato in rosso. Muovendo una barra di controllo, vogliamo che il cerchio dia l'impressione che si muova solo il bordo mentre il suo contenuto resti fermo.

La finestra dell'applicazione

Creiamo il nostro script JavaFX, dichiarando lo stage e la scena in questo modo:

import javafx.stage.Stage;
import javafx.scene.Scene;

Stage {
title: "Data Binding"
scene: Scene {
width: 220, height: 170
} // scene
}

Il cerchio

Aggiungiamo un import per le classi Circle e Color, e mettiamo il nostro cerchio con bordo giallo sulla scena:

...
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;

Stage {
...
scene: Scene {
...
content: Circle {
centerX: 60, centerY: 60, radius: 50
stroke: Color.YELLOW
} // circle
} // scene
}

Dato che non abbiamo specificato i colori della scena e dell'interno del cerchio, ce li troviamo entrambi nel loro default, rispettivamente bianco e nero.

Colore riempitivo per il cerchio

Usiamo la classe RadialGradient per dare un piacevole effetto al colore interno al cerchio. Aggiungiamo perciò l'import per questa classe e per Stop, usata per definire il gradiente e definiamo il riempitivo del cerchio assegnando alla sua proprietà fill il gradiente radiale nei colori bianco e rosso:

...
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;


Stage {
...
scene: Scene {
...
content: Circle {
...
fill: RadialGradient {
centerX: 60, centerY : 60, radius: 50
focusX: 60, focusY: 30
proportional: false

stops: [
Stop {offset: 0 color: Color.RED},
Stop {offset: 1 color: Color.WHITE}
]
} // radialGradient
} // circle
} // scene
}

Barra di scorrimento

Aggiungiamo ora una barra di scorrimento sotto il cerchio, importiamo la classe Slider e aggiungiamola ai nostri oggetti sulla scena. Nota che, dato che ora gli oggetti sulla scena sono due, modifichiamo il content per fare riferimento ad un array, e non ad un singolo oggetto:

...
import javafx.scene.control.Slider;

...
Stage {
...
scene: Scene {
...
content: [
Circle {
...
} // circle

Slider {
min: 0, max: 60, value : 0
translateX: 10, translateY: 120
}
] // content
} // scene
}

Nota che la posizione dell'oggetto slider nella scena é determinata dalle sue variabili translateX e translateY.

La relazione di binding

Per poter definire la relazione di binding all'interno del cerchio, l'oggetto slider deve essere precendentemente definito (e referenziabile). Per far ciò spostiamo la sua definizione prima della creazione dello stage. Fatto questo, possiamo definire il centro del cerchio in funzione del valore dello slider:

...
def slider = Slider {
min: 0, max: 60, value : 0
translateX: 10, translateY: 120
}

Stage {
...
scene: Scene {
...
content: [
Circle {
centerX: bind slider.value + 60, centerY: 60, radius: 50
...
}, // circle
slider
] // content
} // scene
}

Nota che, avendo fatto ricorso a classi del common profile, l'applicazione può essere eseguita sia in ambiente desktop, che mobile.

Segue il codice completo dello script:

package uiTutorial;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.control.Slider;

def slider = Slider {
min: 0, max: 60, value : 0
translateX: 10, translateY: 120
}

Stage {
title: "Data Binding"
scene: Scene {
width: 220, height: 170
content: [
Circle {
centerX: bind slider.value + 60, centerY: 60, radius: 50
stroke: Color.YELLOW
fill: RadialGradient {
centerX: 60, centerY : 60, radius: 50
focusX: 60, focusY: 30
proportional: false

stops: [
Stop {offset: 0 color: Color.RED},
Stop {offset: 1 color: Color.WHITE}
]
} // radialGradient
} // circle

slider
] // content
} // scene
}

Nessun commento:

Posta un commento