JavaFX® con stile – Breve guida ai fogli stile 1/2

di - 21 settembre 2012 in Programmazione

Introduzione

I fogli stili per JavaFX® sono basati sulla specifica 2.1 del W3C estese però con alcune degli elementi definiti nella specifica tre, chiaramente questa specifica di base è stata ulteriormente estesa per includere le caratteristiche della piattaforma JavaFX®. Lo scopo dei fogli stile in JavaFX® è di consentire ai WER Designer/Developer in possesso di una certa familiarità con i fogli stile per l’HTML di personalizzare e sviluppare temi da applicare ai diversi componenti , utilizzando una notazione ed un tipo di logica non dissimile da quella a cui sono già avvezzi. L’aspetto interessante della specifica adottata è rappresentato dal fatto che i fogli stili sviluppati per un’applicazione possono essere elaborati da un qualsiasi parser CSS, sebbene quest’ultimo non sia obbligato a supportare le estensioni sviluppate appositamente per JavaFX®, questa caratteristica consente quindi in via teorica di definire fogli stili multi-target ossia in grado di essere utilizzati in ambienti differenti. A tal fine per distinguere i nomi delle proprietà specifiche per JavaFX® queste presentano un prefisso distintivo, –fx-, il che semplifica di molto la loro individuazione all’interno di un file CSS, va, infatti, precisato che l’estensione adottata per i fogli stile per JavaFX® è la stessa di quella adotta per le pagine HTML®.

Le specifiche JavaFX® non supportano proprietà di layout quali float, position, overflow e width, mentre per alcuni oggetti è possibile utilizzare proprietà che coinvolgono padding e margini, per tutti gli altri aspetti del layout questi possono essere gestiti a livello di programmazione dei singoli componenti, restano chiaramente esclusi da questa possibilità tutti quegli elementi delle specifiche HTML® per i quali non esiste un corrispettivo oggetto nella specifica JavaFX®, un esempio su tutti è rappresentato dalle tabelle che non hanno un corrispettivo nella piattaforma.

Detto questo nella prossima sezione descriveremo in che modo i fogli stile sono applicati agli elementi inseriti all’interno del contesto  di un’applicazione JavaFX.

Applicazione dei fogli stile

I fogli stile sono applicati ai nodi del grafo di una finestra  (in gergo tecnico scene) JavaFX®, in modo analogo a quanto avviene per gli elementi del DOM HTML, questo significa che si opererà prima sul genitore e successivamente sui figli, in particolare il codice è scritto in modo tale che questo processo è applicato solo su quei rami per i quali può rendersi necessaria una nuova applicazione del foglio a seguito di definizioni che incidono più volte sulla stessa gerarchia. I fogli stili sono applicati in modo asincrono, ciò significa che essi sono convertiti ed assegnati in modo non simultaneo alla creazione di un oggetto, inoltre se le specifiche dello stile dovessero mutare , questa modifica non si ripercuote immediatamente sull’oggetto, ma solo in un momento successivo che precede comunque  un refresh dell’intera scena. Proprio questo utilizzo consente in via teorica di applicare ad uno oggetto una serie di caratteristiche a livello di codice di programma, le quali possono essere successivamente sovrascritte per mezzo del foglio stile.

Ogni nodo del grafo possiede una variabile styleClass di tipo <String>List, il quale nelle specifiche HTML® coincide con la proprietà class, questo significa che fornendo una stringa per questa proprietà saranno applicate all’oggetto cui esso risulta associato tutte le caratteristiche definite all’interno del foglio stile, si noti inoltre come sullo stesso oqgetto possono essere applicati più stili visto il tipo di styleClass.

Ogni nodo del grafo di una scena possiede anche un suo specifico id di tipo stringa, il che ci consente di applicare stili personalizzati su singoli elementi in modo simile a quanto accade con l’HTML e l’attributo id da questo punto di vista le funzionalità che questo elemento riveste nei due ambiti è il medesimo.

Precisiamo sin da ora che ogni oggetto possiede un set di caratteristiche sue quindi non necessariamente due oggetti distinti possiedono lo stesso set di proprietà su cui poter agire nella definizione di un foglio stile, inoltre altro elemento di cui tenere conto è le precedenze con cui i vari stili sono applicati ai diversi elementi, in analogia con quanto avviene anche nel caso dell’HTML®.

I fogli stile possono essere sia inline che salvati all’interno di un file esterno, in questo secondo caso per caricarli è necessario utilizzare l’attributo stylesheet della classe Scene, in cu si specifica il path del file in cui sono definite le specifiche da adottare, nel caso delle specifiche inline si ricorre all’API setStyle che ogni oggetto possiede e con la quale è possibile fornire una serie di direttive in odo simile a quanto avvien con l’attributo style delle pagine HTML®.

Dalla specifica 2.1 è possibile specificare fogli stili distinti per ogni singolo ramo del grafo delgi oggetti che definiscono una scena questo significa che i nodi figli erediteranno le specifiche del nodo padre, le quali potranno essere però sovrascritte dal nodo figlio, con un meccanismo di precedenza simile a quello delle pagine HTML, per le quali la specifica più vicina al nodo sarà quella ad avere precedenza maggiore rispetto a quelli applicati al resto della gerarchia cui l’elemento appartiene.

Per quanto concerne la specifica dei path questi possono essere sia assoluti sia relativi, in questo secondo caso come url radice sarà utilizzata quella ricavata dal ClassLoader per l’applicazione concreta.

Come accennato in precedenza il parser CSS definito per JavaFX® è in grado di interpretare correttamente le specifiche di un foglio stile CSS classico non vale però il viceversa, esistono infatti una serie di limitazione che andiamo ad esaminare alcune delle principali:

  • Tutte le keyword che presentano il simbolo @ quale prefisso vengono ignorate;
  • I fogli stile di JavaFX® non supporta la notazione che consente di indicare più font separandoli tramite virgola;
  • Per la specifica dei colori si adotta lo standard HSB in luogo dello HSL;
  • E’ possibile utilizzare il nome della classe JavaFX® come selettore di tipo tuttavia, tale uso non è raccomandato;
  • Ecc

Nell’ambito di una specifica è interessante osservare come i diversi elementi che possono costituire una scena sfruttino ampiamente i meccanismi legati all’ereditarietà, il che implica che i vari nodi ereditano e/o ampliano le proprietà del nodo da cui discendono, ad esempio Rectangle eredita tutte le proprietà definte nell’ambito della classe Shape, la quale è la sua classe genitrice, ciò non ci deve meravigliare in quanto gli elementi con cui si può costruire una scena sono delle classi e quindi la loro specifica è conforme al paradigma OO.  Inoltre così come in Java tutte le classi ereditano un set di base di metodi e proprietà dalla classe Object allo stesso modo le classi definite in JavaFX posseggono un set di proprietà di base che riportiamo qui di seguito:

Classe Proprietà Proprietà CSS Valore Iniziale
Javafx.scene.Node Cursor -fx-cursor Javafx.scene.Cursor.DEFAULT
Javafx.scene.text.Text textAlignment -fx-text-alignment Javafx.scene.text.TextAlignment.LEFT
Javafx.scene.text.Font Font -fx-font Font.DEFAULT (12 pixel)

 

A questo punto prima di concludere questo nostro primo articolo circa la gestione delgi stili in JavaFX® presentiamo due semplici esempi in cui si utilizzano esplicitamente i concetti cui si è fatto cenno in questa introduzione.

Si consideri il seguente frammento di codice:

Scene palcoscenico = new Scene(new Group());
palcoscenico.getStylesheets().add(“test.css”); // si noti come il fogli stile sia esterno all’applicazione
Rectangle rettangolo = new Rectangle(100,100);  //rettangolo 100pxx100px
rettangolo.setLayoutX(50);  // ascissa
rettangolo.setLayoutY(50);  // ordinata
rect.getStyleClass().add(“mio-rettangolo”);  // mio-rettangolo è l’id del selettore  utilizzato all’interno del foglio stile
((Group)palcoscenico.getRoot()).getChildren().add(rettangolo); // si  aggiunge il nuovo elemento al main container

 

Se il path del file specificato non risultasse corretto oppure non esistesse, il risultato di questo codice sarebbe quello di generare un rettangolo nero, al contrario se il file css adottato fosse stato correttamente creato allora al suo interno troveremmo la seguente specifica:

.mio-rettangolo { -fx-fill:red }

Ancora una volta vogliamo sottolineare le similitudini della notazione adottata con quelli dei fogli stile per l’HTML®, a questo punto tornando al nostro esempio il risultato della sua esecuzione sarebbe il seguente:

 

Continuando il nostro processo di personalizzazione di seguito forniamo ora una specifica grazie alla quale il nostro rettangolo sarà riempito di colore giallo e circondato da un bordo tratteggiato di colore verde.

.mio-rettangolo {
    -fx-fill: yellow; riempimento
    -fx-stroke: green; colore linea bordo
    -fx-stroke-width: 5; spessore
    -fx-stroke-dash-array: 12 2 4 2; definizione delle caratteristiche della riga tratteggiata:

un tratto da 12px seguito da uno spazio di 2px seguito da una linea di 4px seguito da uno spazio di 2 px

    -fx-stroke-dash-offset: 6; impostazione dell’offset
    -fx-stroke-line-cap: butt; Impostazione di come disegnare la giunzione tra due linee
}

 

Il risultato della definizione di questo stile è il seguente:

Un ultimo elemento su cui vogliamo appuntare la nostra attenzione riguarda i messaggi che il parser può generare nel caso in cui la specifica CSS non sia sintatticamente valida, ad esempio consideriamo il seguente messaggio:

WARNING: com.sun.javafx.css.parser.CSSParser declaration Expected ‘<percent>’ while parsing ‘-fx-background-color’ at ?[1,49]

Semanticamente parlando la sezione meno comprensibile è quella relativa alla dicitura ?[1.49], questa non rappresenta altro che la posizione all’interno del file CSS espresso tramite il numero di riga e colonna dove è localizzato l’errore, in questo caso inoltre il “?” fa riferimento ad una specifica inline che si trova quindi all’interno della classe, mentre nel caso in cui la specifica errata si trovasse all’interno in un file esterno in luogo del “?” si vedrebbe stampato il path relativo al file.

Con questa ultima precisazione si conclude la nostra prima parte del percorso che ci guiderà a comprendere meglio la gestione degli stili all’interno di una applicazione JavaFX, a partire dal prossimo articolo incominceremo a descrivere più nel dettaglio tutte le proprietà che possono essere utilizzate/impostate per definire al meglio il look&feel delle nostre applicazioni. Stay tuned.

Alessandro Grande

 

Share

Promozioni

Potrebbe interessarti



Commenti