JavaFX Layouts, Containers, Nodes

in Arbeit ...

1. Allgemein

1.1. Klassenhierarchie von Container-enthaltenden UI-Elementen

Zusätzlich werden viele weitere UI-Klassen in der Vererbungshierarchie gezeigt, meist ist ein Link zu Online-Javadoc ( ⬈ ) angegeben.

Auch die implementierten Interfaces (Via Node alle: Styleable, EventTarget; via Control: Skinnable) ) sind samt Javadoc-Link angegeben, weitere wichtige Charakteristiken eingeführt in Region: CSS-Stylebarkeit, Borders, Backgrounds, resizeable finden sich ebenfalls.

Die Klassen zu den vielen Zusatzelementen wie Border, Background, Abstände, Zeilen, Spalten, u.v.m. sind nicht dargestellt. Diese finden sich in den angelinkten Javadocs.

Wegen des Schwerpunktes auf Container-Funktionalität für UI-Elemente werden viele Controls (auch wegen ihrer großen Anzahl und Spezifität) nicht aufgenommen. Information zu diesen findet sich separat.

Node (abstract,EventTarget ⬈+Styleable ⬈)Parent (abstract,protectedchildren)Group (nonresizable,aber gemein-same Trans-formationen)Region (resizable+CSS +Borders+Backgrounds)Pane (unmanaged,publicchildren)AnchorPane BorderPane FlowPane GridPane TilePane HBox VBox StackPane Control +Pkg-Summary ⬈(+Skinnable ⬈)... many other controls likeButton, TextField, ...SplitPane (many Nodes)ButtonBar (many Nodes)ToolBar (many Nodes)Accordion (TitledPanes ⬈with Node)TabPane (Tabs ⬈with Node)ScrollPane (single Node)Axis<T>(abstr),Chart(abstr.)+2 spez. Hilfskl.f. TableView ...WebView WebBrowserShape Arc, Circle, CubicCurveEllipse, Line, PathPolygon, Polyline, QuadCurve, Rectangle, SVGPath, TextImageView (needsImage ),MediaView (needsMediaPlayer which needsMedia ),Canvas (needsGraphicsContext )for 3D, Animation ec.: Camera, LightBase, Shape3D, Subscene
Abbildung 1. Klassenhierarchie Container und Weiteres

1.2. Details zu wichtigen Container-Klassen und "Nachbarn"

Pfeil-Symbole nach links oben (⬉): navigieren nach oben zur grafischen Übersicht

1.2.1. Node

Ist Basisklasse aller "scene graph nodes". Das UI ist als visuelle Hierarchie von Elementen aufgebaut, von denen viele als Container für ein, zwei oder mehr Sub-Elemente dienen können, andere enthalten nur Komponenten wie Text oder Bilder oder haben keinerlei eingebettete Elemente.

Wichtige Funktionalitäten:

  • ID für Auffinden (z.B.: Node wanted = scene.lookup("#myId");), CSS, etc.
    (für Zugriff auf alle Funktionalitäten casten von Node auf tatsächlichen Typ)

  • Koordinatensystem x: , y:

  • 4 Transformationen: Translation (Verschiebung), Rotation (mit Drehpunkt und Winkel), Skalierung (Zoom), Scherung (Quadrat → Raute).

Koordinaten x, y und Abmessungen width, height sind Eigenschaften des Objekts und bleiben bei Transformationen unverändert (lokales Koordinatensystem), seine Abmessungen in seinem "Parent" ändern sich jedoch! Wichtig ist hier der Begriff "Bounding Rectangle". Details siehe Javadoc von Node. Es gibt Methoden - z.B. theNode.boundsInParent() etc., um Werte in den jeweiligen Koordinatensystemen zu erhalten.

Node (JavaFX 17) | OpenJFX.io …​ 2023-02-21

Wichtige Elemente, die NICHT von Node erben: MenuItem, Menu (implementieren aber wie Node die Interfaces Styleable, EventTarget)

1.2.2. Parent

Ist für hierarchische Struktur (Children-Liste) und dazugehörige Operationen zuständig (add/remove, "Dirty-State"-Verwaltung für Layout und Rendering, Bounds-Berechnungen, Ausführen der Layout-Operationen bei jedem "Puls" f. ereignisgesteuerte Neuberechnung).

1.2.3. Region

Basisklasse für alle Controls und Layout Panes. ist "resizable", hat Borders, Hintergrund, ab hier kann mit CSS "gestylt" werden.

Jedes Region-Objekt kann Border (und Background) setzen:

aRegion.setBorder(new Border(new BorderStroke( Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
Für BorderStroke sind die hier verwendeten die Standardwerte, die auch erreicht werden können mit
aRegion.setBorder(new Border(new BorderStroke(null, null, null, null);

Das selbe Border-Objekt kann beliebig oft genutzt werden !!!

Anstelle von (oder in Kombination mit) BorderStroke kann auch BorderImage genutzt werden – siehe verlinkte JavaDocs.

Color hat viele Farb-Konstante und auch viele Factory-Methoden, um Farben (mit optionaler Undurchsichtigkeit = opacity = Alpha-Wert: 0.0…​1.0) zu erzeugen:

  • Color.rgb(int red, int green, int blue, double opacity) …​ Farbwerte 0…​255

  • Color.color​(double red, double green, double blue, double opacity) …​ Farbwerte 0.0…​1.0

  • …​

Meist einfacher ist die Verwendung von CSS: aRegion.setStyle("-fx-border-color: black"; )

1.2.4. Group ("Nachbar" von Region, keine Subklassen)

Hauptaufgabe: Gruppieren von UI-Elementen für gemeinsame Transformationen und weitere Effekte.

In Standardeinstellung werden alle Mitglied-Elemente beim Layout auf ihre Preferred Sizes gesetzt. (umstellbar mit autoSizeChildren)

Layout wird vom Platzbedarf der "managed resizeable children" automatisch festgelegt.

1.2.5. WebView

in Arbeit ...

1.3. "Echte" Container

1.3.1. Pane

unmanaged Position: setLayoutX(..) + [anschließend] setTranslateX(..) Jenkov: JavaFX Pane

1.3.2. AnchorPane

Infos zur AnchorPane.

1.3.3. BorderPane

Infos zur BorderPane.

1.3.4. FlowPane

Infos zur FlowPane.

1.3.5. GridPane

Beispiel für viele GridPane-Funkionalitäten:

package my.support.scribble01;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class GridPaneScribble extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        GridPane gp = new GridPane();

        Label lbl = null;
        Node nodeForLaterChange1 = null;
        for (int iRow = 0; iRow < 3; iRow++) {
            for (int iCol = 0; iCol < 4; iCol++) {
                if (iCol == 1 && iRow == 1) {
                    continue;  // having a gap at pos (1,1) for testing
                }
                lbl = new Label(String.format("Cell c=%d, r=%d", iCol, iRow));
                if (iCol == 0 && iRow == 0) {
                    nodeForLaterChange1 = lbl;
                }
                lbl.setStyle("-fx-border-color: red;-fx-padding: 6.0;-fx-background-color: #dff");
                gp.add(lbl, iCol, iRow);
            }
        }
        // Getting position (row, column) of a given node:
        int iCol = GridPane.getColumnIndex(lbl);
        int iRow = GridPane.getRowIndex(lbl);
        System.out.format("Last created lbl: '%s': col=%d, row=%d%n", lbl.getText(), iCol, iRow);
        // Getting node at given row and column:
        int wantedCol = 2;
        int wantedRow = 0;
        Node wantedNode = null;
        for (Node node : gp.getChildren()) {
            if (GridPane.getColumnIndex(node) == wantedCol
                    && GridPane.getRowIndex(node) == wantedRow) {
                wantedNode = node;
                break;
            }
        }
        System.out.format("Node at col=%d, row=%d: [%s]%n", wantedCol, wantedRow, wantedNode);
        // changing row and/or column of a member node (using a static method!):
        GridPane.setColumnIndex(nodeForLaterChange1, 5);

        // Layout and Styling:
        gp.setGridLinesVisible(true);
        gp.setVgap(10.0);
        gp.setHgap(10.0);
        gp.setPadding(new Insets(10.0));
        gp.setStyle("-fx-background-color: #ffffdd");

        // Final state output:
        System.out.println("\n==== Final Info (ordering from children list!): ====");
        for (Node node : gp.getChildren()) {
            System.out.format("  c=%d, r=%d, rowspan=%d, [%s]%n",
                    GridPane.getColumnIndex(node), GridPane.getRowIndex(node),
                    GridPane.getRowSpan(node), node);
        }
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

        // create scene and show:
        primaryStage.setScene(new Scene(gp));
        primaryStage.show();
    }
}
ScrShot20230523 JfxGridPaneDemo

TODO: # finish !!

1.3.6. TilePane

Infos zur TilePane.

1.3.7. HBox

HBox ist ein simpler horizontal organisierter Container für Nodes. Positionierung erfolgt durch Infos zur HBox.

1.3.8. VBox

Infos zur VBox.

StackPane

Infos zur StackPane.

1.4. Container-Controls Allgemein (Inhalt mehrere Node-Obj.)

1.4.1. Control

Infos zu Control.

1.4.2. SplitPane

Info zur SplitPane.

1.4.3. ButtonBar

Info zu ButtonBar.

1.4.4. ToolBar

Info zu ToolBar.

1.5. Container-Controls Spezialisiert (Mehrere spezielle Elemente)

1.5.1. Accordion

Info zu Accordion.

1.5.2. TabPane

Die TabPane stellt aktivierbare Karteireiter mit je Karteireiter unterschiedlichem Inhaltsberech zur Verfügung.

Diese Komponente ist eine Kombination von Control und Layout. Die Klasse ist: javafx.scene.control.TabPane, also nicht, wie man vielleicht zuerst vermuten würde, im Package javafx.scene.layout.

Anwendungsbeispiele:

JavaFX Tutorial …​ 2023-02-21

1.5.3. ScrollPane

2. Scribble

2.1. Container-Controls Allgemein (Inhalt mehrere Node Obj.)

2.2. Container-Controls Spezialisiert (Mehrere spezielle Elemente)

2.4. Einzuordnen

DialogPane

Overview (JavaFX 17) …​ 2023-03-18

Einige Hintergrund-Info von 2010 JavaFX Layout Secrets with Amy Fowler …​ 1.5.2021, 11:11:43

3. Responsive Layout

prüfen, ob sinnvolle Info: https://stackoverflow.com/questions/35936072/how-to-make-responsive-design-in-javafx [java - How to make responsive design in javafx - Stack Overflow] …​ 2023-02-26