Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

...

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:.

Code Block
languagejavacollapsetrue
public class MinimalApplication extends Application {
	
	@Override
	    
    @Override
    public void start(Stage stage) throws Exception {
		
		Group        
        Pane root = new GroupPane(); // Root of the scene graph
		
		        Scene scene = new Scene(root, 500, 500, Color.AQUA);
		
		    
        stage.setScene(scene);
		        stage.setTitle("Simple JavaFXMinimalApplication");
		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

 

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 { launch(args); } @Override publicvoidstart(Stagestage)throwsException{ Grouproot = 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(); } }

 

Code Block
languagejava
titleStage and scene with empty scene graph
collapsetrue
        stage.show();
    }
    public static void main(String[] args) {

 
 
 
 
 
 
 

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.

 launch(MinimalApplication.class, args);
    }
}
Image Added

start-metoden tar inn et argument av typen Stage (i javafx.stage-pakken), som tilsvarer applikasjonsvinduet. Denne må knyttes til innhold ved at en oppretter en instans av Scene (javafx.scene) med selve innholdet i. I denne minimale applikasjonen så nøyer vi oss med en instans av Pane (javafx.scene.layout), som gir oss t tomt panel. I tillegg til Pane-instansen så oppgir vi her også bredden og høyden Til slutt settes tittelen til applikasjonsvinduet og den vises frem. Merk at launch-metoden som ble kalt i main-metoden ikke returnerer (mens vinduet er oppe), så det er poengløst å legge annen koden etter launch-kallet.

Strukturer av grafiske og interaktive elementer

Innholdet i applikasjonen utgjøres av en såkalt scene graph, som er en hierarkisk struktur av såkalte noder. Node kan være beholdere (eng: container) for andre noder, rene grafiske elementer som streker, rektangler, ellipser polygoner osv. eller interaktive komponenter som knapper, tekstfelt, menyer, lister osv. Nodene har informasjon om plassering og beholderne kan i tillegg ha egen logikk for hvordan innholdet fordeles utover i bredden og høyden. Denne strukturen er illustrert i figurene under (hentet fra Oracle sine nettsider)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:

...

Det er få om ingen begrensninger på hva som kan være inni hva, og sammen så forteller denne strukturen akkurat hva som skal vises på skjermen for brukeren. Dersom en underveis i kjøringen endrer på noen av objektene, f.eks. endrer posisjoner, farger, fonter eller legger til og/eller fjerner elementer, så oppdateres skjermen tilsvarende. Man slipper altså å forholde seg til primitive tegnemetoder, men manipulerer istedet på objektstruktere og lar systemet ta seg av detaljer omkring hvordan disse tegnes (såkalt rendering).

Container-klasser og layout

Når en bygger opp dette objekt-hierarkiet så tenker en gjerne først på den overordnede layout-strukturen, dvs. utlegget av hovedelementer og velger container-typer som gir ønskede muligheter. Her er en liste av de vanligste container-typene (nærmere beskrevet i http://docs.oracle.com/javafx/2/layout/builtin_layouts.htm):

  • HBox og VBox - legger ut elementene horisontalt (x-dimensjonen, dvs. bortover) eller vertikalt (y-dimensjonen, dvs. nedover) og gjør dem like store i den andre dimensjonen.
  • GridPane og TilePane - plasserer elementene i et rutenett, TilePane gjør alle ruten like store, mens GridPane er mer fleksibel.
  • BorderPane - fordeler elementene i regioner, midten (for hovedinnholdet), top, bunn, venstre og høyre, og passer for hovedinnholdet i applikasjonen.
  • AnchorPane - henger elementene fast i punkter knyttet til en eller flere av sidene
  • Pane - generell container uten spesifikk layout, så posisjonen på elementer må settes manuelt.

Alle container-objektene har en liste med elementer i sin children-liste (hentes ut med getChildren()), som igjen kan være container-objekter, om en ønsker, f.eks. en GridPane inni en AnchorPane inni en BorderPane. Hele denne strukturen legges så inn i en Scene i en Stage.

Det er generelt to metoder for å legge til barn:

  • container.getChildren().add(node);

...

  • // legger til én node

...

  • container.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 grunnstrukturen til til hierarkiet er

  • Node: Abstrakt

...

  • superklasse for alle noder i

...

  • hierarkiet, med metodene som alle grafiske og interaktive elementer dermed har
  • Parent: Abstrakt

...

  • superklasse for alle container-klasser, altså noder inni hierarkiet, som inneholder andre noder.

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 legge dem inn i children-lista til en parent Parent-nodeinstans. En node kan bare eksistere på et sted. Dersom være ett sted i hierarkiet og dersom man forsøker å legge til et objekt som child på flere forskjellige steder i grafen, allerede er i hierarkiet til en annen/ny container, så 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. før den legges til den nye.

Til hver node kan det knyttes en id, altså et unikt navn (må sikres av utvikleren) tilsvarende id-tag'en i HTML. En nyttig funksjon er 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 graphdel av hierarkiet. Ellers kan også id'en brukes til å identifisere noder når man vil legge til stiler, se bruker css-stiler (mer om css lenger ned)

Koordinater
Nodene følger et tradisjonell grafisk Alle noder har en x,y-posisjon og størrelse (desimaltall) i et 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

...

Denne x,y-posisjonen angis imidlertid ikke direkte, men er kombinasjonen av ulike typer transformasjoner:

  • translateX og translateY - forskyver noden i x- og

...

  • y-retningen
  • rotate -

...

  • roterer noden et antall grader rundt et gitt referansepunkt.

...

  • scaleX og scaleY - skalerer størrelen med en x- og y-faktor

...

  • og settes med scale-metoden
  • layoutX og layoutY - gir en ekstra forskyving i x- og y-retning og brukes gjerne i forbindelse med midlertidige justeringer, f.eks. drag'n drop

Det går også an å lage egne transformasjonsobjekter, hvor disse effektene kan kombineres, og som kan knyttes til noder.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 grafiske 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.

Interaktivitet

 ....