BufferedImage zurücksetzen funktioniert nicht

Hag2bard

Bekanntes Mitglied
Hallo,

ich bins mal wieder.

Ich möchte einen Map Editor bauen.
Dafür lade ich ein BufferedImage, wandel es in ein ImageIcon um und pack das in ein JLabel, pack das in ein JScrollPane und dies füge ich dem JFrame hinzu.
Nun habe ich eine Graphics2D Objekt erstellt um das BufferedImage anzumalen. In meinem Fall zeichnet er ein Rechteck um das ausgewählte Kästchen.
Sobald ich JFrame.repaint(); aufrufe, wird diese Änderung dann natürlich auch sichtbar.
Jetzt möchte ich mein BufferedImage wieder zum Original Zustand zurücksetzen.
Dafür habe ich ein zweites BufferedImages (final).

Wenn ich nun das angemalte BufferedImage (tileSetBufferedImage) mit dem Originalen ersetze (tileSetBufferedImageOriginal) mit diesem Befehl:
tileSetBufferedImageOriginal = tileSetBufferedImage; und dann repaint() aufrufe, wird dennoch das angemalte BufferedImage angezeigt.

Mein Code ist noch experimentell und nicht schön zu lesen:

Java:
package pokemon;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class PokeEditor extends JFrame {

    private String filename = "tileset-advance.png";
    BufferedImage tileSetBufferedImage;
    final BufferedImage tileSetBufferedImageOriginal;
    Graphics2D graphicstileSet;
    ImageIcon tileSetImageIcon;
    JLabel tileJLabel;
    JScrollPane tileJScrollPane;

    public PokeEditor() {
        try {
            tileSetBufferedImage = ImageIO.read(getClass().getResource(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        tileSetBufferedImageOriginal = tileSetBufferedImage;  //Hier erstelle ich das Original BufferedImage
        graphicstileSet = tileSetBufferedImage.createGraphics();

        tileSetImageIcon = new ImageIcon(tileSetBufferedImage);

        tileJLabel = new JLabel(tileSetImageIcon);
        tileJLabel.setBounds(0, 0, 128, 15971);
        tileJLabel.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int xCoordinateBlock = e.getPoint().x;
                int yCoordinateBlock = e.getPoint().y;
                xCoordinateBlock = xCoordinateBlock / 16;
                yCoordinateBlock = yCoordinateBlock / 16;
                System.out.println("Position X= " + xCoordinateBlock + " Position Y= " + yCoordinateBlock);
                resetTile();
                neu();
                graphicstileSet.drawRect(xCoordinateBlock * 16, yCoordinateBlock * 16, 16, 16);//; x,y,withd, height
                neu();

            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("Block wählen");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("Block nicht wählen");
            }
        });

        tileJScrollPane = new JScrollPane(tileJLabel);
        tileJScrollPane.setBounds(1387, 0, 150, 800);
        tileJScrollPane.getVerticalScrollBar().setUnitIncrement(20);

        this.add(tileJScrollPane);
        this.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("Bild laden bei Swing");
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setSize(1500, 860);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void neu() {
        this.repaint();
    }

    public void resetTile() {
        this.tileSetBufferedImage = this.tileSetBufferedImageOriginal;
        this.repaint();
    }
}

Was mach ich hier falsch?

Danke im Voraus
 

LimDul

Top Contributor
Wie schon im anderen Thread - ein JLabel zu benutzen um ein PNG über ein ImageIcon darzustellen ist eine gute Methode - wenn man sich selbst in den Fuss schießen will. Sinnvoller ist es direkt am dem Panel malen bzw. in ein BufferedImage zu malen und das darzustellen.

Dein "Orginal" ist kein Original sondern vermutlich mit geändert. Das ist das gleiche Objekt, du weißt es nur einer anderen Variable zu. Damit ist es aber immer noch das gleiche Objekt. Du müsstest es kopieren, also neu laden..
 

Hag2bard

Bekanntes Mitglied
Hallo,

es soll ein schon fertiges Bild im rechten Teil des Bildschirmes, also im JScrollPane dargestellt werden.
Ich zeichne nur zur Information, welches Feld geklickt wurde ein Viereck drum herum. (Also eine Art Auswahl)
Oder verstehe ich dich falsch und ich soll das ImageIcon direkt dem JScrollPane übergeben?

Ich glaube ich erinner mich dunkel an die ersten Tutorials von Java.
Die Variable tileSetBufferedImageOriginal zeigt auf das selbe Objekt wie tileSetBufferedImage, da es sich hier um keinen primitiven Datentyp handelt.
Danke für den Denkanstoß
 

Robert Zenz

Top Contributor
Das "ImageIcon" haelt eine Referenz auf das alte "BufferedImage", das hast du nicht geaendert. Auszerdem sind dein Originales und das geaenderte ein und die selbe Instanz.

Also. Nehmen wir folgendes vereinfachtes Szenario.

Java:
public class Painter {
    protected Image image = null;
    
    public Painter(Image image) {
        super();
        
        this.image = image;
    }
    
    public paint() {
        paiuntThisImage(image);
    }
}

// Logik

Image firstImage = createImage();
Image secondImage = firstImage;

Painter painter = new Painter(firstImage);

painter.paint(); // "firstImage" wird gezeichnet.

firstImage = secondImage;

painter.paint(); // "firstImage" wird gezeichnet. Referenz in "painter" hat sich nicht geaendert.

// Zusaetzlich:
secondImage.makeCompletelyRed();

painter.paint(); // "firstImage" wird gezeichnet, jetzt komplett rot weil gleiche Instanz wie "secondImage".

Also du musst das Bild beim zuruecksetzen am besten neu laden aus der Resource, und dann dem ImageIcon diese neue Instanze setzen.
 

LimDul

Top Contributor
Ich versuche mal das Vorgehen zu Beschreiben, das Objekt was im JScrollPane dargestellt werden soll ist ein JPanel. Und zwar genau eins.

Dort ist die paintComponent Methode überschrieben und in dieser Methode wird das Bild gemalt. Dafür gibt es interne Datenstrukturen was in der Tilemap an welcher Stelle ist und die werden dann entsprechend gezeichnet. Kein ImageIcon, kein JPanel, keine 100 Komponenten.

Der allererste Schritt ist sich das Datenmodell zu überlegen - und dieses Datenmodell sollte unabhängig von der GUI sein. Wie sind deine Daten zu der Tilemap intern abgelegt bei dir?
 

Hag2bard

Bekanntes Mitglied
Java:
    public void neu() {
        this.repaint();
        tileJScrollPane.repaint();
        tileJLabel.repaint();
    }

    public void resetTile() {
        try {
            tileSetBufferedImage = ImageIO.read(getClass().getResource(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        tileSetImageIcon = new ImageIcon(tileSetBufferedImage);
    }
}

Ich habe es jetzt so hier versucht, aber dennoch resetet er mein BufferedImage nicht.

@LimDul

Ich verstehe deine Aussage nicht. Ich frage mal so:

Ich habe ein Bild welches ich inklusive Scrollbalken in Java darstellen will. Wenn ich auf eine Koordinate klicke, soll das Bild an dieser Stelle angemalt werden mit einem Kästchen drumherum.
Warum darf ich das nicht in ein Container packen?

Wie soll ich sonst ein Bild in Java darstellen?

Vielleicht sagt ein Bild mehr als 1000 Worte:

Screenshot5.png
Hier im Bild sieht man auch was Java da macht: er malt ein Kästchen an, was ja erstmal genau so sein soll.
Beim nächsten Klick auf ein anderes Kästchen sollen die bereits angemalten Kästchen nicht mehr angemalt sein.
 

Robert Zenz

Top Contributor
Ich habe es jetzt so hier versucht, aber dennoch resetet er mein BufferedImage nicht.

Weil du jetzt den gleichen Fehler wieder machst, aber eine Klasse weiter. Jetzt ersetzt du die "ImageIcon" Instanz ohne den JPanel darueber zu informieren dass es eine neue Instanz gibt. Das gleich in ImageIcon.

Ruf auf dem bestehenden "ImageIcon" "setImage" auf um das im "ImageIcon" enthaltene Bild mit deinem neu geladenen zu ersetzen.
 

LimDul

Top Contributor
Du hast ein Datenmodell. Das Datenmodell sagt dir:
* Was an welcher Position ist
* Was z.B. Selektiert ist

Und gibt es eine Methode beim zeichnen die abfragt wenn "Position x/y" markiert, dann male ein Rechteck drum.

Alternativ kann man das auch mit Komponenten nutzen - aber dann kein JLabel sondern nackte JPanel.

Aber ich glaube, dass du dich vermutlich mit dem Projekt übernimmst, bei sowas größerem ist es wichtig auch die Architektur einigermaßen zu verstehen und eine Trennung zwischen Model & View zu haben, sonst kommt ein Haufen unwartbarer Spagetti Code raus.

Wie gesagt, das Datenmodell ist das was im ersten Schritt wichtig ist - und nicht die Darstellung im GUI.
 

LimDul

Top Contributor
Proof of Concept:
Java:
package de.limdul.javaforum;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class TileMapDemo extends JPanel implements MouseListener {

    private List<Image> tileGraphics = new ArrayList<>();

    private Image[][] tilemap = new Image[30][30];

    private int xSelected = -1, ySelected = -1;

    public static void main(String[] args) throws IOException {
        JFrame frame = new JFrame();
        TileMapDemo panel = new TileMapDemo();
        panel.addMouseListener(panel);
        panel.setFocusable(true);
        frame.add(new JScrollPane(panel));
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public TileMapDemo() throws IOException {
        BufferedImage image = ImageIO.read(getClass().getResourceAsStream("tile1.png"));
        Image scaledImage = image.getScaledInstance(50, 50, Image.SCALE_SMOOTH);
        tileGraphics.add(scaledImage);
        for (int i = 0; i < tilemap.length; i++) {
            for (int j = 0; j < tilemap[i].length; j++) {
                tilemap[i][j] = scaledImage;
            }
        }
        setPreferredSize(new Dimension(50 * tilemap.length, 50 * tilemap[0].length));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < tilemap.length; i++) {
            for (int j = 0; j < tilemap[i].length; j++) {
                if (tilemap[i][j] == null) {
                    continue;
                }
                g.drawImage(tilemap[i][j], i * 50, j * 50, null);
            }
        }
        if (xSelected != -1 && ySelected != -1) {
            g.setColor(Color.BLACK);
            g.drawRect(xSelected * 50, ySelected * 50, 50, 50);
            g.drawRect(xSelected * 50 - 1, ySelected * 50 - 1, 52, 52);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        xSelected = e.getX() / 50;
        ySelected = e.getY() / 50;
        repaint();
        System.err.println(xSelected);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }
}

1635260024952.png
 

Hag2bard

Bekanntes Mitglied
Super Code, davon werde ich mir auf jeden Fall was abgucken.
Aber ich versteh nicht so ganz, wann xSelected und ySelected wieder auf -1 zurückgesetzt werden. Das heißt er zeichnet nur einmal ein Kästchen drum herum, danach haben die beiden Variablen niemals mehr -1 als Wert. Oder täusche ich mich da?
 

mihe7

Top Contributor
Aber ich versteh nicht so ganz, wann xSelected und ySelected wieder auf -1 zurückgesetzt werden.
Nirgends. -1 ist einfach "nix ausgewählt", das ist halt am Anfang so, danach klickst Du mit der Maus rein und wählst was aus. Klickst Du woanders hin, wird was anderes ausgewählt. Warum sollte also die Auswahl wieder aufgehoben werden?
 

Hag2bard

Bekanntes Mitglied
Ok heißt dass, dass die super.paintComponent(g); Methode alles im Ursprungszustand zeichnet? Die if Bedingung in der for Schleife greift nach dem ersten mal zeichnen nicht mehr oder? Welches Graphics Objekt bekommt die Methode paintComponent?
 

LimDul

Top Contributor
Das ist nur ein Proof Concept, sprich nicht wirklich bis ins letzte ausdetailiert.

Man könnte das ja woanders wieder auf -1/-1 setzen. Bzw. sinnvollere wäre eh eine eigene Datenstruktur für die Tiles und dann ein Object Tile selectedTile. Aber das hätte den Rahmen gesprengt, den ich mal eben im Zug nebenbei tippen konnte :)

paintComponent ist die Methode, die man überschreiben will, wenn man auf einer Komponente was zeichnen will. Das Graphics Object, was man bekommt wird von swing erzeugt und ist so konfiguriert, dass man damit auf der Komponente zeichnet.

Hier die Doku dazu: https://docs.oracle.com/en/java/jav...ponent.html#paintComponent(java.awt.Graphics)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Arbeitsspeicherverbrauch BufferedImage.TYPE_INT_RGB vs. TYPE_3BYTE_BGR AWT, Swing, JavaFX & SWT 6
L AWT Ändern der Farbe eines BufferedImage mit Farbähnlichkeit AWT, Swing, JavaFX & SWT 5
I GEmaltes BufferedImage löschen AWT, Swing, JavaFX & SWT 3
cool_brivk24 BufferedImage einem ClickEvent hinzufügen AWT, Swing, JavaFX & SWT 13
cool_brivk24 AWT BufferedImage wird nicht geladen AWT, Swing, JavaFX & SWT 17
J linken Bildausschnitt eines BufferedImage abschneiden AWT, Swing, JavaFX & SWT 4
Zar von Domarus JFrame zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 3
S 2D-Grafik User-BufferedImage rotieren im Zentrum und ohne "anpassung" AWT, Swing, JavaFX & SWT 2
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
G Subimage von BufferedImage speichern AWT, Swing, JavaFX & SWT 4
D JPanel Graphic2D als BufferedImage Speichern AWT, Swing, JavaFX & SWT 5
D BufferedImage -> Feature Extraktion. Unterschiedliche BufferedImage imageTypes problem AWT, Swing, JavaFX & SWT 4
I 2D-Grafik Shape aus BufferedImage "löschen" AWT, Swing, JavaFX & SWT 2
M 2D-Grafik LookupOp Operation auf BufferedImage AWT, Swing, JavaFX & SWT 7
GianaSisters 2D-Grafik BufferedImage.getSubimage - Frage AWT, Swing, JavaFX & SWT 7
P BufferedImage schlechte Qualität beim Abspeichern AWT, Swing, JavaFX & SWT 9
S BufferedImage als schwarz-weiß-Bild AWT, Swing, JavaFX & SWT 3
Luk10 BufferedImage[...].getData() vs BufferedImage.setRGB() AWT, Swing, JavaFX & SWT 2
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
J Flackern wie mit BufferedImage beheben AWT, Swing, JavaFX & SWT 4
N Swing BufferedImage neu laden AWT, Swing, JavaFX & SWT 10
N 2D-Grafik BufferedImage, Line2D, Swing und die Probleme AWT, Swing, JavaFX & SWT 5
Luk10 BufferedImage auf ein anderes BufferedImage zeichnen AWT, Swing, JavaFX & SWT 6
P BufferedImage auf JPanel AWT, Swing, JavaFX & SWT 11
K 2D-Grafik BufferedImage eingelesen, welches Modell?! AWT, Swing, JavaFX & SWT 2
T BufferedImage bei paintComponent AWT, Swing, JavaFX & SWT 6
C 2D-Grafik BufferedImage laden, Frage zum Code AWT, Swing, JavaFX & SWT 2
0x7F800000 2D-Grafik int[] zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 27
H 2D-Grafik BufferedImage aus Integer-Array AWT, Swing, JavaFX & SWT 3
Luk10 2D-Grafik BufferedImage sauber rotieren AWT, Swing, JavaFX & SWT 16
P Image mehrfach in ein BufferedImage zeichnen AWT, Swing, JavaFX & SWT 7
A BufferedImage nach dem Speichern immer schwarz AWT, Swing, JavaFX & SWT 8
J Bild aus Datei in BufferedImage laden AWT, Swing, JavaFX & SWT 4
E BufferedImage Alphaknal ein- und ausblenden AWT, Swing, JavaFX & SWT 7
N BufferedImage zeichnen AWT, Swing, JavaFX & SWT 4
D BufferedImage Größe skalieren AWT, Swing, JavaFX & SWT 2
P Swing Vom BufferedImage bei paintComponent nur soviel zeichnen, wie nötig AWT, Swing, JavaFX & SWT 3
B 2D-Grafik BufferedImage Performance AWT, Swing, JavaFX & SWT 3
Y frage zu BufferedImage AWT, Swing, JavaFX & SWT 7
E AWT RenderedImage aus BufferedImage erzeugen, um Bild abzuspeichern? AWT, Swing, JavaFX & SWT 4
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
A 2D-Grafik BufferedImage wird nicht eingezeichnet AWT, Swing, JavaFX & SWT 3
G 2D-Grafik BufferedImage Hintergrund immer schwarz AWT, Swing, JavaFX & SWT 4
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
J AWT BufferedImage to 2DArray AWT, Swing, JavaFX & SWT 10
R Bild drehen UND skalieren (Image bzw BufferedImage) AWT, Swing, JavaFX & SWT 5
J JPanel in Bufferedimage AWT, Swing, JavaFX & SWT 3
1 BufferedImage in byte[], dann in String und zurück AWT, Swing, JavaFX & SWT 7
J Swing paintComponent() - repaint() - BufferedImage anzeigen AWT, Swing, JavaFX & SWT 5
C BufferedImage-Fehler? Falsches Bild wir gezeichnet AWT, Swing, JavaFX & SWT 5
B BufferedImage Builder AWT, Swing, JavaFX & SWT 15
F Transparentes BufferedImage über BufferedImage AWT, Swing, JavaFX & SWT 12
F Größe von BufferedImage ändern AWT, Swing, JavaFX & SWT 27
I Swing JComponent als BufferedImage speichern AWT, Swing, JavaFX & SWT 18
Dragonfire Swing Zoom-Vorgang optimieren [BufferedImage] AWT, Swing, JavaFX & SWT 2
2 Memory Leak mit BufferedImage !! AWT, Swing, JavaFX & SWT 15
X BufferedImage maximiert in JFrame anzeigen? AWT, Swing, JavaFX & SWT 2
R JPanel - BufferedImage - zeichnen großer Bilder AWT, Swing, JavaFX & SWT 2
R JTable - TableCellRenderer - BufferedImage AWT, Swing, JavaFX & SWT 9
D BufferedImage und Graphics2D AWT, Swing, JavaFX & SWT 3
R Zeichnen von Zahlen in BufferedImage AWT, Swing, JavaFX & SWT 6
G BufferedImage.getRGB() mit 3 int-Werten vergleichen AWT, Swing, JavaFX & SWT 2
Luma BufferedImage wird nicht gezeichnet AWT, Swing, JavaFX & SWT 3
G keine ScaledInstance von BufferedImage? AWT, Swing, JavaFX & SWT 6
S BufferedImage & Scaling: Altes Problem im neuen Gewand AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
G BufferedImage und jpg --> maximale Qualität AWT, Swing, JavaFX & SWT 9
F HTML Text irgendwie auf BufferedImage bringen AWT, Swing, JavaFX & SWT 3
R BufferedImage Problem AWT, Swing, JavaFX & SWT 2
G Problem mit BufferedImage und imageIO AWT, Swing, JavaFX & SWT 2
S BufferedImage drehen AWT, Swing, JavaFX & SWT 3
? ActionListener auf BufferedImage AWT, Swing, JavaFX & SWT 11
M BufferedImage mit html interpretierten String beschriften AWT, Swing, JavaFX & SWT 3
A Probelme mit großen BufferedImage in paintComponent AWT, Swing, JavaFX & SWT 7
B Farbtiefe eines BufferedImage verringern AWT, Swing, JavaFX & SWT 3
F ImageIcon -> BufferedImage AWT, Swing, JavaFX & SWT 2
T Performance Problem bei BufferedImage AWT, Swing, JavaFX & SWT 3
F Animiertes Gif als BufferedImage AWT, Swing, JavaFX & SWT 10
L Anzeigen von fotos: ImageIcon oder BufferedImage + paint() ? AWT, Swing, JavaFX & SWT 5
C Rotate BufferedImage --> Bild unvollständig AWT, Swing, JavaFX & SWT 5
U Streifen hinter bewegtem BufferedImage AWT, Swing, JavaFX & SWT 13
M BufferedImage skalieren AWT, Swing, JavaFX & SWT 6
T BufferedImage verkleinern Resultat ist zu pixelig. AWT, Swing, JavaFX & SWT 6
G Image Object speichern oder in ein BufferedImage umwandeln AWT, Swing, JavaFX & SWT 2
P Problem beim Zeichnen auf ein BufferedImage AWT, Swing, JavaFX & SWT 4
B BufferedImage aus einer Datei AWT, Swing, JavaFX & SWT 4
C Farben in BufferedImage ändern ? AWT, Swing, JavaFX & SWT 2
J Image to BufferedImage AWT, Swing, JavaFX & SWT 5
T BufferedImage kopieren AWT, Swing, JavaFX & SWT 3
T BufferedImage Farbe "Transparent" AWT, Swing, JavaFX & SWT 21
T BufferedImage + bestimmten bereich ausfüllen AWT, Swing, JavaFX & SWT 3
M BufferedImage Größe? AWT, Swing, JavaFX & SWT 10
U Löschen eines BufferedImage AWT, Swing, JavaFX & SWT 7
J Image aus BufferedImage ohne AWT AWT, Swing, JavaFX & SWT 5
V Image in BufferedImage AWT, Swing, JavaFX & SWT 3
J BufferedImage aus byte-Array erstellen AWT, Swing, JavaFX & SWT 3
Zeppi Swing Button soll Spiel zurücksetzen AWT, Swing, JavaFX & SWT 5
M Swing JTable zurücksetzen AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben