You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

JavaFX er ment å være Java Swing sin etterfølger som det foretrukne rammeverk for grafikk og brukergrensesnitt. JavaFX er gjør det bl.a. enklere å kombinere grafikk og interaktive komponenter, har bedre støtte for rik grafikk og animasjon, gjør det lettere å skille funksjon og det rent visuelle.

Et GUI-rammeverk er en samling klasser som gjør det mulig å bygge rike, funksjonelle grafiske brukergrensenitt uten alt for mye arbeid. Brukergrensesnitt bygget med slike rammeverk har noenlunde samme struktur, og her skal vi gi en liten introduksjon med utgangspunkt i JavaFX-rammeverket. Vi har valgt JavaFX, fordi det er mer fleksibelt og moderne enn Java Swing, som det er ment å ta over etter og det ligner mer på andre "rammeverk" som HTML5 og Flash. Selv om JavaFX nå er en del av Java 7-installasjonen, så er det ikke trivielt å sette opp et Java-prosjekt for JavaFX-applikasjoner på egen hånd. Derfor anbefales det å installere e(fx)clipse-tillegget til Eclipse, som gjør det mye lettere.

Vi deler gjerne rammeverket opp i håndtering av

  • kjøring/oppstart av programmer
  • strukturer av grafiske og interaktiver elementer, altså det rent visuelle
  • interaktivitet, altså brukerinput og dynamikk
  • brukergrensesnittdefinisjonsfiler

Et "vanlig" program starter naturlig nok med det første. Så bygges det opp en visuell struktur, med en blanding av rent grafiske elementer og interaktive komponenter (ofte kalt widgets). De interaktive elementene knyttes deretter til programlogikken som skal reagere på og håndtere input fra brukeren. De fleste rammeverk gjør det mulig å beskrive det andre punktet i separate XML-filer (litt som HTML brukes for web-sider), slik at programmet blir mindre og ryddigere.

Vi skal ta disse i tur og orden.

Kjøring/oppstart av programmer

JavaFX har en egen programklasse kalt Application (i pakken javafx.application) som en må arve fra. Denne definerer en del metoder som kalles når programmet initialiseres (init), starter (start) opp og stopper (stop). Av disse er det bare start-metoden som må defineres i din egen hovedprogramklasse. Men merk at det ikke er din egen kode som oppretter instansen av hovedprogramklassen og kaller disse oppstartsmetodene, det er det rammeverket selv som gjør. Og for at det skal skje må du i main-metoden kalle den statiske metoden launch i Application-klassen med navnet til din egen klasse som første argument og programargumentene til din main-metode som launch-metoden sitt andre argument. En minimalt hovedprogramklasse er vist under til venstre, med applikasjonsvinduet som da dukker opp til høyre:

public class MinimalApplication extends Application {
	
	@Override
	public void start(Stage stage) throws Exception {
		
		Group root = new Group(); // Root of the scene graph
		
		Scene scene = new Scene(root,500,500, Color.AQUA);
		
		stage.setScene(scene);
		stage.setTitle("Simple JavaFX");
		stage.show();
	}

	public static void main(String[] args) {
		launch(MinimalApplication.class, args);
	}
}
 

 

 

 

er bygget opp med en stage i bunn som utgjør rammen til applikasjonen, og har typisk et navn som vises øverst applikasjonsvinduet. En stage fylles med en scene. Scenen utgjør området hvor vi framstiller knapper, figurer, tekst og andre komponenter. Dette skjer dog ikke helt vilkårlig, siden alle komponenter må legges til i en scene graph, og kalles da noder i denne grafen. Grafens struktur bestemmer hvordan nodene rendres på scenen.

Altså: Stage -> Scene -> Scene Graph

 

Stage and scene with empty scene graph
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class SimpleJavaFX extends Application {
	
	public static void main(String[] args) {
		launch(args);
	}
	@Override
	public void start(Stage stage) throws Exception {
		
		Group root = new Group(); // Root of the scene graph
		
		Scene scene = new Scene(root,500,500, Color.AQUA);
		
		stage.setScene(scene);
		stage.setTitle("Simple JavaFX");
		stage.show();
	}
}

 

Scene Graph

Det er scenegrafen som styrer selve utformingen av grensesnittet i en JaveFX-applikasjon. JavaFX Scene Graph API gjør det mye enklere å lage et GUI ved at en scenegraf på et hvilket som helst tidspunkt vet hvilke objekter som skal vises frem, hvilke områder på skjermen som må tegnes på nytt og hvordan alt skal rendres på en mest mulig effektiv måte. Ved å bruke scenegraf API'et slipper man å forholde seg til primitive tegnemetoder og kan heller la systemet ta seg av detaljer omkring rendring.

En scene graph er en trestruktur som inneholder dataelementer, og hvert element kalles en node. En node er enten en rotnode, intern-node eller løvnode, noe som vil si at alle noder i treet, for utenom rotnoden, må ha en parent (forelder). Under er et eksempel på en enkel scene graph, med elementer både som nodetype, og med faktiske klasser som kan tilsvare nodetypen.

Nodetype
- Bildet er hentet fra oracles nettsider 

Klasser som kan opptre som tilsvarende nodetype
- Bildet er hentet fra oracles nettsider 

Måten man bygger denne trestrukturen på er ved å bruke lister med children. Hver node som kan opptre som en intern node har en metode getChildren() som returnerer en liste med nærmeste etterkommere. I bildet over vil Groups children-liste inneholde ett circle-, ett rectangle- og ett region-objekt. Videre vil region-objektets liste inneholde ett text- og ett imageview-objekt.
Nye barn kan legges til på to måter:

  • parent.getChildren().add(node); Legger til én node
  • parent.getChildren.addAll(node1,node2,node3,....); Legger til flere noder

I pakken javafx.scene finnes det massevis av klasser, men de tre viktigste for å forstå oppbygningen til Scene Graph API er

  • Node: Abstrakt baseklasse for alle noder i en scene graph.
  • Parent: Abstrakt baseklasse for alle interne noder. (Arver direkte fra Node)
  • Scene: Base containeren for alt innholdet i en scene graph.

Disse klassene inneholder viktig funksjonalitet som arves videre og brukes i forbindelse med tegnerekkefølge, synlighet, transformasjoner, osv.
Parent arves av diverse internnode-klasser som Control, Group, Region og WebView. Det finnes også utallige løvnode-klasser, slik som javafx.scene.shape og javafx.scene.text.

Noder

Det finnes noen fellestrekk som gjelder for alle nodene man bruker i JavaFX. Alle noder, utenom rotnoden, legges til i grafen ved å addes i listen av barn til en parent-node. En node kan bare eksistere på et sted. Dersom man forsøker å legge til et objekt som child på flere forskjellige steder i grafen, vil objektet fjernes fra dens forrige parrents liste over children, før det addes som child hos sin nye parent. Det kan heller ikke finnes sykler i grafen. 

Id
Hver node kan også gis en id. Dette er en id som ligner veldig på id-tagen i HTML, og det er opp til utvikleren å sikre at en id er unik i en scene graph. En nyttig funksjon i denne forbindelse er lookup(String id) som kan brukes til å finne en node med en unik id i en scene graph. Ellers kan også id'en brukes til å identifisere noder når man vil legge til stiler, se mer om css lenger ned. 

Koordinater
Nodene følger et tradisjonell grafisk koordinatsystem med økende verdier mot høyre på x-aksen, og økende verdier nedover på y-aksen. Med dette er altså (0,0) lokalisert øverst til venstre. Man kan også definere koordinatene med flyttall og (0.5 , 0.5) tilsvarer da sentrum av pixelet øverst til venstre.

Transformasjoner

  • Translate flytter i x- og/eller y-retning ut fra nodens referansepunkt. Altså en enkel forflytning av objektet. TranslateTransition er en utvidelse av Translate og kan gjøre utføre forflytningen som en animasjon.
  • Rotation roterer noden et antall grader rundt et gitt referansepunkt. RotateTransition muliggjør rotasjonene som en animasjon.
  • Scale skalerer noden utfra nodens referansepunkt med en x- og y-faktor. Dersom referansepunktet er øverst til venstre i noden vil skaleringen utføres nedover og mor høyre. Klassen ScaleTransition finnes også.
  • Shearing roterer en akse slik at x- og y-aksen ikke lenger er vinkelrette for den gjeldende noden

Etter man har laget en transformasjon tiltenkt en eller flere noder kan man enkelt utføre den ved å legge den til i listen(e) av transformasjoner for noden(e): node.getTransforms().add(transform);

Cascading Style Sheets (CSS)

En node har feltene id, styleClass og style. Disse brukes til å endre nodens stil med CSS. Feltene id og styleClass brukes i CSS for å avgjøre hvilke noder som skal ha de forskjellige stilene. Feltet style brukes til å legge på en CSS stil til en node direkte i koden. For en basic forståelse av dette konseptet, ta en titt på denne videoen. Oracle har også en god tutorial for å få et lite innblikk i mulighetene CSS gir oss.

Layouts

JavaFX har støtte for mange forskjellige layouts og stiler gjennom en rekke container-klasser. Disse klassene er på en måte forhåndsdefinerte "beholdere", og en analogi kan være måten et klesskap er utformet. Klærne dine kan legges i store og små hyller (gjerne flere plagg i samme hylle), eller henges opp i kleshengere. Dersom det ikke er en hylle der du vil legge fra deg genseren, nei da går det ikke å legge genseren der. 
Her utgjør klærne dine noder, mens hyllene og oppheng utgjør layout. Det kan godt tenkes at klesskapet i utgangspunktet bare er delt i to, men at det er puttet flere hyller (layouts) i den ene av disse to containerne.

....

  • No labels