Versions Compared

Key

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

...

JavaFX og det tilhørende filformatet FXML og verktøyet SceneBuilder, gjør det relativt enkelt å lage fasaden til app-er. Med Eclipse-tillegget e(fx)clipse så kan du faktisk lage fasaden uten programmering, og så trinnvis gjøre app-en funksjonell ved å koble elementene i fasaden, så som knapper og tekstfelt, til selve (koden for) app-logikken. Her viser vi hvordan dette gjøres for en enkel app basert på Counter-logikken i Tilstand og oppførsel.

Counter-

...

Counter-klassen implementerer en enkel teller, som får fra 1 til en angitt øvre grense. Koden og en enkel forklaring er gitt under:

Counter-klassenForklaring
Code Block
languagejava
public class Counter {
	int end;
	int counter = 0;


	Counter(int end) {
		this.end = end;
	}

	int getCounter() {
		return counter;
	}

	void count() {
		if (counter < end) {
			counter = counter + 1;
		}
	}
 }

Counter-klassen deklarerer felt for den øvre grensa og telleren.

Den øvre grensa initialiseres av konstruktøren.

Telleren kan lese (utenifra) med getCounter()-metoden.

count()-metoden brukes til å telle opp ett trinn, men dette skjer bare hvis den øvre grensa ikke alllerede er nådd.

Figuren under viser hva som skjer når en teller fra 0 og oppover og den øvre grensa er 3.

PlantUML Macro
object "~#1: Counter" as counter0 {
	end = 3
	counter = 0
}
object "~#1: Counter" as counter1 {
	end = 3
	counter = 1
}
counter0 -> counter1: count()
 
object "~#1: Counter" as counter2 {
	end = 3
	counter = 2
}
counter1 -> counter2: count()

object "~#1: Counter" as counter3 {
	end = 3
	counter = 3
}
counter2 -> counter3: count()
counter3 -> counter3: count()

Vi ser at det samme objektet (samme #id) endrer tilstand ved at telleren øker, inntil telleren er lik den øvre grensa.

Counter-appen

Tanken er nå å lage en app som lar oss opprette og initialisere, lese og endre tilstanden til et Counter-objekt. Vi skal starte med en enkel variant, som lar oss lese og endre tilstanden til et forhåndsopprettet Counter-objekt, og så utvider vi den til å støtte å lage nye Counter-objekter.

...

FXML-kodeForklaringKontroller-kode
Code Block
languagejavafx
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.text.Text?>

<HBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="counter.CounterController">
	<Text fx:id="counterOutput" text="Current counter value: 0"/>
	<Button text="Count" onAction="#handleCountAction"/>
</HBox>

FXML-koden inneholder et fx:controller-attributt, som angir (det fulle) navnet til kontroller-klassen. Når FXML-koden kjøres (lastes inn og vises), så vil det automatisk lages et objekt av denne klassen. Her vil det altså være et CounterController-objekt.

CounterController-objektet gis sjansen til å utføre initialiseringskode, ved at en metode med signaturen void initialize() og annotert med @FXML (egentlig javafx.fxml.FXML) automatisk kalles (hvis den finnes). Annotasjonen står foran metoden og en import-setningen gjør at vi slipper å bruke det fulle navnet. Her opprettes det et Counter-objekt med 5 som øvre grense for telleren, og en får koblingen som vist under.

PlantUML Macro
object "counter:Counter" as counter
object "kontroller:CounterController" as controller
controller -> counter: counter
 

CounterController-objektet skal bl.a. oppdatere Text-objektet som viser counter-verdien. For å kunne gjøre det, så må CounterController-objektet ha en referanse til Text-objektet, altså et felt av typen Text (egentlig javafx.scene.text.Text), slik at en får koblingene vist under.

PlantUML Macro
object "counter:Counter" as counter
object "kontroller:CounterController" as controller
controller -> counter: counter
object "text:Text" as text
controller -> text: counterOutput
 

Selv koblingen opprettes automatisk av JavaFX vha. to elementer i koden:

  1. counterOutput-feltet i CounterController, med Text som type og annotert med @FXML
  2. fx:id-attributtet på Text-elementet i FXML-koden, med navnet på feltet som verdi

Merk at navnet på feltet kan være hva som helst, bare det stemmer med fx:id-attributtet og felt-typen er riktig. Dersom noe ikke stemmer, så vil det bli markert som en feil i FXML-koden av editoren.

Det siste som trengs er kode som håndterer Count-knappen og koblingen mellom knappen og koden. Dette håndteres med to elementer i koden:

  1. handleCountAction-metoden annotert med @FXML
  2. onAction-attributtet med #handleCountAction som verdi

handleCountAction-metoden sørger for å øke telleren, med counter.count(), og oppdatere teksten som vises av Text-objektet, med counterOutput.setText(...).

onAction er attributtet som brukes av Button-klassen når knappen trykkes og hver type interaktive JavaFX-objekt har sine on-attributter for de ulike typene interaksjon den støtter. Hvis kontroller-objektet skal reagere på annen type input, så brukes tilsvarende on-attributt.

Som over så spiller ikke navnet (på metoden) noen rolle, bare det stemmer med verdien til attributtet.

Code Block
import javafx.fxml.FXML;
 
public class CounterController {

	Counter counter;

	@FXML
	Text counterOutput;

	@FXML
	void initialize() {
		counter = new Counter(5);
	}

	@FXML
	void handleCountAction() {
		counter.count();
		counterOutput.setText("Current counter value: " + counter.getCounter());
	}
}

...

Counter-app - komplett variant

...