JavaFX – Hello World con Scene Builder

di - 7 agosto 2012 in Programmazione

Nel precedente articolo si è fornita una prima introduzione a JavaFX, in particolare è stato presentato un primo esempio di codice, si è però fatto cenno alla possibilità di realizzare la GUI per questo programma  utilizzando un apposito tool grafico, nello specifico SceneBuilder®. Diciamo innanzitutto che si tratta di un tool esterno a NetBeans® il che implica la possibilità di utilizzarlo anche in abbinamento con altri strumenti primo fra tutti Eclipse®, per i nostri articoli comunque continueremo a fare riferimento all’accoppiata Netbeans® – SceneBuilder®. Un’altra precisazione si rende necessaria prima di procedere oltre SceneBulder® nasce al momento con l’unico scopo di costruire l’interfaccia utente, pertanto la definizione di tutta la logica di business è demandata ad un applicativo esterno, è però possibile effettuare l’associazione componenti eventi direttamente all’interno dell’interfaccia grafica dell’applicativo. Chiarito questo punto cerchiamo di descrivere nel modo più esaustivo possibile come creare il nostro programma “HelloWorld” utilizzando SceneBuilder, per farlo ci serviremo di una serie di screenshot ed una serie di frammenti di codice.

Come primo passo creiamo un nuovo progetto, denominato ad esempio “Hello_Scene_Builder”.

La prima differenza che possiamo notare è che in questo caso si crea un’applicazione FXML, cliccando sul pulsante next saranno richieste le usali informazioni circa il nome del progetto, il nome del package principale e via discorrendo, il tutto è sintetizzato nella prossima immagine.

L’elemento evidenziato rappresenta il file XML in cui sarà inserita la descrizione dell’interfaccia grafica che SceneBuilder popolerà automaticamente ogni qualvolta si inserirà un nuovo elemento all’interno dell’area di lavoro. A questo punto al termine del processo di definizione del nuovo progetto ci ritroveremo con una struttura di progetto simile a quella mostrata in figura:

 

Notiamo immediatamente come il wizard abbia popolata il nostro progetto con tre file i quali hanno nell’ordine i seguenti scopi:

  • Hello_Scene_Builder.java: è il punto di avvio per l’intera applicazione, infatti contiene al suo interno il metodo main;
  • Hello_World.fxml: è il file xml in cui sono descritti i diversi elementi che costituiscono l’interfaccia utente
  • Hello_WorldController.java: è la classe deputata alla gestione degli eventi.

Osservando la suddivisione dei compiti è evidente un utilizzo del famigerato pattern MVC ( Model-View-Controller) infatti:

  • Hello_World.fx: svolge il ruolo del pattern view;
  • Hello_WorldController: ricopre i ruoli tipici del pattern Controller

Appare chiara come non ci sia un elemento che possa essere accomunato alla pattern model, in quanto data la semplicità dell’applicazione non esiste alcuna classe deputata alla gestione dei dati o alla logica di business.

Detto, questo cerchiamo ora di esaminare più da vicino i diversi elementi che costituiscono il programma, partiamo quindi con l’analizzare il codice associato alla classe Hello_Scene_Builder.

package big.alex;

 

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Parent;

import javafx.scene.Scene;

import javafx.stage.Stage;

 

/**

*

* @author Alessandro

*/

public class Hello_Scene_Builder extends Application {

@Override

public void start(Stage stage) throws Exception {

Parent root = FXMLLoader.load(getClass().getResource(“Hello_World.fxml”));

Scene scene = new Scene(root);

stage.setScene(scene);

stage.show();

}

public static void main(String[] args) {

launch(args);

}

}

 

Osservando il codice notiamo immediatamente come l’avvio dell’applicazione segua i dettami titpici dei thread, infatti nel metodo start si implementa la logica operativa del  task, mentre il metodo launch si farà carico di avviare il task. Notiamo come nel metodo start vi sia un esplicito riferimento al file fxml, come abbiamo infatti precisato al suo interno sono definiti  tutti gli elementi di cui consta l’interfaccia utente, ricordiamo che questo file descrive gli elementi da un punto di vista grafico la logica per la gestione degli eventi deve essere implementata in una classe separata.

Altra operazione presente nel metodo start riguarda la creazione di un’istanza della classe Scene, questa può essere pensata come un’entità simile alla classe JPanel intesa nel caso specifico come un mero contenitore. Lo stage cui si fa riferimento nel codice è il contenitore di livello 0 in cui saranno inserite le diverse istanze della classe scene, se volessimo proseguire con il nostro parallelo con le swing potremmo paragonare la classe stage alla classe JFrame. Analogamente a quanto avviene con le Swing anche per le JavaF si rende necessaria l’invocazione di un metodo per la visualizzazione, nel caso specifico il metodo in questione è denominato show().

Passiamo ora ad esaminare più nel dettaglio il file Hello_world.fxml.

<?xml version=”1.0″ encoding=”UTF-8″?>

 

<?import java.lang.*?>

<?import java.util.*?>

<?import javafx.scene.*?>

<?import javafx.scene.control.*?>

<?import javafx.scene.layout.*?>

 

<AnchorPane id=”AnchorPane” prefHeight=”200.0″ prefWidth=”320.0″ xmlns:fx=”//javafx.com/fxml” fx:controller=”big.alex.Hello_WorldController”>

<children>

<Button fx:id=”button” layoutX=”126.0″ layoutY=”90.0″ onAction=”#handleButtonAction” onMouseEntered=”#handleButtonOnMouseEntered” text=”Click Me!” />

<Label fx:id=”label” layoutX=”126.0″ layoutY=”120.0″ minHeight=”16.0″ minWidth=”69.0″ />

</children>

</AnchorPane>

Esaminando il codice del file Hello_World, notiamo innanzitutto che si tratta di un file xml, osserviamo inoltre che oltre agli usuali tag e direttive per l’indicazione dei namespace sono presenti una serie di direttive di inclusione, queste in particolare si rendono necessarie durante la fase di inizializzazione della scena. All’interno dei tag notiamo anche l’utilizzo di una serie di identificatori (evidenziati in verde), i quali saranno utilizzati in seguito all’interno della classe controller. Fondamentale affinché i vari componenti dell’interfaccia possano rispondere alle azioni compiute dall’utente è la direttiva evidenziata in azzurro (fx:controller=”big.alex.Hello_WorldController”)  con essa si viene a creare il legame tra interfaccia utente e logica di controllo, il cui utilizzo è reso esplicito attraverso l’invocazione di una serie di metodi, evidenziati in giallo. Fortunatamente per lo sviluppatore tutta la parte relativa all’associazione componente-evento può avvenire attraverso una comoda interfaccia grafica di cui mostriamo di seguito un immagine.

Chiaramente affinchè si possa effettuare questa associazione è indispensabile che si sia definita una classe controller che andiamo ora ad esaminare nel dettaglio

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package big.alex;

 

import java.net.URL;

import java.util.ResourceBundle;

import javafx.event.ActionEvent;

import javafx.fxml.FXML;

import javafx.fxml.Initializable;

import javafx.scene.control.Label;

import javafx.scene.input.MouseEvent;

 

/**

*

* @author Alessandro

*/

public class Hello_WorldController implements Initializable {

@FXML

private Label label;

private String textLabel=””;

@FXML

private void handleButtonAction(ActionEvent event) {

System.out.println(“You clicked me!”);

label.setText(“Hello World!”);

}

@FXML

private void handleButtonOnMouseEntered(MouseEvent evt) {

label.setText(textLabel=textLabel.equals(“”)?”You’re on the Button!”:”Again on the Button!”);

}

@Override

public void initialize(URL url, ResourceBundle rb) {

// TODO

}

}

 

Osserviamo innanzitutto che la classe controller implementa un Adapter pertanto è possibile definire la logica per i soli eventi utili ai fini della nostra applicazione. Osserviamo come la logica di definizione del gestore segua i dettami classi di Java®, notiamo inoltre l’utilizzo dell’annotazione @FXML il quale è utilizzato per marcare campi e metodi che saranno poi riferiti all’interno del file fxml. Si noti a questo proposito come il nome degli oggetti debba coincidere con quello degli id specificati all’interno del file xml, a tal proposito se modificassimo il nome dell’oggetto Label in label2 all’interno del codice, nel momento in cui si eseguisse il codice si riceverebbe in output un messaggio di errore nel momento in cui si invocasse la gestione di uno degli eventi, questo perché l’elemento label2 non è stato definito all’interno del file xml. Per quel che concerne infine il metodo initialize, come suggerisce il nome stesso, è utilizzato per effettuale tutte quelle operazioni legate all’inizializzazione del gestore degli eventi.

Con quest’ultima precisazione si completa questo nostro appuntamento con le JavaFX®, nei prossimi articoli descriveremo in che modo utilizzare i fogli stile nonché gli altri componenti grafici con cui costruire le nostre interfacce.

 

 

Share

Promozioni

Potrebbe interessarti



Commenti