Maven & JavaFX für Werner

Gierige Programmierer

So sind Programmierer nun mal. Reicht man ihnen den kleinen Finger, wollen sie mehr, immer mehr ;-). Man kann das bisherige Tutorial natürlich auch für eine Browser-App modifizieren. Aber dabei gibt es einige Dinge zu beachten. Im Browser kann man Java nur über sogenannte Applets ablaufen lassen. Das hat allerhand Nachteile. Zum Ersten: Auf dem jeweiligen Client muss Java installiert sein. Zeitens: für den Browser muss das passende PlugIn installiert sein. Drittens: Rechte müssen korrekt gesetzt sein. Viertens: Es wäre total oldschool.
Nativ kann man im Browser nur JavaScript ablaufen lassen. Dann hat man aber keine Java-Entwicklung mehr. Oder man verwendet einen Java-Nach-JavaScript Compiler. Ich kenne zwei. Der eine ist GWT (Google-Webkit-Toolkit) und der andere J2CL. J2CL ist der neuere. Den kenne ich aber noch nicht so gut, während GWT mein täglich Brot ist. Daher fangen wir mit GWT an.
Damit deine Anwendung im Browser laufen kann, brauchst du auch einen Server, von dem der Browser die Daten holen kann. Im Java-Umfeld ist dies klassischer Weise der Tomcat von Apache. Wir bräuchten also noch diesen Tomcat, in dem wir dann unsere neue Applikation werfen. Das ist aber auch nicht so schön, weil wir dann nicht einfach ein ausführbares Java-Programm haben. Aber natürlich gibt es auch hier eine Abhilfe.
Das Zauberwort hier heißt SpringBoot. Damit kann man eine Java-Applikation bauen, die selber einen Tomcat enthält und unsere GWT-Anwendung einem Browser zur Verfügung stellt. Wie immer gibt es hier auch einen Haken. Es gibt keinen einfachen Archetype in Maven für solch ein Projekt. Das ist mir schon immer ein Dorn im Auge gewesen, desshalb habe ich selber mal solch einen Archetype geschrieben. Damit du diesen Archetype nutzen kannst, musst du ihn bei dir installieren. Das geht so: Archetype-Projekt herunterladen, Auspacken, Builden, Installieren.
cd Downloads/
wget https://javafx.valaquenta.de/springboot-gwt-archetype.valaquenta.tar.gz

cd ../Entwicklung/
tar xzvf ../Downloads/springboot-gwt-archetype.valaquenta.tar.gz

. ../etc/myenv.sh 11

cd springboot-gwt-archetype.valaquenta/
mvn package
mvn install
cd ../..
Damit hast du meinen passenden Archetype und Maven kann ein nettes Projekt erstellen. Wie der Archetype zu verwenden ist, siehst du in der "README"-Datei. In Analogie zu den JavaFX-Projekten, erstellen wir uns nun also ein SpringBoot-GWT-Projekt, um auch im Browser ein bishen malen zu können:
cd Entwicklung/
mvn archetype:generate \
    -DarchetypeGroupId=de.valaquenta.archetypes \
    -DarchetypeArtifactId=springboot-gwt-archetype \
    -DarchetypeVersion=2022.12 \
    -DgroupId=de.wh \
    -DartifactId=gwt-shell \
    -Dpackage=de.wh.gwtshell \
    -Dversion=2022.12 \
    -DmoduleName=GwtShell
cd ..
Um zu schauen, ob auch alles geklappt hat, übersetzen wir das Projekt und starten es auch gleich:
cd Entwicklung/gwt-shell/
mvn package
java -jar target/gwt-shell-2022.12.jar
cd ../..
Damit ist der Tomcat gestartet und meine Beispiel App steht zur Verfügung. Sollte es beim Starten ein Fehler geben, liegt es sehr Wahrscheinlich daran, dass der Port für den Tomcat bereits verwendet wird. Dann muss man einfach einen anderen mitgeben: "java -jar target/gwt-shell-2022.12.jar --server.port=7000". Das die App funktioniert kannst du im Browser prüfen. Einfach im Browser "http://localhost:8080" aufrufen (oder ...localhost:7000). Es sollte eine Meldungsbox mit "Welcome to GwtShell" erscheinen. Nach einem Klick auf OK, wirst du die Erleuchtung erhalten. Beendet wird der Server einfach durch Strg-C.
Nun wollen wir ein bischen malen. Aber zuvor noch ein paar kleine Infos. Web-Anwendungen sind - im Gegensatz zu normalen Java-Programmen - immer 3 teilig. Es gibt den Teil der im Client abläuft (Browser), es gibt den Teil der im Server (Tomcat) abläuft und es gibt Teile, die auf beiden Seiten laufen sollen. Das spiegelt sich auch im Projekt wieder das Package "de.wh.gwtshell.client" nimmt alle Klassen für den Browser auf, "de.wh.gwtshell.server" die Klassen für den Tomcat. Das dritte Package fehlt hier, da es noch nicht gebraucht wurde. Aber es würde "de.wh.gwtshell.shared" heißen.
Schauen wir uns den Code an. Der Einstiegspunkt für die Browser-Funktion ist in "GwtShell.java" aus dem Package "de.wh.gwtshell.client" zu finden. Die Methode "onModuleLoad" ist das Zauberwort. Sobald der Browser die App geladen hat, spring er hier hin und führt die Anweisungen aus. In meiner Beispiel-App wird erst mal eine Alert-Box ausgegeben. Dann wird eine Anfrage an den Server gestellt, und wenn die Antwort kommt, wird auch diese in einer Alert-Box ausgegeben.
Nun lass uns wirklich malen. Den Code in "onModuleLoad" werfen wir einfach weg. Wir legen uns auch hier einen Canvas an, fügen ihn zur unser Oberfläche hinzu und malen ein bischen:
package de.wh.gwtshell.client;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;

/**
 *
 * @author ruediger
 */
public class GwtShell implements EntryPoint {

    @Override
    public void onModuleLoad() {
        Canvas canvas = Canvas.createIfSupported();

        canvas.setCoordinateSpaceWidth(900);
        canvas.setCoordinateSpaceHeight(900);
        canvas.setWidth("900px");
        canvas.setHeight("900px");

        RootPanel.get().add(canvas);

        drawSomeThing(canvas.getContext2d());
    }

    private void drawSomeThing(Context2d gc) {
        gc.beginPath();
        gc.moveTo(100, 100);
        gc.lineTo(500, 100);
        gc.lineTo(500, 500);
        gc.lineTo(100, 500);
        gc.lineTo(100, 100);
        gc.stroke();

        gc.beginPath();
        gc.moveTo(400, 400);
        gc.lineTo(800, 400);
        gc.lineTo(800, 800);
        gc.lineTo(400, 800);
        gc.lineTo(400, 400);
        gc.setFillStyle("coral");
        gc.fill();
    }

}
Java-Programm stoppen (wenn noch nicht getan). Programm neu erstellen, und starten. Dann wieder den Browser mit der passenden URL aufrufen.
cd Entwicklung/gwt-shell/
mvn package
java -jar target/gwt-shell-2022.12.jar
cd ../..
Im Browser sollten unsere beiden bekannten Vierecke zu sehen sein. Der eigenlich Code ist auch dem JavaFX-Code sehr ähnlich (wir mahlen halt immer in einem Canvas). Das drumm herum ist naturgemäß aber ein völlig anderes.
Das Debugging ist hier natürlich ein ganz anderes und wirklich fürchterlich. Kann ich keinem Empfehlen. Daher werde ich es hier auch nicht präsentieren. Das ist im JavaFX viel einfacher.
Fertig. Zurück zu Teil 4: Malen mit der Maus