Java Anwendungsentwicklung – Tag 2 von 10
Von Franz-Martin, CTO bei Java Fleet Systems Consulting
Schwierigkeit: 🟢 Einsteiger
Dauer: ~6-8 Stunden (mit Übungen)
Voraussetzungen: Tag 1 abgeschlossen, Java SE Grundkenntnisse
🗺️ Deine Position im Kurs
| Tag | Thema | Niveau | Status |
|---|---|---|---|
| 1 | Die Desktop-Ära: Warum GUIs? | 🟢 Grundlagen | ✅ Abgeschlossen |
| → 2 | AWT & Swing Grundlagen | 🟢 Grundlagen | 👉 DU BIST HIER! |
| 3 | Layouts & Event-Handling | 🟢 Grundlagen | 🔜 Kommt als nächstes |
| 4 | Komplexe Swing-Komponenten | 🟡 Fortgeschritten | 🔒 Gesperrt |
| 5 | JavaFX: Die „moderne“ Alternative | 🔴 KOPFNUSS | 🔒 Gesperrt |
| 6 | JDBC Grundlagen | 🟢 Grundlagen | 🔒 Gesperrt |
| 7 | JDBC Best Practices | 🟡 Fortgeschritten | 🔒 Gesperrt |
| 8 | JPA Einführung | 🟢 Grundlagen | 🔒 Gesperrt |
| 9 | JPA CRUD & Queries | 🟡 Fortgeschritten | 🔒 Gesperrt |
| 10 | Integration & Ausblick | 🔴 KOPFNUSS | 🔒 Gesperrt |
Legende: 🟢 Einsteiger-freundlich | 🟡 Requires Grundlagen | 🔴 Optional/Anspruchsvoll
📋 Bevor du startest
Voraussetzungen:
- ✅ Tag 1 gelesen (du weißt WARUM wir das lernen)
- ✅ JDK 21 installiert
- ✅ NetBeans 22 (oder IntelliJ IDEA)
- ✅ Maven 3.9+
Download für heute:
⚡ Das Wichtigste in 30 Sekunden
Heute lernst du:
- ✅ Den fundamentalen Unterschied zwischen AWT und Swing
- ✅ Ein Fenster mit JFrame erstellen
- ✅ Die wichtigsten Swing-Komponenten (JButton, JLabel, JTextField…)
- ✅ Warum
SwingUtilities.invokeLater()PFLICHT ist - ✅ Ein funktionierendes Formular bauen
Die Kernregel:
Alle Swing-Komponenten beginnen mit „J“
Button → JButton, Label → JLabel, TextField → JTextField
Wenn kein „J“ → es ist AWT. Wenn „J“ → es ist Swing. So einfach.
👋 Willkommen zu Tag 2!
Liebe Java-Crew! ⛵
Franz-Martin hier, zurück für Tag 2!
Gestern war Theorie-Tag. Du weißt jetzt, WARUM wir Swing lernen. Heute wird’s praktisch: Du baust dein erstes Fenster!
Aber zuerst die wichtigste Frage:
Was ist der Unterschied zwischen AWT und Swing?
Wenn du das verstehst, verstehst du alles, was danach kommt.
Los geht’s! 🚀
🟢 GRUNDLAGEN
AWT vs Swing – Der fundamentale Unterschied

Abbildung 1: AWT nutzt native OS-Komponenten, Swing zeichnet alles selbst
AWT (Abstract Window Toolkit) – 1995
AWT war Javas erster Versuch einer GUI-Bibliothek. Die Idee war clever:
„Wir nutzen einfach die Buttons, Labels und Textfelder, die das Betriebssystem schon hat!“
// AWT-Code (ohne J!)
Button button = new Button("OK");
Label label = new Label("Hallo");
TextField textField = new TextField(20);
Das Problem: Ein Windows-Button sieht anders aus als ein Mac-Button als ein Linux-Button. Und sie verhalten sich unterschiedlich!
Das Ergebnis: „Write Once, Debug Everywhere.“
Swing – 1998
Swing löste das Problem radikal: Es ignoriert das Betriebssystem komplett.
// Swing-Code (mit J!)
JButton button = new JButton("OK");
JLabel label = new JLabel("Hallo");
JTextField textField = new JTextField(20);
Swing zeichnet jeden einzelnen Pixel selbst. Ein JButton ist kein Windows-Button – es ist ein von Java gezeichnetes Rechteck, das wie ein Button aussieht.
Vorteile:
- ✅ Sieht auf jedem OS gleich aus
- ✅ Verhält sich auf jedem OS gleich
- ✅ Look-and-Feel kann geändert werden
- ✅ Mehr Kontrolle, mehr Möglichkeiten
Nachteile:
- ❌ Sieht nicht „nativ“ aus
- ❌ Der typische „Java-Look“
- ❌ Performance-Overhead
💡 Neu hier? Was ist „Look-and-Feel“?
Das Look-and-Feel bestimmt, wie Swing-Komponenten aussehen. Du kannst zwischen verschiedenen wählen:
- Metal – Der klassische Java-Look (grau, langweilig)
- Nimbus – Etwas moderner (seit Java 6)
- System – Versucht wie das OS auszusehen
- FlatLaf – Modern, hübsch (externe Library)
Dein erstes JFrame
Ein JFrame ist das Hauptfenster deiner Anwendung. Hier ist das absolute Minimum:
package de.javafleet.gui;
import javax.swing.*;
public class MeinErstesFenster {
public static void main(String[] args) {
// PFLICHT: Swing-Code im Event Dispatch Thread!
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Mein erstes Fenster");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null); // Bildschirmmitte
frame.setVisible(true); // IMMER als letztes!
});
}
}
Die wichtigsten JFrame-Methoden:
| Methode | Beschreibung |
|---|---|
setTitle(String) | Fenstertitel setzen |
setSize(width, height) | Größe in Pixeln |
pack() | Größe automatisch an Inhalt anpassen |
setLocationRelativeTo(null) | Bildschirmmitte |
setDefaultCloseOperation() | Was beim Schließen passiert |
setResizable(false) | Größenänderung verbieten |
setVisible(true) | Fenster anzeigen (IMMER zuletzt!) |
Der Event Dispatch Thread (EDT) – WICHTIG!

Abbildung 2: Warum SwingUtilities.invokeLater() so wichtig ist
Das ist einer der häufigsten Fehler bei Swing-Anfängern:
// ❌ FALSCH - GUI-Code direkt in main()
public static void main(String[] args) {
JFrame frame = new JFrame(); // GEFAHR!
frame.setVisible(true); // GEFAHR!
}
// ✅ RICHTIG - Mit invokeLater()
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setVisible(true);
});
}
Warum ist das so wichtig?
Swing ist NICHT thread-safe. Das bedeutet:
- Es gibt einen speziellen Thread für GUI-Updates: den Event Dispatch Thread (EDT)
- Wenn du GUI-Code aus einem anderen Thread ausführst, bekommst du Race Conditions
- Diese Bugs treten manchmal auf – nicht immer. Das macht sie schwer zu finden.
SwingUtilities.invokeLater() stellt deinen Code in die EDT-Queue. So wird er garantiert im richtigen Thread ausgeführt.
„Das Fiese an EDT-Bugs: Auf deinem Rechner läuft alles. Beim Kunden crasht es. Und du weißt nicht warum.“
— Franz-Martin (aus leidvoller Erfahrung)
Die wichtigsten Swing-Komponenten
Hier sind die Komponenten, die du am häufigsten brauchst:
Text-Komponenten
| Komponente | Zweck | Beispiel |
|---|---|---|
JLabel | Text anzeigen (nicht editierbar) | Beschriftungen |
JTextField | Einzeilige Eingabe | Name, E-Mail |
JPasswordField | Passwort-Eingabe (zeigt ●●●) | Login |
JTextArea | Mehrzeilige Eingabe | Kommentare |
// JLabel - Nur Anzeige
JLabel label = new JLabel("Dein Name:");
JLabel htmlLabel = new JLabel("<html><b>Fett</b> und <i>kursiv</i></html>");
// JTextField - Einzeilig
JTextField textField = new JTextField(20); // 20 Spalten breit
String eingabe = textField.getText(); // Wert auslesen
// JPasswordField - Für Passwörter
JPasswordField passwordField = new JPasswordField(20);
char[] passwort = passwordField.getPassword(); // Gibt char[] zurück!
// JTextArea - Mehrzeilig (IMMER in JScrollPane!)
JTextArea textArea = new JTextArea(5, 30); // 5 Zeilen, 30 Spalten
textArea.setLineWrap(true); // Automatischer Umbruch
JScrollPane scrollPane = new JScrollPane(textArea);
💡 Warum gibt getPassword() ein char[] zurück?
Sicherheit! Strings bleiben im Speicher, bis der Garbage Collector sie löscht. char[] kann sofort mit
Arrays.fill(passwort, '0')überschrieben werden. Bei sensiblen Daten wichtig!
Button-Komponenten
| Komponente | Zweck | Beispiel |
|---|---|---|
JButton | Klickbare Schaltfläche | OK, Abbrechen |
JCheckBox | Mehrfachauswahl | Newsletter: Ja/Nein |
JRadioButton | Einzelauswahl (mit ButtonGroup) | Klein/Mittel/Groß |
JToggleButton | Ein/Aus-Schalter | Dark Mode |
// JButton - Der Klassiker
JButton button = new JButton("Klick mich!");
button.addActionListener(e -> {
System.out.println("Button wurde geklickt!");
});
// JCheckBox - Mehrfachauswahl
JCheckBox check = new JCheckBox("Newsletter abonnieren");
boolean ausgewaehlt = check.isSelected();
// JRadioButton - Einzelauswahl (BRAUCHT ButtonGroup!)
JRadioButton klein = new JRadioButton("Klein");
JRadioButton gross = new JRadioButton("Groß");
ButtonGroup group = new ButtonGroup(); // WICHTIG!
group.add(klein);
group.add(gross);
// Jetzt kann nur EINER ausgewählt sein
Listen & Dropdowns
// JComboBox - Dropdown
String[] optionen = {"Option 1", "Option 2", "Option 3"};
JComboBox<String> comboBox = new JComboBox<>(optionen);
String auswahl = (String) comboBox.getSelectedItem();
// JList - Scrollbare Liste
JList<String> list = new JList<>(optionen);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane listScroll = new JScrollPane(list);
🟡 PROFESSIONALS
🏃 Schon erfahren? Hier kommt das praktische Beispiel.
Ein vollständiges Formular
Lass uns alles zusammensetzen: Ein Registrierungsformular mit Validierung.

Abbildung 3: So hängen JFrame, ContentPane und Komponenten zusammen
Die Code-Struktur
Guter Swing-Code hat eine klare Struktur:
public class MeinFormular extends JFrame {
// 1. Komponenten als Felder (für späteren Zugriff)
private JTextField tfName;
private JButton btnSenden;
public MeinFormular() {
super("Mein Formular");
initComponents(); // 2. Komponenten erstellen
setupLayout(); // 3. Layout aufbauen
setupActions(); // 4. Event-Handler
setupFrame(); // 5. Frame konfigurieren
}
private void initComponents() {
tfName = new JTextField(20);
btnSenden = new JButton("Senden");
}
private void setupLayout() {
// Komponenten zum Frame hinzufügen
}
private void setupActions() {
btnSenden.addActionListener(e -> senden());
}
private void setupFrame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
}
private void senden() {
// Verarbeitung
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MeinFormular().setVisible(true);
});
}
}
Diese Struktur hält deinen Code sauber und wartbar.
Das Mini-Formular (vollständig)
Im Download findest du MiniFormular.java – ein komplettes Registrierungsformular mit:
- Vorname, Nachname, E-Mail
- Passwort mit Bestätigung
- Land-Auswahl (JComboBox)
- Newsletter-Checkbox
- AGB-Checkbox (Pflichtfeld)
- Validierung aller Eingaben
- Saubere Fehler-Meldungen
Auszug – Die Validierung:
private void registrieren() {
// Daten sammeln
String vorname = tfVorname.getText().trim();
String email = tfEmail.getText().trim();
char[] passwort = pfPasswort.getPassword();
// Validierung
StringBuilder fehler = new StringBuilder();
if (vorname.isEmpty()) {
fehler.append("• Vorname ist erforderlich\n");
}
if (!email.contains("@") || !email.contains(".")) {
fehler.append("• E-Mail-Format ungültig\n");
}
if (passwort.length < 8) {
fehler.append("• Passwort zu kurz (min. 8 Zeichen)\n");
}
// Ergebnis
if (fehler.length() > 0) {
JOptionPane.showMessageDialog(this,
"Bitte korrigiere:\n\n" + fehler,
"Validierungsfehler",
JOptionPane.ERROR_MESSAGE);
} else {
// Erfolg!
JOptionPane.showMessageDialog(this,
"Registrierung erfolgreich!",
"Willkommen!",
JOptionPane.INFORMATION_MESSAGE);
}
// SICHERHEIT: Passwort-Array überschreiben!
Arrays.fill(passwort, '0');
}
Tipps aus der Praxis
1. JTextArea IMMER in JScrollPane
// ❌ FALSCH frame.add(textArea); // ✅ RICHTIG frame.add(new JScrollPane(textArea));
Ohne ScrollPane gibt’s keine Scrollbars, auch wenn der Text überläuft.
2. RadioButtons BRAUCHEN ButtonGroup
// ❌ FALSCH - Beide können gleichzeitig an sein! frame.add(radio1); frame.add(radio2); // ✅ RICHTIG ButtonGroup group = new ButtonGroup(); group.add(radio1); group.add(radio2);
3. setVisible(true) IMMER als letztes
// ❌ FALSCH - Flackern, falsches Layout frame.setVisible(true); frame.add(panel); frame.pack(); // ✅ RICHTIG frame.add(panel); frame.pack(); frame.setVisible(true);
4. pack() vs setSize()
// setSize() - Feste Größe frame.setSize(800, 600); // pack() - Automatisch basierend auf Inhalt frame.pack(); // Besser! Passt sich an.
🔵 BONUS
⏸️ Optional! Für Neugierige.
Look-and-Feel ändern
Standard-Swing sieht… nach 1998 aus. Du kannst das ändern:
// MUSS vor dem Erstellen von Komponenten aufgerufen werden!
// 1. System Look-and-Feel (sieht aus wie Windows/Mac)
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// 2. Nimbus (moderner Java-Look)
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
// 3. FlatLaf (empfohlen - externe Library)
UIManager.setLookAndFeel(new FlatDarkLaf());
Wir nutzen in allen Beispielen FlatLaf Dark. Das sieht 2025 tatsächlich vorzeigbar aus.
Komponenten zur Laufzeit ändern
// Text ändern
button.setText("Neuer Text");
label.setText("<html><b>Fett!</b></html>");
// Aktivieren/Deaktivieren
button.setEnabled(false); // Ausgegraut
textField.setEditable(false); // Nur lesen
// Sichtbarkeit
panel.setVisible(false); // Verstecken
// Nach Änderungen: Neuzeichnen erzwingen
frame.revalidate();
frame.repaint();
💬 Real Talk: Nova baut ihr erstes Fenster
Java Fleet Büro, Dienstagnachmittag. Nova sitzt vor ihrem Laptop. Franz-Martin schaut vorbei.
Franz-Martin: „Und? Erstes Fenster gebaut?“
Nova: (frustriert) „Ja. Es ist da. Aber es sieht SO hässlich aus. Wie aus den 90ern.“
Franz-Martin: (lacht) „Willkommen bei Swing! Hast du das Look-and-Feel geändert?“
Nova: „Das was?“
Franz-Martin: (setzt sich) „Zeig mal deinen Code.“
Nova:
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setSize(400, 300);
frame.setVisible(true);
}
Franz-Martin: (zuckt zusammen) „Okay. Drei Probleme.“
Nova: „Drei?!“
Franz-Martin: „Erstens: Wo ist invokeLater?“
Nova: „Braucht man das? Es läuft doch.“
Franz-Martin: „Es läuft JETZT. Es wird nicht IMMER laufen. EDT-Bugs sind die schlimmsten Bugs – sie treten zufällig auf. Bei dir nie, beim Kunden ständig.“
Nova: (seufzt, tippt)
SwingUtilities.invokeLater(() -> {
// ...
});
Franz-Martin: „Gut. Zweitens: Was passiert, wenn der User das Fenster schließt?“
Nova: „Es schließt?“
Franz-Martin: „Nein. Es versteckt sich nur. Dein Programm läuft weiter. Check mal den Task Manager.“
Nova: (checkt) „Oh. Da sind fünf Java-Prozesse…“
Franz-Martin: „setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE).“
Nova: (tippt)
Franz-Martin: „Drittens: Das Look-and-Feel. Schreib das VOR dem Erstellen der Komponenten:“
try {
UIManager.setLookAndFeel(new FlatDarkLaf());
} catch (Exception e) {
e.printStackTrace();
}
Nova: (führt aus) „Oh! Das sieht ja… tatsächlich okay aus!“
Franz-Martin: „FlatLaf ist dein Freund. Ohne das zeigst du niemandem deine Swing-App.“
Nova: „Warum ist das nicht Standard?“
Franz-Martin: (steht auf) „Weil Swing von 1998 ist. Da war das der heiße Scheiß.“
Nova: „Hättest du mir das nicht VORHER sagen können?!“
Franz-Martin: (grinst) „Manche Fehler muss man selbst machen. Jetzt vergisst du’s nie wieder.“
🎨 Challenge für dich!
Wähle dein Level:
🟢 Level 1 – Einsteiger
- [ ] Erstelle ein Fenster mit einem Label und einem Button
- [ ] Wenn der Button geklickt wird, ändere den Label-Text Geschätzte Zeit: 15-30 Minuten
🟡 Level 2 – Fortgeschritten
- [ ] Baue einen einfachen Taschenrechner (nur +, -, *, /)
- [ ] Nutze JTextField für Ein- und Ausgabe
- [ ] Vier Buttons für die Operationen Geschätzte Zeit: 45-60 Minuten
🔵 Level 3 – Profi
- [ ] Erweitere das MiniFormular um ein Profilbild-Upload
- [ ] Nutze JFileChooser zum Auswählen eines Bildes
- [ ] Zeige eine Vorschau mit JLabel und ImageIcon Geschätzte Zeit: 1-2 Stunden
Java Anwendungsentwicklung - Tag 2
AWT & Swing Grundlagen
❓ Häufig gestellte Fragen
Frage 1: Muss ich wirklich IMMER invokeLater() verwenden?
Ja. Technisch „funktioniert“ es manchmal ohne, aber du erzeugst Race Conditions, die zufällig auftreten. Mach’s dir zur Gewohnheit – immer invokeLater().
Frage 2: Warum sieht mein Fenster auf meinem Mac anders aus als bei meinem Kollegen auf Windows?
Wahrscheinlich nutzt ihr das System-Look-and-Feel (UIManager.getSystemLookAndFeelClassName()). Das passt sich dem OS an. Wenn du überall gleich aussehen willst, nimm FlatLaf oder Nimbus.
Frage 3: Kann ich Swing mit CSS stylen wie HTML?
Nein. Swing hat kein CSS. Du kannst Look-and-Feel ändern und einzelne Komponenten mit setForeground(), setBackground(), setFont() stylen – aber es ist mühsam. Das ist einer der Gründe, warum JavaFX entwickelt wurde (das HAT CSS).
Frage 4: Wie mache ich mein Fenster responsive (passt sich Bildschirmgröße an)?
Mit LayoutManagern! Das ist Thema von Tag 3. Kurzfassung: Nutze BorderLayout, GridBagLayout oder BoxLayout statt fester Positionen.
Frage 5: Was ist der Unterschied zwischen setEnabled(false) und setEditable(false)?
setEnabled(false) → Die ganze Komponente ist deaktiviert (ausgegraut, nicht klickbar).setEditable(false) → Nur bei Textfeldern: Du kannst den Text lesen, aber nicht ändern.
Frage 6: Wie mache ich meinen eigenen Button mit eigenem Design?
Entweder: Look-and-Feel ändern (empfohlen).
Oder: Eigene Klasse von JButton erben und paintComponent() überschreiben (aufwändig, aber volle Kontrolle).
Frage 7: Bernd hat gesagt, er hätte 1999 eine Swing-App gebaut, die 50 Fenster gleichzeitig offen haben konnte. Wie geht das?
(Schmunzelt)
Jedes new JFrame() ist ein eigenständiges Fenster. Du kannst so viele erstellen, wie du willst. Ob du SOLLTEST, ist eine andere Frage.
Bernds Lagerverwaltung hat für jede Funktion ein eigenes Fenster. „Artikel anlegen“ – Fenster. „Lagerbestand prüfen“ – Fenster. „Lieferant bearbeiten“ – Fenster.
Heute würde man das mit Tabs oder einem Single-Window-Design lösen. Aber 1999 war das „modern“.
📦 Downloads
| Projekt | Für wen? | Download |
|---|---|---|
| java-anwendungsentwicklung-tag2.zip | 🟢 Alle | ⬇️ Download |
Inhalt:
HalloJFrame.java– Das absolute MinimumKomponentenDemo.java– Alle Komponenten in TabsMiniFormular.java– Vollständiges Registrierungsformular- FlatLaf Dark Theme
Quick Start:
# Standard-Demo (Komponenten) mvn exec:java # Erstes JFrame mvn exec:java -Phallo # Mini-Formular mvn exec:java -Pformular
🔗 Weiterführende Links
📚 Für Einsteiger
| Ressource | Beschreibung |
|---|---|
| Oracle Swing Tutorial | Das offizielle Tutorial |
| Java ist auch eine Insel – GUI | Deutsches Standardwerk |
🛠️ Tools
| Tool | Beschreibung |
|---|---|
| FlatLaf | Modernes Look-and-Feel |
| NetBeans GUI Builder | Visueller Designer |
| IntelliJ UI Designer | Visueller Designer |
📖 Referenz
| Ressource | Beschreibung |
|---|---|
| Swing Component Gallery | Alle Komponenten |
| How to Use Icons | Icons in Swing |
🎉 Tag 2 geschafft!
Was du heute gelernt hast:
✅ Der Unterschied zwischen AWT und Swing
✅ JFrame erstellen und konfigurieren
✅ Die wichtigsten Swing-Komponenten
✅ Warum SwingUtilities.invokeLater() PFLICHT ist
✅ Ein funktionierendes Formular bauen
Die wichtigste Regel:
Alle Swing-Komponenten beginnen mit „J“
Und IMMERSwingUtilities.invokeLater()verwenden!
🔜 Wie geht’s weiter?
Morgen – Tag 3: Layouts & Event-Handling
Heute hast du Komponenten kennengelernt. Morgen lernst du, wie man sie ANORDNET:
- BorderLayout, GridLayout, BoxLayout
- ActionListener, MouseListener, KeyListener
- Das Observer-Pattern in der Praxis
Bring dein Formular mit! Wir werden es mit Layouts verbessern.
Bis morgen!
— Franz-Martin
Fragen? Schreib uns:
- franz-martin@java-developer.online
Tags: #Java #Swing #AWT #GUI #JFrame #Komponenten #Anwendungsentwicklung
📚 Das könnte dich auch interessieren
© 2025 Java Fleet Systems Consulting | java-developer.online

