Skip to content
This repository was archived by the owner on Nov 7, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is loosely inspired by Keep a Changelog.

### Changed

- **Web 0.15.9, small quizzes in the Swing lessons and two VisuBot fixes:** L29–L41 (Swing up to MVC) each get one multiple-choice question inside a central step (e.g. the dot in `fenster.setSize`, the `e` in the arrow, attribute, `setBackground`, division by 0, `append`, who the model talks to), de/en/pt, no repeats of the final quiz. VisuBot „Sensoren abfragen“ now briefly shows the branch as `if`/`else` in Java before it is used later. The bomb round in „Abstand messen“ no longer uses `else if` (only introduced later), two separate `if` instead.
- **Web 0.15.8, VisuBot: PAP and pseudocode:** new robot lesson „PAP und Pseudocode“ (`02-quadrat-als-pap.md`, de/en) right after „Das Quadrat“: flowchart symbols, spaghetti-code warning, exercise „Das Quadrat als PAP“ (`::: pap`, arrow back up for the loop, output in the parallelogram), the square as pseudocode and in Java, comparison of the three, Angeberwissen about Lillian and Frank Gilbreth (process charts, 1921), link to the VisuStruct lesson, game „Welche Darstellung?“, checklist and quiz. VisuBot now has 35 lessons; later numbers move up by one. „Wie geht es weiter?“ no longer lists PAP as missing.
- **Web 0.15.7, VisuBot ends with „Wie geht es weiter?“:** new last robot lesson (`23-wie-geht-es-weiter.md`, de/en, own part „Ausblick“/„Outlook“, VisuBot now has 34 lessons): a look back at the basics learned with the mBot2, a last „Warum läuft das nicht?“ (`mbot.getDistance` without brackets, three walls), and „Was noch fehlt“ with links to the VisuStruct lessons that VisuBot does not cover (PAP and pseudocode, keyboard input, 2D arrays, searching and sorting, Python/JavaScript, try/catch, files, Swing up to MVC). Game „Welche Welt?“ (VisuBot or VisuStruct, eight rounds), checklist and quiz. Test: five parts, the outlook is last.
- **Web 0.15.6, VisuBot: structured programming basics, step by step:** six new beginner robot lessons (de/en), inserted by file name without renaming (the series now has 33 lessons): „Zählen und Summieren“ after do-while (counter and sum pattern, exercises „Schritte bis zur Wand“ in three worlds and Java „Spirale mit Strecke“), „Feste Werte mit final“ after the ultrasonic sensor (constants, `const`/`final`, „Wand mit Konstante“, Java „Quadrat mit Konstante“), „Nah, mittel oder weit?“ (three cases, `else if`, order of conditions; „Tempo nach Abstand“, Java „Tag oder Nacht?“), „Der größte Wert“ after colours (maximum with desk-check table, new worlds `platz-1`/`platz-2`, „Wo ist am meisten Platz?“, Java „Die Richtung merken“), „Ein Merker mit boolean“ after the light sensor („Wurde es dunkel?“, Java „Wurde geklatscht?“) and „Zustände: Was mache ich gerade?“ after stopwatch/battery (state machine, Robo-Ampel with switch, Java with String states and `.equals`). Each lesson has competencies, a game, a „Warum läuft das nicht?“ exercise, a checklist and a quiz. Glossary: Merker/flag, Zustandsautomat/state machine.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/28-erstes-fenster.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ Der Punkt in `fenster.setSize(…)` bedeutet: „Fenster, mach das!“ Vor dem P

> Ohne `setDefaultCloseOperation` versteckt Java das Fenster beim Schließen nur. Das Programm läuft dann unsichtbar weiter.

::: quiz
? Was bedeutet der Punkt in `fenster.setSize(300, 200)`?
- [x] „Fenster, mach das!“: Vor dem Punkt steht, wer etwas tut, dahinter, was es tut.
- [ ] Er trennt die beiden Zahlen.
- [ ] Er beendet die Zeile.
> Vor dem Punkt steht das Objekt `fenster`, dahinter seine Methode `setSize`.
:::

## Warum setVisible am Ende steht

`setVisible(true)` zeigt das Fenster so, wie es in diesem Moment ist. Deshalb richtest du zuerst alles ein: Titel, Größe, später auch Knöpfe. Erst ganz am Ende machst du das Fenster sichtbar.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/29-knopf-im-fenster.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ fenster.add(knopf);
- `new JButton("Klick mich")` baut einen Knopf. Der Text in Klammern steht später auf dem Knopf.
- `fenster.add(knopf)` legt den Knopf ins Fenster. Ohne `add` gibt es den Knopf zwar, aber er liegt nirgends und du siehst ihn nicht.

::: quiz
? Was steht auf dem Knopf nach `new JButton("Start")`?
- [ ] knopf
- [x] Start
- [ ] JButton
> Der Text in Klammern ist die Beschriftung. `knopf` ist nur der Name der Variable.
:::

## Das ganze Programm

Beide Zeilen kommen **vor** `setVisible(true)`, denn das Fenster soll erst fertig eingerichtet und dann gezeigt werden:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/30-der-knopf-reagiert.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ Von außen nach innen gelesen:

Die Zeile steht nach `new JButton(…)`, denn den Knopf muss es schon geben. Und wie alles andere kommt sie vor `setVisible(true)`.

::: quiz
? Wofür steht das `e` in `e -> knopf.setText(…)`?
- [x] Für das Ereignis, also den Klick
- [ ] Für „Ende“
- [ ] Für einen Fehler
> Hier brauchst du `e` nicht, aber der Name muss dastehen.
:::

## Das ganze Programm

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/31-zahl-verdoppeln.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ Statt eines Fehlers in der Konsole sieht man jetzt einen Hinweis im Fenster.
Der Pfeil hat schon ein `e` für das Ereignis. Deshalb braucht die Exception im `catch` einen anderen Namen, hier `fehler`. Zwei Variablen mit demselben Namen erlaubt Java nicht.
:::

::: quiz
? Warum heißt die Exception im `catch` hier `fehler` und nicht `e`?
- [ ] `catch` verlangt immer den Namen `fehler`.
- [x] `e` ist schon das Ereignis des Pfeils, und zwei Variablen mit demselben Namen erlaubt Java nicht.
- [ ] `e` ist nur für Zahlen erlaubt.
> Den Namen darfst du frei wählen, nur nicht doppelt.
:::

## Spiel: Was steht danach im Fenster?

::: spiel frage
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/32-klickzaehler.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ public class Zaehler {
- `static` heißt: Die Variable gehört zur Klasse selbst. Weil `main` auch `static` ist, braucht es das hier.
- Eine solche Variable nennt man **Attribut** der Klasse. Sie lebt so lange wie das Programm, nicht nur so lange wie `main`.

::: quiz
? Wie nennt man eine Variable, die direkt in der Klasse steht und nicht in `main`?
- [ ] Parameter
- [x] Attribut
- [ ] Zuhörer
> Ein Attribut lebt so lange wie das Programm, nicht nur so lange wie `main`.
:::

## Das ganze Programm

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/33-ampel.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ licht.setBackground(Color.RED);
`opaque` ist englisch für „undurchsichtig“. Eine Beschriftung ist normalerweise durchsichtig wie Schrift auf einer Glasscheibe. Erst mit `setOpaque(true)` bekommt sie eine eigene Fläche, die man anmalen kann.
:::

::: quiz
? Welche Zeile malt den Hintergrund der Beschriftung `licht` grün an?
- [ ] `licht.setText(Color.GREEN);`
- [x] `licht.setBackground(Color.GREEN);`
- [ ] `licht.setColor("grün");`
> Die Hintergrundfarbe setzt `setBackground`. Damit man sie sieht, braucht ein `JLabel` vorher `setOpaque(true)`.
:::

## Sich die Farbe merken

Damit die Ampel weiß, was als Nächstes kommt, merkt sie sich ihren Zustand in einer Zahl: 0 heißt Rot, 1 heißt Grün, 2 heißt Gelb. Wie beim Klickzähler aus Lektion 32 steht die Variable in der Klasse, damit der Zuhörer sie ändern darf:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/34-notenrechner.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ Bei 85 Punkten ist `punkte >= 92` falsch, aber `punkte >= 81` wahr. Also Note 2,

Du kannst diesen Teil ohne Fenster im Bereich [Code](#zeige-codelive) ausprobieren. Schreib `int punkte = 85;` davor und `System.out.println("Note: " + note);` dahinter. Das Struktogramm zeigt dir die verschachtelten Verzweigungen.

::: quiz
? Welche Note ergibt der Schlüssel bei 29 Punkten?
- [ ] 4
- [ ] 5
- [x] 6
> Alle Bedingungen sind falsch, auch `punkte >= 30`. Dann gilt der `else`-Zweig.
:::

## Das Fenster

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/35-taschenrechner.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ geteilt.addActionListener(e -> {
Mit `double` und `Double.parseDouble(…)` gibt es Nachkommastellen: 7 / 2 ergibt 3.5. Dafür wirft Java bei Kommazahlen keine Exception beim Teilen durch 0. Das Ergebnis heißt dann `Infinity`, also „unendlich“.
:::

::: quiz
? Was zeigt der Rechner bei 8 geteilt durch 0?
- [ ] 0
- [ ] Infinity
- [x] Nicht durch 0!
> Mit `int` wirft `a / b` eine `ArithmeticException`. Das `catch` fängt sie ab und zeigt den Hinweis.
:::

## Eine eigene Methode

Das steht nicht im Lehrplan, macht den Code aber kürzer.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/36-zahlenraten.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ static int geheim = (int) (Math.random() * 100) + 1;
static int versuche = 0;
```

::: quiz
? Warum stehen `geheim` und `versuche` in der Klasse und nicht in `main`?
- [ ] Weil `Math.random()` nur in der Klasse funktioniert
- [x] Weil sie über alle Klicks erhalten bleiben und der Zuhörer `versuche` ändern muss
- [ ] Weil `main` keine Zahlen speichern kann
> Wie beim Klickzähler: Variablen aus `main` darf der Zuhörer nicht verändern.
:::

## Das ganze Programm

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/37-viele-knoepfe-ein-zuhoerer.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ for (int i = 1; i <= 9; i++) {
- In jedem Durchlauf entsteht ein neuer Knopf. Alle bekommen denselben Zuhörer `taste`.
- `fenster.add(tasten, BorderLayout.CENTER)` setzt die ganze Fläche mit allen Tasten ins Fenster.

::: quiz
? Wie viele Knöpfe und wie viele Zuhörer entstehen in dieser Schleife?
- [ ] 9 Knöpfe und 9 Zuhörer
- [x] 9 Knöpfe und 1 Zuhörer
- [ ] 1 Knopf und 9 Zuhörer
> In jedem Durchlauf kommt ein neuer Knopf dazu. Alle bekommen denselben Zuhörer `taste`.
:::

## Das ganze Programm

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/38-innere-klassen.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ plus.addActionListener(new ActionListener() {
- Am Ende steht `});`: die geschweifte Klammer schließt die Klasse, die runde den Aufruf von `addActionListener`.
- Die anonyme Klasse steht **in** `main`. Sie sieht deshalb auch die Variablen von `main`, solange diese sich nicht mehr ändern.

::: quiz
? Was schließt `});` am Ende der anonymen Klasse?
- [x] `}` schließt die Klasse, `)` den Aufruf von `addActionListener`.
- [ ] `}` schließt `main`, `)` die Klasse.
- [ ] Beides schließt die Methode `actionPerformed`.
> Die Methode `actionPerformed` endet schon eine Zeile davor mit ihrer eigenen `}`.
:::

## 3. Das Lambda

Das Lambda ist die Kurzform der anonymen Klasse, seit Java 8:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/39-zwei-reiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ bereich.append("Heu\n");
- `setEditable(false)` verhindert, dass man in der Liste selbst herumtippt.
- `getText()` liefert den ganzen Text mit allen Zeilen.

::: quiz
? Was macht `bereich.append("Heu\n")`?
- [ ] Es ersetzt den ganzen Text durch „Heu“.
- [x] Es hängt „Heu“ hinten an und beginnt danach eine neue Zeile.
- [ ] Es schreibt „Heu\n“ genau so in die Liste.
> `append` hängt an, `"\n"` ist der Zeilenumbruch.
:::

## Von einem Reiter zum anderen

Der Knopf **Hinzufügen** steht im Reiter Eingabe, der Textbereich im Reiter Liste. Trotzdem kann der Zuhörer beide benutzen. Alle Bausteine sind Variablen in `main`, und das Lambda sieht sie alle, egal auf welchem Reiter sie später angezeigt werden:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/de/40-model-view-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ Das Model redet mit niemandem. Es wartet, bis es gefragt wird.
Merk dir: Das Model weiß nichts von Fenstern. In `Zaehler` steht kein einziges `JLabel` und kein `import javax.swing`. Wenn du dort Swing brauchst, gehört der Code in die View.
:::

::: quiz
? Mit wem redet das Model von sich aus?
- [ ] Mit der View
- [ ] Mit dem Knopf
- [x] Mit niemandem
> Das Model wartet, bis der Controller es fragt.
:::

## Der Gewinn: eine zweite View

Jetzt soll der Zählerstand zusätzlich als Balken erscheinen. Dafür kommt eine zweite View dazu. Ein `JProgressBar` ist ein Balken, der sich füllt, hier von 0 bis 10:
Expand Down
12 changes: 12 additions & 0 deletions web/lessons/de/visubot/04-sensoren.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ tipp: Im true-Zweig steht `mbot.turnRight()`, im false-Zweig `mbot.forward()`.
lösung: vb-wand-vorn-loesung.visustruct
:::

Im Bereich [Code](#zeige-codelive) siehst du dein Struktogramm auch als Java. Eine Verzweigung heißt dort **if**, der false-Zweig **else**. Die Bedingung steht in runden Klammern, jeder Zweig in geschweiften Klammern:

```java
if (mbot.getDistance() < 20) {
mbot.turnRight();
} else {
mbot.forward();
}
```

> Selbst tippen musst du `if` noch nicht. Mehr dazu kommt in der Lektion über den Ultraschallsensor.

## Was liefert der Sensor?

Ein Sensor liefert einen **Wert**, so wie eine Variable. Fährt der mBot2 weiter, ändert sich der Wert: Der Abstand wird kleiner, je näher die Wand kommt. Erst ein **Vergleich** macht aus dem Wert eine Frage mit der Antwort `true` (wahr) oder `false` (falsch).
Expand Down
3 changes: 2 additions & 1 deletion web/lessons/de/visubot/06-abstand.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ zeit: 30
runde:
if (mbot.getDistance() < 10) {
mbot.forward();
} else if (mbot.getDistance() > 20) {
}
if (mbot.getDistance() > 20) {
mbot.forward();
}
frage: Unter 10 cm soll er zurückfahren, über 20 cm vorfahren.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/28-erstes-fenster.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ The dot in `window.setSize(…)` means: “Window, do this!” Before the dot is

> Without `setDefaultCloseOperation`, Java only hides the window when it is closed. The program then keeps running invisibly.

::: quiz
? What does the dot in `window.setSize(300, 200)` mean?
- [x] “Window, do this!”: before the dot is who does something, after it what they do.
- [ ] It separates the two numbers.
- [ ] It ends the line.
> Before the dot is the object `window`, after it its method `setSize`.
:::

## Why setVisible comes last

`setVisible(true)` shows the window exactly as it is at that moment. So you set everything up first: title, size, and later buttons too. Only at the very end do you make the window visible.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/29-knopf-im-fenster.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ window.add(button);
- `new JButton("Click me")` builds a button. The text in brackets will be written on the button.
- `window.add(button)` puts the button into the window. Without `add` the button exists, but it is not placed anywhere and you cannot see it.

::: quiz
? What is written on the button after `new JButton("Start")`?
- [ ] button
- [x] Start
- [ ] JButton
> The text in brackets is the label. `button` is only the name of the variable.
:::

## The whole program

Both lines go **before** `setVisible(true)`, because the window should be set up completely first and then shown:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/30-der-knopf-reagiert.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ Read from the outside in:

The line comes after `new JButton(…)`, because the button has to exist already. And like everything else it comes before `setVisible(true)`.

::: quiz
? What does the `e` in `e -> button.setText(…)` stand for?
- [x] The event, that is the click
- [ ] “End”
- [ ] An error
> You do not need `e` here, but the name has to be there.
:::

## The whole program

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/31-zahl-verdoppeln.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ Instead of an error in the console, you now see a hint in the window.
The arrow already has an `e` for the event. That is why the exception in `catch` needs a different name, here `error`. Java doesn't allow two variables with the same name.
:::

::: quiz
? Why is the exception in `catch` called `error` here and not `e`?
- [ ] `catch` always needs the name `error`.
- [x] `e` is already the event of the arrow, and Java does not allow two variables with the same name.
- [ ] `e` is only allowed for numbers.
> You can choose the name freely, just not twice.
:::

## Game: What is in the window afterwards?

::: spiel frage
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/32-klickzaehler.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ public class Counter {
- `static` means: the variable belongs to the class itself. Because `main` is `static` too, it is needed here.
- A variable like this is called a **field** of the class. It lives as long as the program, not just as long as `main`.

::: quiz
? What do you call a variable that sits directly in the class and not in `main`?
- [ ] A parameter
- [x] A field
- [ ] A listener
> A field lives as long as the program, not just as long as `main`.
:::

## The whole program

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/33-ampel.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ light.setBackground(Color.RED);
`opaque` means “not see-through”. A label is normally transparent, like writing on a pane of glass. Only with `setOpaque(true)` does it get its own area that can be painted.
:::

::: quiz
? Which line paints the background of the label `light` green?
- [ ] `light.setText(Color.GREEN);`
- [x] `light.setBackground(Color.GREEN);`
- [ ] `light.setColor("green");`
> `setBackground` sets the background colour. To see it, a `JLabel` first needs `setOpaque(true)`.
:::

## Remembering the colour

So that the traffic light knows what comes next, it remembers its state in a number: 0 means red, 1 means green, 2 means yellow. As with the click counter from lesson 32, the variable is in the class so that the listener may change it:
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/34-notenrechner.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ With 85 points, `points >= 90` is false, but `points >= 80` is true. So grade B,

You can try this part without a window in the [Code](#zeige-codelive) area. Put `int points = 85;` in front of it and `System.out.println("Grade: " + grade);` after it. The structure chart shows you the nested branches.

::: quiz
? Which grade does the key give for 29 points?
- [ ] 4
- [ ] 5
- [x] 6
> All conditions are false, even `points >= 30`. Then the `else` branch applies.
:::

## The window

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/35-taschenrechner.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ divide.addActionListener(e -> {
With `double` and `Double.parseDouble(…)` you get decimal places: 7 / 2 gives 3.5. In return, Java throws no exception when dividing decimal numbers by 0. The result is then `Infinity`.
:::

::: quiz
? What does the calculator show for 8 divided by 0?
- [ ] 0
- [ ] Infinity
- [x] Not by 0!
> With `int`, `a / b` throws an `ArithmeticException`. The `catch` catches it and shows the message.
:::

## A method of your own

This is not in the curriculum, but it makes the code shorter.
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/36-zahlenraten.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ static int secret = (int) (Math.random() * 100) + 1;
static int guesses = 0;
```

::: quiz
? Why are `secret` and `guesses` in the class and not in `main`?
- [ ] Because `Math.random()` only works in the class
- [x] Because they must last over all clicks and the listener has to change `guesses`
- [ ] Because `main` cannot store numbers
> Like in the click counter: the listener must not change variables from `main`.
:::

## The whole program

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/37-viele-knoepfe-ein-zuhoerer.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ for (int i = 1; i <= 9; i++) {
- Each pass creates a new button. All of them get the same listener `key`.
- `window.add(keys, BorderLayout.CENTER)` puts the whole area with all the keys into the window.

::: quiz
? How many buttons and how many listeners does this loop create?
- [ ] 9 buttons and 9 listeners
- [x] 9 buttons and 1 listener
- [ ] 1 button and 9 listeners
> Each pass adds a new button. All of them get the same listener `key`.
:::

## The whole program

```java
Expand Down
8 changes: 8 additions & 0 deletions web/lessons/en/38-innere-klassen.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ plus.addActionListener(new ActionListener() {
- At the end there is `});`: the curly bracket closes the class, the round one closes the call to `addActionListener`.
- The anonymous class is **inside** `main`. So it also sees the variables of `main`, as long as they don't change any more.

::: quiz
? What does `});` close at the end of the anonymous class?
- [x] `}` closes the class, `)` closes the call of `addActionListener`.
- [ ] `}` closes `main`, `)` closes the class.
- [ ] Both close the method `actionPerformed`.
> The method `actionPerformed` already ends one line earlier with its own `}`.
:::

## 3. The lambda

The lambda is the short form of the anonymous class, since Java 8:
Expand Down
Loading
Loading