Nach dem Öffnen des Dialogs eine Aktion ausführen.

beastofchaos

Bekanntes Mitglied
Hallo Leute,
Ich dachte ich schreibe mal für die ganzen komplexen Vorgänge in meinem Programm einen Dialog, welcher ein Laden-GIF-Icon anzeigt während die Aktion getätigt wird.
Die Aktion an sich soll einfach über ein Runnable-Objekt beim Öffnen des Dialogs ausgeführt werden.
Mein Dialog stamtm wie gewohnt von JDialog ab und enthält die beiden Attribute "labelLoad" und "iconLoading", um einen Text und zweitens das GIF-Icon anzuzeigen.

Um unnötig viele Dialog zu verhindern hab ich den Konstruktor privat definiert, eine private statische Instanz hinzugefügt und veranlasst, dass der Dialog nur erzeugt werden kann, wenn sich die Attribute "owner" und "title" zur alten Instanz unterschiedlich sind.

Java:
public static void createDialogInstane(JFrame owner, String title)
	{
		if (instance == null || !instance.getOwner().equals(owner)
				|| !instance.getTitle().equals(title))
		{
			instance = new DLoad(owner, title);
		}
	}

Der Dialog wird dann mit dem Inhalt des Labels und dem Runnable-Objekt geöffnet
Java:
public static void showDialog(String loadMessage, Runnable runnableAction)
	{
		if (instance == null)
		{
			throw new NullPointerException(
					"Dialog instance has to be created before trying open it!");
		}
		else
		{
			instance.runnableAction = runnableAction;
			instance.labelLoad.setText("<html>" + loadMessage + "<br>&nbsp;</html>");

			instance.setVisible(true);
		}
	}

Im Konstruktor meines Dialogs wird ein WindowListener hinzugefügt über den in "windowOpened" die Run-Methode ausgeführt wird und anschließend der Dialog wieder geschlossen wird.

Wenn ich den Spaß jetzt nutzen will, wird beim ersten Mal die GIF nicht angezeigt, aber der Dialog wird zum Glück nach ein paar Sekunden geschlossen(wenn die Aktion durchgeführt ist). Wenn ich die gleiche Aktion nochmal ausführen will, wird der Dialog geöffnet und diesmal wird die GIF angezeigt, aber der Dialog schließt sich nicht mehr. Beide Male wird dieselbe Instanz benutzt

Problem 1 -> Beim ersten Aufruf scheint die Anzeige einer GIF im Label nicht zu funktionieren
Problem 2 -> Bei allen weiteren wird der WindowListener nicht mehr aufgerufen.

Idee zu 1. -> repaint()-Methode nach dem Konstruieren direkt aufrufen -> kein Effekt
Idee zu 2. -> "windowOpened" wird nur aufgerufen, wenn der Dialog zum ersten Mal geöffnet wird.

Habt ihr zu den beiden Problemen eine Idee, die ich ausprobieren könnte?

Es muss ja nicht über den WindowListener laufen. Bloß wie könnte ich sonst eine Aktion nach dem Aufruf von "setVisible(true)" ausführen. Schließlich blockt "setVisible(true)" bei einem Dialog diesen Thread.

Gruß, Thomas
 

Michael...

Top Contributor
Mein Dialog stamtm wie gewohnt von JDialog ab und enthält die beiden Attribute "labelLoad" und "iconLoading", um einen Text und zweitens das GIF-Icon anzuzeigen.
Blos weil man einen Dialog anzeigen will ist es meiner Meinung nach nicht gerechtfertigt von JDialog zu erben. Bau Dir doch eine Hilfsklasse die das ganze behandelt und steuert.
Bloß wie könnte ich sonst eine Aktion nach dem Aufruf von "setVisible(true)" ausführen. Schließlich blockt "setVisible(true)" bei einem Dialog diesen Thread.
Die Aktion bzw. der Thread muss natürlich gestartet werden bevor setVisible(true) auf dem JDialog aufgerufen wird.

Zu Deinem Problem kann ich nicht viel sagen, weder sieht man hier etwas von einem Icon noch wie das Zusammenspiel zwischen Thread starten und Dialog anzeigen ausschaut. Ein KSKB wäre nicht schlecht.
 

beastofchaos

Bekanntes Mitglied
main-Methode:
Java:
public static void main(String[] args)
	{
		// Hauptfenster und Dialog erzeugen
		JFrame frame = new JFrame("Custom tool tip with icon");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(400, 400);
		frame.setLocationRelativeTo(null);
		DLoad.createDialogInstane(frame, "Laden...");

		// Fenster und Dialog nacheinander öffnen. Die Dauer der Aktion wird per "sleep(1000)" simliert
		frame.setVisible(true);
		DLoad.showDialog("Lade Dialog....", new Runnable()
		{
			@Override
			public void run()
			{
				System.out.println("RUN");
				try
				{
					Thread.sleep(1000); // Hier würde die Aktion stehen, welche ausgeführt werden soll.
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		});
		
		// Testweise ein zweites Mal aufrufen
		DLoad.showDialog("Lade Dialog....", new Runnable()
		{
			@Override
			public void run()
			{
				System.out.println("RUN");
				try
				{
					Thread.sleep(1000);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		});
	}

Die Dialog-Klasse:
Java:
package dialogs;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;

import management.CursorAdmin;
import designs.ImageDesign;

/**
 * <strong>DLoad extends JDialog</strong><br>
 * <br>
 * Zeigt eine Lade-Anzeige mit einem Text darunter, welcher beim Öffnen des
 * Dialogs gesetzt wird. <br>
 * <br>
 * Der Dialog ist nur solange offen, wie die Run-Methode ausgeführt wird.
 * 
 * @author Thomas Kellermeier
 */
@SuppressWarnings("serial")
public final class DLoad extends JDialog
{

	// ------Attribute----------------------------------------------------------------------------------------------//

	/**
	 * Zeigt den Text an, welcher beim Öffnen des Dialogs angezeigt wird.
	 * Der Text erscheint direkt unter dem Gif-Icon und ist von <html>-Tags
	 * umschlossen, wodurch Zeilenumbrüche auch simpel eingebaut werden
	 * können, sollte der Text zu lang sein.
	 * 
	 * @see #showDialog(String, Runnable)
	 */
	private JLabel labelLoad;

	/**
	 * Enthält in der Run-Methode die Aktion, die während der Sichtbarkeit
	 * des Dialogs ausgeführt werden soll. Die Methode wird über einen
	 * WindowListener aufgerufen.
	 */
	private Runnable runnableAction;

	/**
	 * Die einzige vorhandene DLoad-Instanz, welche nur intern zum Erzeugen
	 * und Anzeigen verfügbar ist. Die Instanz kann nur neu kosntruiert
	 * werden, wenn sich das neue Objekt von dem alten bezüglich der
	 * Attribute "Owner" und "Title" unterscheidet.
	 */
	private static DLoad instance;

	// ------Konstruktor--------------------------------------------------------------------------------------------//

	/**
	 * Erzeugt den Laden-Dialog, welcher nur mittels einer internen Instanz
	 * aufgerufen werden kann. <br>
	 * <br>
	 * Es wird ein Gif-Icon erzeugt, welches in einem Label zentral gezeigt
	 * wird. Darunter wird der Lade-Text angezeigt, welcher in der
	 * Öffnen-Methode übergeben wird.
	 * 
	 * @param owner
	 *                Das Fenster, über welches der Dialog angezeigt wird.
	 * @param title
	 *                Der Titel des Dialogs.
	 */
	private DLoad(Window owner, String title)
	{
		super(owner, title);
		setModal(true);
		setCursor(CursorAdmin.WAIT_CURSOR);
		setPreferredSize(new Dimension(300, 150));
		addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowOpened(WindowEvent e)
			{
				if (runnableAction != null)
				{
					runnableAction.run();
					setVisible(false);
				}
			}
		});
		Container content = getContentPane();
		content.setLayout(new BorderLayout(10, 10));

		ImageIcon iconLoading = ImageDesign.openImageIcon("/res/images/loading_60.gif", "");
		JLabel labelIcon = new JLabel(iconLoading);
		add(labelIcon, BorderLayout.CENTER);

		labelLoad = new JLabel("");
		labelLoad.setHorizontalAlignment(JLabel.CENTER);
		add(labelLoad, BorderLayout.SOUTH);

		setPreferredSize(new Dimension(300, 150));
		pack();
		setLocationRelativeTo(owner);
	}

	// ------Methoden-----------------------------------------------------------------------------------------------//

	/**
	 * Erzeugt die Dialog-Instanz, welche zum Öffnen des Laden-Dialogs
	 * benuzt wird. Wenn die Methode vorher bereits mit den selben
	 * Parametern aufgerufen wurde, bleibt die Instanz unangetastet.
	 * 
	 * @see #showDialog(String, Runnable)
	 */
	public static void createDialogInstane(Window owner, String title)
	{
		if (instance == null || !instance.getOwner().equals(owner)
				|| !instance.getTitle().equals(title))
		{
			instance = new DLoad(owner, title);
		}
	}

	/**
	 * Öffnet den Dialog und führt die jeweilig Aktion aus. Nach dem
	 * Abschließen der Aktion wird der Dialog wieder geschlossen. <br>
	 * <br>
	 * Der Text, der die jeweilig Aktion beschreibt wird automatisch mit
	 * HTML-Tags umschlossen und erlaubt so auch <em>manuelle</em>
	 * Zeilenumbrüche, wenn der Text für das Anzeige-Label zu lang sein
	 * sollte. <br>
	 * <br>
	 * Die Aktion, welche in der Run-Methode des zweiten Parameters
	 * aufgeführt werden sollte, wird aufgerufen, wenn das Fenster
	 * erfolgreich geöffnet wurde. <br>
	 * <br>
	 * <strong>Warnung: Die dafür benutzte Dialog-Instanz muss vorher
	 * erzeugt werden.</strong>
	 * 
	 * @see #createDialogInstane(JFrame, String)
	 * @throws NullPointerException
	 *                 Wenn noch keine Dialog-Instanz generiert wurde.
	 */
	public static void showDialog(String loadMessage, Runnable runnableAction)
	{
		if (instance == null)
		{
			throw new NullPointerException(
					"Dialog instance has to be created before trying open it!");
		}
		else
		{
			instance.runnableAction = runnableAction;
			instance.labelLoad.setText("<html>" + loadMessage + "<br>&nbsp;</html>");

			instance.setVisible(true);
		}
	}
}


Im Anhang nochmal der Dialog und meine Laden-GIF. Die GIF-Datei muss natürlich hinzugefügt werden und der Pfad angepasst werden, ja nach dem wo du sie hinlegst

Gruß, Thomas
 

Anhänge

  • DLoad.java
    4,9 KB · Aufrufe: 2
  • loading_60.gif
    loading_60.gif
    7,6 KB · Aufrufe: 55

Michael...

Top Contributor
1. nicht die run() eines Threads oder Runnables selbst aufrufen. Runnable Objekte werden immer einem Thread übergeben und ein neuer Thread wird immmer mit start() gestartet. Der direkter Aufruf von run() führt den Code einfach nur im aktuellen Thread aus.
2. wieso der WindowListener im Dialog? Du hast doch bereits eine Methode showDialog(...) hier einfach bevor Du setVisible auf den Dialog aufrufs ein Thread Objekt erzeugen (das Runnable im Konstruktor übergeben) und daran start() aufrufen.
 

Michael...

Top Contributor
Die Problemstellung die dann noch offen bleibt, ist das Schließen des Dialogs nach Abarbeitung des Threads. Eventuell wäre es dann besser nicht ein Runnable zu übergeben sondern einen eigene Klasse zu definieren, das Runnable im Kontext des Dialogs zu erstellen damit hier der Aufruf des "Jobs" und das Schließen des Dialogs durchgeführt werden kann.
 

beastofchaos

Bekanntes Mitglied
Das Problem ist jetzt ganz gelöst. Der übersprüngliche Code zum Öffnen:
Java:
        instance.runnableAction = runnableAction;
        instance.labelLoad.setText("<html>" + loadMessage + "<br>&nbsp;</html>");
        addWindowListener(new WindowAdapter()
        {
            @Override
            public void windowOpened(WindowEvent e)
            {
                if (runnableAction != null)
                {
                    runnableAction.run();
                    setVisible(false);
                }
            }
        });
        instance.setVisible(true);

Die Lösung mit einem Thread:
Java:
        instance.runnableAction = runnableAction;
        instance.labelLoad.setText("<html>" + loadMessage + "<br>&nbsp;</html>");

        Thread threadRun = new Thread(runnableAction)
        {
                @Override
                public void run()
                {
                        instance.runnableAction.run();
                        instance.setVisible(false);
                }
        };
        threadRun.start();
        instance.setVisible(true);

Lösung war also tatsächlich ein neues Thread-Objekt. Wusste das bis her nicht - dachte Runnable ist die Klasse um einfach Methoden als Parameter zu übergeben :))) Danke hierfür.

Gruß, Thomas
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D JTable nach Öffnen-Dialog umbaun AWT, Swing, JavaFX & SWT 5
F Fensternamen nach Öffnen änderbar? AWT, Swing, JavaFX & SWT 4
berserkerdq2 Buttons und Shapes sehen ja nach Screengröße klein oder zu groß aus, jemand eine Idee, was man tun kann? AWT, Swing, JavaFX & SWT 1
W JEditorPane textausrichtung nach settext funktioniert nicht mehr AWT, Swing, JavaFX & SWT 11
H Swing Buttons erst nach Klick sichtbar AWT, Swing, JavaFX & SWT 13
H JavaFX Fenstergröße nach maximieren erkennen AWT, Swing, JavaFX & SWT 6
D Swing Komponenten nicht sichtbar nach Start AWT, Swing, JavaFX & SWT 12
T Elemente auf vorheriger Stage, nach Wechsel der Stage ansprechen AWT, Swing, JavaFX & SWT 32
berserkerdq2 Mein Rechteck hat 4 Seiten, ich soll je nach dem, welche Seite berührt wurde, etwas ausführen, wie prüfe ich das? AWT, Swing, JavaFX & SWT 12
Ernesto95 JavaFX Return Value nach Beendigung einer Animation AWT, Swing, JavaFX & SWT 15
K Textarea aktuallisiert sich nicht, nach Auswahl (Itemlistener) AWT, Swing, JavaFX & SWT 3
M Nach Export als Runnable Jar wird css nicht merh gefunden AWT, Swing, JavaFX & SWT 22
P kein Scrollen nach affinertransformation bei mouse dragged AWT, Swing, JavaFX & SWT 2
M Wieso verändert sich die Framerate nach erneutem Starten des AnimationTimer? AWT, Swing, JavaFX & SWT 18
T ListView nach Erweiterung Fehler in CellFactory AWT, Swing, JavaFX & SWT 8
N JavaFX Tableview nach Löschen von Element falscher Index AWT, Swing, JavaFX & SWT 4
B JavaFX TextInputDialog: Focus auf Eingabefeldinhalt setzen und nach OK Inhalt leeren AWT, Swing, JavaFX & SWT 5
VPChief Nach abspielen von Sound reagiert das Program nichtmehr AWT, Swing, JavaFX & SWT 9
VPChief Swing Eclipse: Nach Exportieren, Button funktioniert nicht mehr AWT, Swing, JavaFX & SWT 26
E Swing Componenten werden nach Änderung des display modes verzerrt dargestellt AWT, Swing, JavaFX & SWT 8
L JavaFX Exception nach includieren einer fxml // nested controller AWT, Swing, JavaFX & SWT 1
Zrebna Problem bei Eventhandling (Value soll nach jedem erneutem Klick gelöscht werden) AWT, Swing, JavaFX & SWT 4
R Swing JTextField - Schriftgröße je nach Länge und Größe ändern AWT, Swing, JavaFX & SWT 0
F AWT awt KeyEvent - Zeichen direkt nach Eingabe löschen AWT, Swing, JavaFX & SWT 2
L Komponenten eines Panels werden erst nach Klick darauf angezeigt AWT, Swing, JavaFX & SWT 13
K JavaFX Element in HBOX nach rechts verschieben AWT, Swing, JavaFX & SWT 2
S JavaFX Slider freezt nach Benutzung AWT, Swing, JavaFX & SWT 3
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
Fiedlerdan Image-Pfad Probleme nach Export aus Eclipse AWT, Swing, JavaFX & SWT 31
T JavaFX Nach Zoomen wird an falscher Stelle gezeichnet AWT, Swing, JavaFX & SWT 0
S Ausgabe aktualisiert sich nur nach 2. Klick AWT, Swing, JavaFX & SWT 17
F JavaFX Zustand der CheckMenuItems behalten nach Programmneustart AWT, Swing, JavaFX & SWT 7
J jButton soll nach klicken eine Variable um 1 erhöhen AWT, Swing, JavaFX & SWT 2
S Nach scrollen verschwindet das zuvor im JPanel gezeichnete AWT, Swing, JavaFX & SWT 2
stroggi Swing Suche nach Kurveneditor (UI-Element) AWT, Swing, JavaFX & SWT 1
Neumi5694 java.awt.Window nach javafx.stage.Window AWT, Swing, JavaFX & SWT 1
L Swing Komponenten erst nach Resize sichtbar AWT, Swing, JavaFX & SWT 2
F Swing Frame nach vorne holen AWT, Swing, JavaFX & SWT 2
T Swing Änderung des ActionListener Events nach Klick auf JButton AWT, Swing, JavaFX & SWT 2
S Swing JButton verschwindet nach Compilieren AWT, Swing, JavaFX & SWT 8
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
robinab JavaFX TableView column resize nach setItems() AWT, Swing, JavaFX & SWT 0
MiMa Java, Maven Projekte nach JavaFX? AWT, Swing, JavaFX & SWT 3
S JavaFX Node soll auch nach Skalierung zentriert platziert sein AWT, Swing, JavaFX & SWT 3
J Suche nach einer horizontal aufklappbaren Toolbar AWT, Swing, JavaFX & SWT 1
Bluedaishi JTextArea gefundene Zeile nach Oben Scrollen AWT, Swing, JavaFX & SWT 13
MiMa Java Projekt nach JavaFX convertieren AWT, Swing, JavaFX & SWT 4
it_is_all JPanel verschwindet nach Button-Klick AWT, Swing, JavaFX & SWT 2
N Swing JButtons werden nach repaint() doppelt dargestellt AWT, Swing, JavaFX & SWT 12
U JavaFX Wechsel der Scene nach betätigen eines Button AWT, Swing, JavaFX & SWT 2
L JTextField erscheint erst nach Veränderung der Framegröße AWT, Swing, JavaFX & SWT 5
C Nach Aufruf von anderer Klasse streikt Grafik AWT, Swing, JavaFX & SWT 1
F AWT Robot Klasse Screenshot nach Pixelmustern in bestimmten Radius um Bildschirmmittelpunkt absuchen AWT, Swing, JavaFX & SWT 13
H Musik wird nach dem erstellen der .jar Datei nicht mehr abgespielt AWT, Swing, JavaFX & SWT 1
D iText PDF wird nach Neustart nicht importiert AWT, Swing, JavaFX & SWT 0
J Java FX Koordinaten NACH Animation setzen, wie? AWT, Swing, JavaFX & SWT 9
A Nach klick auf Button neuen Inhalt im gleichen Fenster AWT, Swing, JavaFX & SWT 3
Pr0m3theus Animation nach Event AWT, Swing, JavaFX & SWT 6
N Swing Abfrage durch JTextField nach Button betätigung AWT, Swing, JavaFX & SWT 3
S JTextArea Text nach oben wandern lassen AWT, Swing, JavaFX & SWT 7
Thallius JScrollPane Scrollpos setzen nach Neuzeichnen AWT, Swing, JavaFX & SWT 3
C JavaFX mehrere Kreise nach Eingabeprozess ausgeben AWT, Swing, JavaFX & SWT 2
J 2D-Grafik Linie wird nach Mausklick nicht am richtigen Ort gezeichnet AWT, Swing, JavaFX & SWT 11
C Memory Karten nach Paar offen bleiben sonst wieder umdrehen AWT, Swing, JavaFX & SWT 1
C Benutzername in GUI eingeben und nach Spiel neues Fenster Benutzername wieder anzeigen AWT, Swing, JavaFX & SWT 1
W Swing JPanel nur einmal nach mehreren Änderungen neu zeichnen AWT, Swing, JavaFX & SWT 1
L JavaFX Java FX Anwendung nach MVC mit Observer Pattern AWT, Swing, JavaFX & SWT 15
M JavaFX Methode nach initialize() aufrufen AWT, Swing, JavaFX & SWT 6
MrSnake Tabelle nach 2 Strings Filtern AWT, Swing, JavaFX & SWT 3
N Swing JFormattedTextField keine Werte nach Formatzuweisung AWT, Swing, JavaFX & SWT 0
T Swing Tabelle mit Button - Anzeigefehler nach Zeile entfernen AWT, Swing, JavaFX & SWT 1
R LookAndFeel Wie kann man die Textfarbe der Nimbus ProgressBar nach Füllstand ändern? AWT, Swing, JavaFX & SWT 2
KilledByCheese Swing Seltsame Ausgabe nach ButtonClick AWT, Swing, JavaFX & SWT 1
thobren JavaFX textarea nach setPrefRowCount Ansicht aktualisieren AWT, Swing, JavaFX & SWT 1
L Graphik nach 100 ms neu laden AWT, Swing, JavaFX & SWT 1
B Doppelte MenuBar -> Nach Minimieren verschwunden AWT, Swing, JavaFX & SWT 3
W JComboBox auffristen nach Listenänderung AWT, Swing, JavaFX & SWT 20
T JavaFX Editable Combobox Text-Selektierung nach Trigger AWT, Swing, JavaFX & SWT 4
A JFace/SWT: ListViewer Inhalt nach Selection in zweitem List Viewer aktualisieren! AWT, Swing, JavaFX & SWT 5
E JMenu erscheint nach RDP-Verbindung auf falschem Desktop AWT, Swing, JavaFX & SWT 1
B Resize von Image nach Resize von Button AWT, Swing, JavaFX & SWT 1
M Swing PDF Datei nach drucken nicht löschbar AWT, Swing, JavaFX & SWT 6
M JavaFX TableView nach Spalte sortieren AWT, Swing, JavaFX & SWT 1
F 2D-Grafik Grafikproblem nach Aufruf von JColorChooser-Dialog AWT, Swing, JavaFX & SWT 6
J JTable filtern nach einer Spalte AWT, Swing, JavaFX & SWT 2
J 2D-Grafik Windows Blue-Screen nach anzeigen eines Bildes in Java AWT, Swing, JavaFX & SWT 10
P Anwendung kommt nach minimieren nicht mehr in den Vordergrund AWT, Swing, JavaFX & SWT 5
1 JButton nach Klick ausblenden AWT, Swing, JavaFX & SWT 6
K Swing JPanel nach oben und links vergrößern AWT, Swing, JavaFX & SWT 3
Z Plot nach links verschieben!! AWT, Swing, JavaFX & SWT 1
J Swing: JFrame nach oben "aufklappen" AWT, Swing, JavaFX & SWT 0
X JFrame erst nach dem Laden sichtbar stellen AWT, Swing, JavaFX & SWT 8
G .jar startet nicht nach Exportierung AWT, Swing, JavaFX & SWT 7
P Swing JTable flimmert nach Zellsortierung AWT, Swing, JavaFX & SWT 3
S JComboBox nach auswahl erneuern AWT, Swing, JavaFX & SWT 4
Thallius Swing Tabelle nach Datumsspalte sortieren AWT, Swing, JavaFX & SWT 4
C JTextPane scrollt mit setText() immer nach oben AWT, Swing, JavaFX & SWT 2
D Swing Bestimmte Berechnung von Spalten durchführen und dann die Zeilen nach bestimmten Kriterien einfärben AWT, Swing, JavaFX & SWT 5
A JPanel wird nach Buttonklick nicht angezeigt AWT, Swing, JavaFX & SWT 2
P Swing JTable keine Markierung nach Button klick AWT, Swing, JavaFX & SWT 0

Ähnliche Java Themen

Neue Themen


Oben