Grafikk-modellen til JavaFX er basert på en såkalt scene-graph, som er en trestruktur av node-objekter som beskriver hva som skal vises på skjermen. Når en endrer på trestrukturen eller egenskaper i nodene som påvirker hvordan de ser ut på skjermen, så sørger JavaFX automatisk for at de tegnes opp på nytt. Siden både rene grafiske elementer og interaktive elementer i JavaFX er noder, så står en fritt til å kombinere disse som en vil. Interaktive elementer er i grunnen ikke annet enn grafiske elementer som reagerer på og oppdateres iht. bruker-input. Ved kløktig rigging av node-strukturen og timing av endringene, så kan en få til et vell av av effekter.
Under ser du et eksempel på en tre-struktur som inneholder en sirkel, et rektangel, en tekst og et bilde (de to siste er gruppert). Akkurat hvordan det vil se ut på skjermen er avhengig av koordinatene og størrelsen til noden og grafiske effekter som fargen som brukes på streker og til å fylle figurer og strek-typen. En mulighet er vist under til høyre.
Det finnes noen fellestrekk som gjelder for alle elementene (ofte kalt noder) man bruker i JavaFX. Alle elementene, utenom den øverste (ofte kalt rotnoden), legges til i grafen ved å legge dem inn i children-lista til en elementet over. En node kan bare være ett sted i treet og dersom man forsøker å legge et element som allerede er i treet under en annen node, så vil elementet flyttes, ikke kopieres.
Koordinatsystem
Alle noder har en x,y-posisjon og størrelse (desimaltall) i et koordinatsystem med økende x-verdier mot høyre på skjermen og økende y-verdier nedover på skjermen. Med dette er altså (0,0) øverst til venstre. Denne x,y-posisjonen angis imidlertid ikke direkte, men er kombinasjonen av flere egenskaper:
- layoutX og layoutY - forskyver noden i x- og y-retningen. Det er disse som vanligvis brukes for å angi posisjonen, f.eks. den automatiske layouten som gjøres av paneler som AnchorPane.
- 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
- translateX og translateY - gir en ekstra forskyving i x- og y-retning og brukes gjerne i forbindelse med midlertidige justeringer, f.eks. drag'n drop. Denne kommer i tillegg til layoutX og layoutY.
Dette gir ganske stor fleksibilitet ved utforming av grafikk og effekter. F.eks. kan en lage en ruter-formet figur på flere måter, f.eks. som fire rette streker med passende koordinater, eller som et rektangel som er rotert 45 grader. Det går også an å knytte egne transformasjonsobjekter til noder, hvor disse egenskapene kombineres.
Koordinatene til en node er relativt til noden over i trestrukturen, slik at endring av posisjonen til en node automatisk påvirker nodene under. F.eks. kan en gruppere noder som utgjør en større figur i en samle-node og flytte alle på en gang ved å endre posisjonen til samle-noden.
Figurer
Det finnes mange standard-figurer som kan brukes for rent grafisk innhold. Disse er alle subklasser av Shape-klassen (javafx.scene.shape), som dermed får en del felles egenskaper:
- fill - fargen eller effekten (av typen Paint) som fyller figuren
- stroke - fargen eller effekten som brukes for å tegne (omrisset til) figuren
- strokeWidth (strek-tykkelse), strokeType (plassering), strokeDashOffset (stipling) og strokeLineJoin og strokeLineCap (håndtering av hjørner og ender)
Nyttige figurer er Line (strek), Rectangle (rektangel), Circle (sirkel), Ellipse (ellipse), Arc (buesegment), Polygon (mangekant), Path (segmentert figur) og Text (tekst). I tillegg er det en egen klasse for bilder (ImageView som viser et Image, som ikke er en Shape). Noen av disse er vist i eksemplet under, hvor center-regionen til en BorderPane er fylt med et Pane-objekt med figurer i. Figurene har fått ulike grafiske egenskaper, for å illustrere hva de gjør.
@Override public void start(Stage stage) throws Exception { BorderPane root = new BorderPane(); // Root of the scene graph // Add one Text node in each surrounding region root.setTop(new Text("top")); root.setBottom(new Text("bottom")); root.setLeft(new Text("left")); root.setRight(new Text("right")); Pane shapesPane = new Pane(); shapesPane.setPrefSize(300, 300); Line line = new Line(10, 10, 100, 100); // x1, y1, x2, y2 line.getStrokeDashArray().setAll(10.0d, 10.0d); // dashes Rectangle rect = new Rectangle(150, 10, 30, 40); // x, y, w, h rect.setFill(Color.BLUE); Ellipse ell = new Ellipse(40, 180, 40, 30); // cx, cy, rx, ry ell.setStroke(Color.RED); ell.setStrokeWidth(5); ell.setFill(Color.GREEN); Text text = new Text(180, 180, "center"); List<String> fonts = Font.getFamilies(); text.setFont(new Font(fonts.get((int) (Math.random() * fonts.size())), 32)); shapesPane.getChildren().addAll(line, rect, ell, text); root.setCenter(shapesPane); Scene scene = new Scene(root, 500, 500); stage.setScene(scene); stage.setTitle("BorderPaneApplication"); stage.show(); } |