Programmieren > Sprachen > Java > Schulung 1

Lektion 1: Die Grundstruktur eines JavaFX-Programms

Projekt in NetBeans anlegen

Es erscheint ein Fenster mit einem Button, der die Aufschrift Click Me! trägt. Wird der Button geklickt, erscheint der Schriftzug Hello World unterhalb des Buttons und der Text You clicked me! wird auf der Konsole ausgegeben.

Code-Analyse

Es werden 3 Dateien generiert, um dieses Programm zu realisieren.

Die Hauptdatei

Die Hauptklasse einer JavaFX Anwendung erbt von Klasse Application. In der main Methode dieser Klasse wird die JavaFX Umgebung mit der Funktion launch gestartet. Um die Oberfläche aufzubauen, muss die Methode start überschrieben werden. Dieser Methode wird eine Stage (zu deutsch Bühne) mitgegeben, auf der die Applikation spielt. Die Stage ist das Hauptfenster, das mit der Applikation gefüllt wird. Die Oberfläche wird durch die FXML-Datei definiert. Deswegen wird diese mit einem FXMLLoader geladen und einer Scene übergeben (Es wird also eine Bühnenszene gebaut) Die Szene wird der Bühne übergeben und der Vorhang wird geöffnet (stage.show). Da die Definition der Oberfläche in der FXML Datei ist und der Java-Code zur Oberfläche im Controller ist, wird die Hauptklasse nur selten noch verändert.

package de.erichweigand.gewicht; 
 
import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 
 
/** 
 * 
 * @author erich 
 */ 
public class Gewicht extends Application { 
     
    @Override 
    public void start(Stage stage) throws Exception { 
        Parent root = FXMLLoader.load(getClass().getResource("GewichtsView.fxml")); 
         
        Scene scene = new Scene(root); 
         
        stage.setScene(scene); 
        stage.show(); 
    } 
 
    /** 
     * @param args the command line arguments 
     */ 
    public static void main(String[] args) { 
        launch(args); 
    } 
     
}

Der Controller

Der Controller enthält den Java-Code, der der Oberfläche Leben einhaucht. Mit der Annotation @FXML wird eine Verbindung zur FXML-Datei hergestellt. So wird mit dieser Annotation einmal die Verbindung zu einem Label hergestellt (der Wert von fx:id in der FXML-Datei ergibt den Namen der Java-Variablen) und zum zweiten die Funktion, mit der auf ein Button-Klick reagiert werden soll (der Wert von onAction in der FXML-Datei gibt den Methodennamen an).

package de.erichweigand.gewicht; 
 
import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.Label; 
 
/** 
 * 
 * @author erich 
 */ 
public class GewichtsViewController implements Initializable { 
     
    @FXML 
    private Label label; 
     
    @FXML 
    private void handleButtonAction(ActionEvent event) { 
        System.out.println("You clicked me!"); 
        label.setText("Hello World!"); 
    } 
     
    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
        // TODO 
    }     
     
}

Programmstruktur erweitern

Wenn man größere Programme schreibt, sollte man darauf achten eine übersichtliche Struktur durchzuhalten. Wie die richtige Struktur aussieht ist teils Tradition teils Geschmack des Programmierers. Ich benutze hier diese Struktur:

Im Main-Package ist nur die Hauptdatei. Die anderen Programmteile sind in Unterpackages, die je nach Komplexität des Programms weitere Unterpackages enthalten können.

Verschiebt man die Dateien in NetBeans übernimmt NetBeans das Umschreiben (Refactoring) der Java-Klassen auf die neue Package-Struktur. In 2 Fällen muss man hier allerdings von Hand eingreifen, um wieder ein lauffähiges Programm zu erhalten

Parent root = FXMLLoader.load(getClass().getResource("/de/erichweigand/gewicht/view/GewichtsView.fxml"));
fx:controller="de.erichweigand.gewicht.controller.GewichtsViewController"

Oberfläche erweitern

Wo wir gerade bei größeren Programmen sind. Jede Desktop-Applikation die was auf sich hält hat in etwa folgende Struktur.

Diese Struktur wird in JavaFX durch das Layout BorderPane erreicht. Auf dieses Layout stellen wir diese Applikation nun um, spendieren der Applikation auch noch gleich eine Menüleiste. Der Inhalt der Menüleiste beschränkt sich fürs erste auf File -> Exit. Die Funktionalität dafür wird im Controller umgesetzt. Doch zuerst die sich ergebende FXML Datei.

<?xml version="1.0" encoding="UTF-8"?> 
 
<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
 
 
<BorderPane prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.erichweigand.gewicht.controller.GewichtsViewController"> 
   <center>  
        <Button fx:id="button" onAction="#handleButtonAction" text="Click Me!" /> 
   </center> 
   <top> 
      <MenuBar BorderPane.alignment="CENTER"> 
        <menus> 
          <Menu mnemonicParsing="false" text="File"> 
            <items> 
              <MenuItem mnemonicParsing="false" onAction="#exitApplication" text="Exit" /> 
            </items> 
          </Menu> 
        </menus> 
      </MenuBar> 
   </top> 
   <bottom> 
        <Label fx:id="label" minHeight="20" minWidth="80" BorderPane.alignment="CENTER" /> 
   </bottom> 
</BorderPane>

Damit das Exit über die Menüleiste funktioniert benötigt der GewichtsViewController noch eine Funktion, die die Applikation beendet.

    @FXML 
    private void exitApplication(ActionEvent event) { 
        System.exit(0); 
    }

Abgesehen von der Menüleiste funktioniert die Applikation nach dem Neukompilieren noch genau so wie vorher. Die kompletten Source-Dateien, die sich nach Lektion 1 ergeben befinden sich im Anhang an diese Seite.

GewichtsLektion01.tar