FlugMonitor – Echtzeit-Flugverkehr mit Java und OpenSky visualisieren

Wer kennt das nicht: Man schaut in den Himmel, sieht ein Flugzeug und fragt sich, wo es gerade herkommt und in welcher Höhe es fliegt. Mit dem FlugMonitor lässt sich genau diese Frage beantworten – und zwar für alle Flugzeuge auf der Welt gleichzeitig. In diesem Artikel zeige ich, wie ich eine Java-Swing-Anwendung gebaut habe, die Echtzeit-Daten des OpenSky Network abruft, auswertet und übersichtlich darstellt.

———————————————————————–
Was ist der FlugMonitor?
———————————————————————–

Der FlugMonitor ist eine Desktop-Anwendung, die ich mit Java 21 und Swing entwickelt habe. Swing ist das klassische GUI-Framework von Java – also das Werkzeugkasten, mit dem man Fenster, Tabellen und Buttons baut. Die Anwendung zeigt auf einen Blick, wie viele Flugzeuge sich gerade weltweit in welchem Höhenbereich befinden. Die Daten kommen dabei in Echtzeit direkt vom OpenSky Network, das Flugzeugpositionen aus aller Welt sammelt und kostenlos zur Verfügung stellt.

Das Besondere: Die Anwendung fragt bei jedem Klick auf „Aktualisieren“ live die OpenSky-API ab und wertet tausende Flugzeugpositionen in Millisekunden aus. Das Ergebnis landet sofort in einer übersichtlichen Tabelle und einem farbigen Balkendiagramm.

———————————————————————–
Was ist das OpenSky Network?
———————————————————————–

Das OpenSky Network (opensky-network.org) ist ein internationales Forschungsprojekt, das Flugzeugdaten per ADS-B empfängt. ADS-B steht für „Automatic Dependent Surveillance–Broadcast“ – ein System, bei dem moderne Flugzeuge automatisch ihre Position, Geschwindigkeit und Höhe per Funksignal ausstrahlen. Tausende freiwillige Helfer auf der ganzen Welt haben ADS-B-Empfänger aufgestellt und senden ihre Empfangsdaten kontinuierlich an das OpenSky-Netzwerk.

Für Entwickler stellt OpenSky eine kostenlose REST-API bereit. Eine Java-Bibliothek macht den Zugriff besonders einfach: Mit wenigen Zeilen Code holt man sich den aktuellen Zustand aller sichtbaren Flugzeuge als Liste von „StateVector“-Objekten. Jedes StateVector enthält unter anderem:

– Rufzeichen des Flugzeugs (ICAO24-Transpondercode)
– Geografische Position (Längen- und Breitengrad)
– Geodätische Höhe in Metern
– Geschwindigkeit und Kursrichtung
– Ob das Flugzeug am Boden ist (onGround-Flag)

———————————————————————–
Die Benutzeroberfläche im Überblick
———————————————————————–

Beim Start der Anwendung öffnet sich ein Fenster mit drei Bereichen:

1. Zwei Schaltflächen oben:
– „Aktualisieren“ (blau): Holt die neuesten Daten vom OpenSky-Server.
– „Kopieren“ (grün): Überträgt die gesamte Tabelle als formatierten Text
in die Zwischenablage, zum Beispiel für Berichte oder E-Mails.

2. Eine Tabelle in der Mitte mit zwei Spalten:
– „Flugbereich in Meter“: Die Höhenkategorie, z. B. „11.000 – 11.500“
– „Flughöhe in Meter“: Die Anzahl der Flugzeuge in diesem Bereich

Die Tabelle hat 18 Zeilen für verschiedene Höhenbänder, eine
hervorgehobene Summenzeile am Ende sowie Zebrastreifen zur besseren
Lesbarkeit.

3. Ein Balkendiagramm unten:
Das Diagramm zeigt dieselben Daten visuell. Jeder Balken entspricht einer
Höhenkategorie. Die Farben verlaufen von Graugrün (am Boden / „Parken“)
über Türkis und Blau (mittlere Flughöhen) bis zu Violett (Reiseflughöhen
um 11.000 Meter) und zurück zu Grau (Stratosphäre über 13.000 Meter).
So erkennt man auf den ersten Blick, welche Höhen am stärksten genutzt
werden.

Unten in der Statusleiste steht nach jedem Abruf der genaue Zeitstempel,
z. B. „Zeitpunkt: So. 19.04.2026 06:33:30“.

———————————————————————–
Die Höhenbereiche – was bedeuten sie?
———————————————————————–

Die 18 Kategorien in der Tabelle folgen einer fachlichen Logik:

Parken (0 m): Flugzeuge, die am Boden stehen. Das erkennt die Anwendung
am „onGround“-Flag im StateVector oder daran, dass keine Höhenangabe
vorliegt. An einem normalen Tag sind das mehrere Hundert Maschinen weltweit,
die von OpenSky trotzdem erfasst werden (z. B. auf belebten Rollfeldern).

1 bis 500 m: Start- und Landephase. Flugzeuge steigen kurz nach dem Abheben
sehr steil, daher ist diese Kategorie weniger stark besetzt als man erwarten
würde.

500 bis 5.000 m: Steig- und Sinkflug. Hier befinden sich Maschinen auf dem
Weg zu ihrer Reiseflughöhe sowie Propellermaschinen und Hubschrauber auf
kürzeren Strecken.

5.000 bis 9.000 m: Unterer Reiseflugbereich. Kleinere Verkehrsflugzeuge und
Regionalflüge nutzen diesen Bereich.

9.000 bis 13.000 m: Oberer Reiseflugbereich. Das ist die Welt der großen
Verkehrsflugzeuge wie Airbus A320, Boeing 737 oder A380. Der deutliche
Gipfel bei 11.000 bis 11.500 Metern entspricht der typischen Reiseflughöhe
(FL350 bis FL380 in der Luftfahrt-Sprache). Hier fliegen die meisten
Langstreckenmaschinen.

Über 13.000 m: Wenige spezialisierte Flugzeuge, z. B. bestimmte
Businessjets oder Militärflugzeuge.

Das Diagramm auf dem Screenshot zeigt schön den charakteristischen Einbruch
bei 5.000 bis 7.000 Metern (kaum Flugzeuge in diesem Zwischenbereich) und
den deutlichen Gipfel bei 11.000 bis 11.500 Metern – der klassischen
Reiseflughöhe moderner Verkehrsflugzeuge.

———————————————————————–
Technischer Aufbau – Schritt für Schritt erklärt
———————————————————————–

Die Projektstruktur

Das Projekt besteht für die Gui aus einer einzigen Java-Datei: FlugMonitorSwing.java.

Maven verwaltet die Abhängigkeiten.

Die Hauptklasse heißt FlugMonitorSwing und erbt von JFrame – dem Standard-Fenster in Swing. Innerhalb der Klasse gibt es zwei wichtige innere Klassen: DiagramPanel für das Balkendiagramm und ZebraRenderer für die Tabellendarstellung.

Datenabruf mit SwingWorker

In Java gibt es eine wichtige Regel: Alles, was die Benutzeroberfläche betrifft, muss im sogenannten Event Dispatch Thread (EDT) laufen. Netzwerk- anfragen blockieren aber den Thread, solange sie laufen – das würde das Fenster einfrieren.

Die Lösung heißt SwingWorker. Das ist eine Klasse, die einen Hintergrundthread startet, die Arbeit erledigt (hier: Netzwerkabruf) und danach sauber in den EDT zurückwechselt, um die Oberfläche zu aktualisieren:

Während der Abruf läuft, sind die Buttons deaktiviert (setEnabled(false)), damit man nicht versehentlich einen zweiten Abruf startet. Nach dem Abruf werden sie wieder aktiviert.

Verteilung berechnen

Die Methode berechneVerteilung() geht alle StateVector-Objekte durch und entscheidet für jedes Flugzeug, in welche Höhenkategorie es gehört:

Die Bereiche sind als unveränderliche Java-Records definiert:

Records sind ein modernes Java-Feature (ab Java 16), das kompakte Datenklassen ohne Boilerplate ermöglicht.

Das Balkendiagramm mit Graphics2D

Für das Diagramm wurde bewusst keine externe Bibliothek (wie JFreeChart) eingesetzt. Stattdessen zeichnet die innere Klasse DiagramPanel alles selbst mit Java2D, dem eingebauten Grafiksystem von Java.

Jede Swing-Komponente kann die Methode paintComponent(Graphics g) überschreiben und dann beliebige Grafiken zeichnen. Der Schlüssel ist das Casting auf Graphics2D, das erweiterte Möglichkeiten bietet:

Antialiasing sorgt dafür, dass Kanten und Schrift weich und nicht pixelig erscheinen. Wichtig: g.create() erzeugt eine Kopie des Graphics-Objekts, die am Ende mit dispose() sauber freigegeben wird.

Die Balken werden als RoundRectangle2D gezeichnet – ein Rechteck mit abgerundeten Ecken:

Darüber kommt ein halbtransparenter weißer Streifen (Alpha-Wert 35 von 255), der einen Glanzeffekt imitiert:

Farben nach Höhe

Die 18 Farben für die Balken wurden manuell als Hex-Werte festgelegt. Der Verlauf folgt einer inhaltlichen Logik: Graugrün für geparkte Flugzeuge am Boden, über lebendiges Grün (Niedrigflug), Türkis und Blau (mittlere Höhen), bis zu sattem Violett für den Reiseflugbereich, und zurück zu gedämpftem Blaugrau für die Stratosphäre:

Tabelle mit Zebrastreifen

Die Tabelle verwendet einen eigenen ZebraRenderer, der von DefaultTableCellRenderer erbt. Je nach Zeilennummer wird die Hintergrundfarbe gewechselt. Die Summenzeile erhält eine Sonderbehandlung:

Zwischenablage

Der „Kopieren“-Button baut einen formatierten String aus dem TableModel:

Dieser String wird dann per Toolkit in die System-Zwischenablage gelegt:

Damit kann der Inhalt direkt in Excel, eine E-Mail oder einen Texteditor eingefügt werden.

———————————————————————–
Build und Start
———————————————————————–

Das Projekt nutzt Maven als Build-System. Die pom.xml definiert Java 21 als Zielversion und bindet das Maven Shade Plugin ein, das alle
Abhängigkeiten in eine einzige ausführbare JAR-Datei bündelt (Fat-JAR):

Alternativ kann die Anwendung direkt aus der IDE (IntelliJ IDEA, Eclipse) gestartet werden, indem man FlugMonitorSwing.main() ausführt.

Voraussetzung ist eine Java-21-Installation sowie eine Internetverbindung zum OpenSky-Server. Die OpenSky-API ist ohne Registrierung nutzbar, unterliegt aber einem Rate-Limit (ca. 10 Anfragen pro Minute für anonyme Nutzer). Wer mehr Anfragen benötigt, kann sich kostenlos registrieren und erhält dann ein erhöhtes Kontingent.

———————————————————————–
Was zeigt der aktuelle Screenshot?
———————————————————————–

Der Screenshot entstand am Sonntag, dem 19. April 2026 um 06:33:30 Uhr.
Zu diesem frühen Sonntagmorgen-Zeitpunkt waren 4.821 Flugzeuge weltweit
von OpenSky erfasst. Die Verteilung zeigt das typische Muster:

– 662 Flugzeuge stehen am Boden („Parken“) – wartende Maschinen auf
Flughäfen in Asien, Europa und Amerika.

– Der Höhenbereich 11.000 – 11.500 m ist mit 498 Flugzeugen am
stärksten besetzt. Das sind überwiegend Langstreckenmaschinen auf
Interkontinentalrouten (z. B. Nordatlantik oder Transpazifik).

– Zwischen 5.000 und 7.000 Metern gibt es einen deutlichen Einbruch
(136 und 134 Flugzeuge). Diese „Lücke“ ist charakteristisch: Flugzeuge
durchqueren diesen Bereich nur kurz beim Steigen und Sinken, niemand
fliegt dort dauerhaft.

– Der zweite Gipfel bei 10.500 – 11.000 m (380 Flugzeuge) und
11.500 – 12.000 m (435 Flugzeuge) bestätigt, dass der gesamte Bereich
zwischen FL320 und FL390 der Hauptverkehrsweg der zivilen Luftfahrt ist.

———————————————————————–
Mögliche Erweiterungen
———————————————————————–

Der FlugMonitor lässt sich auf viele Weisen ausbauen:

Filterung nach Region: Die OpenSky-API erlaubt es, einen geografischen Ausschnitt (Bounding Box) zu übergeben. So könnte man nur Flugzeuge über Deutschland oder Europa anzeigen.

Automatische Aktualisierung: Ein javax.swing.Timer könnte alle 60 Sekunden automatisch aktualisieren, ohne dass der Nutzer auf den Button klicken muss.

Historische Daten: OpenSky bietet auch eine History-API. Damit ließe sich der Tagesverlauf darstellen – morgens weniger, tagsüber mehr Flugzeuge.

Karte: Mit einem Kartenbibliothek (z. B. JXMapViewer oder einer eingebetteten WebView) könnten die Flugzeuge auf einer Weltkarte als Punkte dargestellt werden.

CSV-Export: Neben dem Kopieren-Button könnte ein Export-Button eine CSV-Datei schreiben, die sich direkt in Excel öffnen lässt.

Dark Mode: Swing unterstützt mit modernen Look-and-Feels wie FlatLaf einen echten Dark Mode, der die dunkle DiagramPanel-Optik nahtlos in die gesamte Oberfläche integrieren würde.

———————————————————————–
Fazit
———————————————————————–

Der FlugMonitor zeigt, wie viel man mit purem Java und ohne externe Grafikbibliotheken erreichen kann. Die Kombination aus SwingWorker (für reaktive UI), Graphics2D (für das Diagramm) und der OpenSky-API (für Echtzeit-Daten) ergibt eine vollständige Desktop-Anwendung, die sich in wenigen Minuten bauen und starten lässt.

Der vollständige Quellcode und die Maven-Konfiguration stehen auf GitLab zum Download bereit.

Wer Fragen oder Anmerkungen hat, kann diese gerne in den Kommentaren hinterlassen – ich freue mich über jede Rückmeldung!