GRAFICA ED EVENTI
SWING, AWT e JavaFX
argomenti
• JavaFX: architettura e gerarchia
• Componenti principali: Stage, Scene, contenuti
• Gestione degli eventi
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
Java Package Grafici
I package grafici che comprende tutt’ora il JDK sono a grandi linee i seguenti:
• Package java.awt (Abstract Window Toolkit):
– il primo package grafico (Java 1.0)
– indipendente dalla piattaforma... o quasi!
• Package javax.swing:
– il secondo package grafico (Java 2; versione preliminare da Java 1.2)
– scritto esso stesso in Java, realmente indipendente dalla piattaforma
• Package javafx:
– L’ultimo package grafico (Java 7)
– Scritto interamente in Java, alcune applicazioni swing possono girare
sotto JavaFX
Scendiamo più in dettaglio nel package JavaFX.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
Java Package: JavaFX
• Il Package di Swing è potente, flessibile e IMMENSO.
• Il numero dei package disponibili è alto, molti programmi usano un piccolo
subset di package disponibili.
• Programmazione “event-driven”:
– non più algoritmi stile input/elaborazione/output...
– ... ma reazione agli eventi che l’utente, in modo interattivo, genera sui
componenti grafici
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: COMPONENTI PRINCIPALI
• La main class in una applicazione JavaFX eredita dalla classe
javafx.application.Application .
Il metodo start() è il punto d’ingresso delle applicazione JavaFX.
• In JavaFX, le applicazioni definiscono un container per l’intefaccia
utente mediane l’uso di un stage e una scene.
• JavaFX Stage è il contenitore principale
• JavaFX Scene è quello che mostra il contenuto dell’interfaccia
• In JavaFX, il contenuto della scena è rappresentato come una
gerarchia di nodi.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: esempio1
import
import
import
import
import
import
import
javafx.application.Application;
javafx.event.ActionEvent;
javafx.event.EventHandler;
javafx.scene.Scene;
javafx.scene.control.Button;
javafx.scene.layout.StackPane;
javafx.stage.Stage;
public class EmptyWindow extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
StackPane root = new StackPane();
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: esempio1
• Il risultato dell’esecuzione:
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: esempio2
• Nell’esempio precedente abbiamo creato una finestra
completamente vuota
• Vediamo un esempio di come si possono inserire componenti nella
nostra applicazione.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: esempio2
public class HelloWorld extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Layout
• Nell’esempio precedente usiamo uno StackPane. Il problema è che
questo layout posiziona tutto in centro e quindi non è il migliore da
usare.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: disegnare forme generiche
• Prima di tutto bisogna settare come radice un oggetto di tipo Group
• Va in seguito creato un Canvas, una tela, dove verranno disegnate le
figure
Group root = new Group();
Canvas canvas = new Canvas(300, 250);
• Dall’oggetto Canvas si recupera il graphic context dove fisicamente si
disegnerà
GraphicsContext gc =
canvas.getGraphicsContext2D();
• Si disegnano le figure e infine si aggiunge il canvas al nodo radice.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: soluzione
public void start(Stage primaryStage) {
// settaggio finestra
primaryStage.setTitle("Finestra con forme");
// creazione root e canvas
Group root = new Group();
Canvas canvas = new Canvas(300, 250);
// Recupero GraphicsContext
GraphicsContext gc =
canvas.getGraphicsContext2D();
// disegno le forme
drawShapes(gc);
// aggiungo il canvas a root
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: soluzione
private void drawShapes(GraphicsContext gc) {
gc.setFill(Color.GREEN);
gc.setStroke(Color.BLUE);
gc.setLineWidth(5);
gc.strokeLine(40, 10, 10, 40);
gc.fillOval(10, 60, 30, 30);
gc.strokeOval(60, 60, 30, 30);
gc.fillRoundRect(110, 60, 30, 30, 10, 10);
gc.strokeRoundRect(160, 60, 30, 30, 10, 10);
gc.fillArc(10, 110, 30, 30, 45, 240, ArcType.OPEN);
gc.fillArc(60, 110, 30, 30, 45, 240, ArcType.CHORD);
...
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: soluzione
...
gc.fillArc(110, 110, 30, 30, 45, 240, ArcType.ROUND);
gc.strokeArc(10, 160, 30, 30, 45, 240, ArcType.OPEN);
gc.strokeArc(60, 160, 30, 30, 45, 240, ArcType.CHORD);
gc.strokeArc(110, 160, 30, 30, 45, 240, ArcType.ROUND);
gc.fillPolygon(new double[]{10, 40, 10, 40},
new double[]{210, 210, 240, 240}, 4);
gc.strokePolygon(new double[]{60, 90, 60, 90},
new double[]{210, 210, 240, 240}, 4);
gc.strokePolyline(new double[]{110, 140, 110, 140},
new double[]{210, 210, 240, 240}, 4);
}
• NOTA: fill identifica figure piene, stroke il bordo
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: disegnare forme generiche
• Il risultato dell’esecuzione è il seguente:
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi
• Finora si sono utilizzate alcune delle funzionalità di JavaFX, ma
l’interazione con l’utente non è stata presa in considerazione.
• Ogni applicazione deve poter interagire con l’utente, e per fare questo
deve essere reattiva su alcuni componenti, che quindi devono essere in
grado di determinare il proprio stato e lanciare opportuni segnali quando
questo viene modificato dall’utente.
• Ogni componente grafico, quando si opera su di esso, genera un evento
che descrive cosa è accaduto.
• Tipicamente, ogni componente può generare molti tipi diversi di eventi,
in relazione a ciò che sta accadendo:
– un bottone può generare l’evento “azione” che significa che è stato
premuto;
– una casella di opzione può generare l’evento “modificato” per indicare
che la casella è stata selezionata / deselezionata.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi
• Un modo semplice per definire un metodo per gestire eventi differenti è
quello di definire una classe che implementa l’interfaccia
EventHandler.
• La classe creata dovrà implementare il metodo handle(Event e)
preposto alla gestione dell’evento stesso. In questo metodo verrà inserita
la logica che gestirà l’evento scatenato.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi - un esempio
Per provare a gestire qualche evento, proviamo a scrivere un
programma che implementi una semplice calcolatrice.
Architettura:
• un pannello con un campo di testo e sei pulsanti
• un unico EventHandler per tutti i pulsanti (è il vero
calcolatore)
Gestione degli eventi:
Ogni volta che si preme un pulsante:
• si recupera il nome del pulsante
• si legge il valore nel campo di testo
• si svolge l'operazione precedente
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
•
•
Per semplicità nella gestione degli definiamo i bottoni e il campo di testo come attributi
della classe. La classe che implementerà EventHandler sarà interna alla classe principale
del nostro programma.
Infine, nel metodo start() cominciamo a creare i bottoni e il campo di testo
public class MyCalculator extends Application {
TextField txt;
Button btnadd, btnsub, btndiv, btnmul, btnclear, btneq;
@Override
public void start(Stage primaryStage) {
txt = new TextField();
btnadd = new Button("+");
btnsub = new Button("-");
btnmul = new Button("x");
btndiv = new Button("/");
btneq = new Button("=");
btnclear = new Button("Clear");
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
•
Il posizionamento degli elementi verrà effettuato usando un GridPane. Settiamone le
caratteristiche e aggiungiamo i componenti.
GridPane root = new GridPane();
root.setAlignment(Pos.CENTER);
// gap fra i componenti di ogni riga/colonna
root.setHgap(10);
root.setVgap(10);
root.add(txt, 0, 0, 4, 1);
root.add(btnadd, 0, 1);
root.add(btnsub, 1, 1);
root.add(btnmul, 2, 1);
root.add(btndiv, 3, 1);
// definisco che il bottone srà contenuto in più colonne (4)
root.add(btneq, 0, 2, 4, 1);
root.add(btnclear, 0, 3, 4, 1);
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
•
Collego il gestore degli eventi ai bottoni e setto i parametri della finestra.
MyEventHandler eh = new MyEventHandler(0);
btnadd.setOnAction(eh);
btnsub.setOnAction(eh);
btnmul.setOnAction(eh);
btndiv.setOnAction(eh);
btneq.setOnAction(eh);
btnclear.setOnAction(eh);
Scene scene = new Scene(root, 340, 160);
primaryStage.setTitle("Mini Calcolatrice");
primaryStage.setScene(scene);
primaryStage.show();
}
// definisco il main
public static void main(String[] args) {
launch(args);
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
•
Infine definisco la classe gestore degli eventi
class MyEventHandler implements EventHandler {
private double result;
private String precOp;
// costruttore
public MyEventHandler(double result) {
this.result = result;
precOp = "nop";
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
@Override
public void handle(Event e) {
double num;
String operazione;
num = Double.parseDouble(txt.getText());
if (e.getSource() == btnclear) {
txt.setText("");
txt.requestFocus();
result = 0;
precOp = "nop";
} else {
...
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX: Eventi – esempio architettura
if (e.getSource() == btnadd)
operazione = "+";
} else if (e.getSource() ==
operazione = "-";
} else if (e.getSource() ==
operazione = "*";
} else if (e.getSource() ==
operazione = "/";
} else {
operazione = "nop";
}
{
btnsub) {
btnmul) {
btndiv) {
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX : Eventi – esempio architettura
if (precOp.equals("+")) {
result += num;
} else if (precOp.equals("-")) {
result -= num;
} else if (precOp.equals("*")) {
result *= num;
} else if (precOp.equals("/")) {
result /= num;
} else if (precOp.equals("nop")) {
result = num;
}
txt.setText("" + result);
precOp = operazione;
txt.requestFocus();
}
}
}
}
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE
JavaFX : Eventi - risultato
• Il risultato dovrebbe essere il seguente:
• Abbiamo utilizzato un unico gestore di evento per prelevare e
gestire tutti gli eventi dei pulsanti che abbiamo creato.
• Ci sono pattern di programmazione migliori di questo.
STRUMENTI JAVA PER LO SVILUPPO DI INTERFACCE UTENTE E SERVIZI DI RETE E LORO APPLICAZIONE