OOP GUI - Fenster vererben?

membersound

Bekanntes Mitglied
Hallo,

ich habe eine Frage zur Vererbung bei der GUI Erstellung.
Meine Gui hat zwei Buttons, und jeder soll ein anderes JDialog Fenster öffnen. Diese Dialogfenster ähneln sich. Bzw das eine hat mehr Komponenten als das andere. Deshalb habe ich gedacht, macht Vererbung bestimmt Sinn.
Leider hab ich kein wirkliches Tutorial oder Beispiel für sowas gefunden.

In meinem bisher erstellen JDialog habe ich nun im Konstruktor eine private initComponents() sowie die private Eventhandlung Methoden.
Den Dialog erstelle ich also beim ActionEvent vom Buttonclick, und setze dort auch auf visible.

So, jetzt möchte ich mit dem zweiten Button aber einen zweiten/anderen JDialog erstellen können, und bei diesem noch einige Komponenten hinzufügen.
Kann ich dafür irgendwie die initComponents() der Elternklasse erben und weitere Elemente dort hinzufügen (irgendwie mit super())? Oder sollte ich besser die init Methode komplett überschreiben (dh den Code aus der Elternklasse dorthin kopieren + eben die zusätzlichen Komponenten an Ort und Stelle einfügen)?

Wie kann ich die bereits erstellten ActionPerformed Methoden meines ersten JDialogs in der Kindklasse verwenden? Muss ich sie dafür einfach public setzen und sie dann ganz normal wiederverwenden?

Irgendwie macht das alles einen Knoten in meinen Kopf :autsch:
Danke
 
Zuletzt bearbeitet:

Volvagia

Top Contributor
Ja. Du kannst in der Sub die initComponents() überschreiben, und darin als erstes super.initComponents() aufrufen. Damit wird zuerst die der nächsthöheren Superklasse aufgerufen. Darunter machst du das, was du bei dem Dialog eben weiteres machen willst.

Ja, wenn er als Klassenvariable angelegt ist ginge das. Du übergibst ihn wie jede andere Instanz auch. Schöner fände ich persönlich aber eine Methode, die im Listener aufgerufen wird. Dann bist du nicht an die Action gebunden. Dafür würde ich aber für jeden Komponenten einen eigenen Listener erzeugen und die Methode aufrufen lassen. Ist zwar wartungstechnisch nicht soooo toll als nur eine Instanz, aber am Ende kann ich damit besser arbeiten als mit nur einen Listener.
 

membersound

Bekanntes Mitglied
Ja. Du kannst in der Sub die initComponents() überschreiben, und darin als erstes super.initComponents() aufrufen. Damit wird zuerst die der nächsthöheren Superklasse aufgerufen. Darunter machst du das, was du bei dem Dialog eben weiteres machen willst.

Das kann ich ja leider nicht. Zumindest ergibt es: initComponents() has private access in <ParentclassJDialog>

Aber da die private initComponents() in dem Konstruktor steht, wird sie dann nicht sowieso schon direkt aufgerufen, wenn ich den ChildJDialog erzeuge?


Ich versuch das gerade auch noch parallel im Netbeans Gui Editor umzusetzen. Dann wäre das mit dem positionieren der Zusatzelemente einfacher. Aber ich schaff es nicht dort eine Vererbung zu erzeugen. Wenn ich manuell extends im Code eintrage, bekomme ich im Visual Editor nur einen leeren Frame.
Wenn jemand weiß wie ich Visual Inheritance in Netbeans hinbekomme wäre ich echt dankbar...
 
J

JohannisderKaeufer

Gast
Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;

public class Dialog1 extends JDialog implements ActionListener {
	public Dialog1() {
		setLayout(new GridLayout(1, 0));
		initComponents();
		makeItVisible();
	}

	private void makeItVisible() {
		System.out.println("Make it visible");
		pack();
		setVisible(true);
	}

	private void initComponents() {
		System.out.println("Add some components");
		JButton button = new JButton("B1");
		button.addActionListener(this);
		add(button);
	}

	private void handleEvent() {
		System.out.println("E1");
	}

	public void actionPerformed(ActionEvent e) {
		handleEvent();
	}
}

Java:
import java.awt.event.ActionEvent;

import javax.swing.JButton;

public class Dialog2 extends Dialog1 {
	public Dialog2() {
		super();
		initComponents();
	}

	private void initComponents() {
		System.out.println("Add more Components");
		JButton button = new JButton("B2");
		button.addActionListener(this);
		add(button);
	}

	private void handleEvent() {
		System.out.println("E2");
	}

	public void actionPerformed(ActionEvent e) {
		handleEvent();
	}
}

Ein kleines Beispiel und daraus resultierende Probleme.

Dialog1 ist straight Forward, ein einfacher Dialog mit einem Button der beim Drücken auf die Konsole E1 schreibt. Der ActionListener ist ein Bestandteil vom Dialog1.

Dialog2 erbt davon und soll einen weiteren Button hinzufügen. Das erste Problem ist, daß die Methode makeItVisible zu früh aufgerufen wird. Also bevor, der Dialog2 fertig initialisiert ist

Code:
Add some components
Make it visible
Add more Components

Daraus ergibt sich dann auch das das pack zu früh aufgerufen wird und die Buttons insgesamt zu schmal werden.
Das heißt, das beim Dialog2 nochmals sichergestellt werden muß, dass das pack() nochmals nach dem hinzufügen des zweiten Buttons geschehen muß.


Läßt man das ganze (Dialog2) laufen und clickt auf den zweiten Button, scheint alles in Ordnung. "E2" landet auf dem Terminal.

Drückt man nun Button1, erscheint auf der Konsole abermals E2 anstatt korrekterweise E1. Das ist weil durch die Vererbung auch der ActionListener vererbt und überschrieben wurde und die Referenz die an button1 geheftet wird nun auf den ActionListener, so wie er in Dialog2 definiert wurde zeigt.
Eine Lösung besteht nun dahingehend, dass man den ActionListenern eigene Klassen zugesteht, die dann nicht mitvererbt werden. Dies kann z.B. in einer inneren Klasse geschehen.

Oder aber, man geht hin und ruft in Dialog2#actionPerformed(AE e) mit super.actionPerformed(e), den ActionListener aus der Oberklasse mitauf. Das hätte allerdings zur Folge das auf der Konsole bei einem Klick E1 und E2 landen. Egal welcher Button gedrückt wird.
D. H. man müßte im ActionListener eine Unterscheidung einbauen, die erkennt welcher Button gedrückt wurde.

Die Variante mit der inneren Klasse gefällt mir hierfür am besten und würde dann so aussehen
Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;

public class Dialog1 extends JDialog {
	public Dialog1() {
		setLayout(new GridLayout(1, 0));
		initComponents();
		makeItVisible();
	}

	private void makeItVisible() {
		System.out.println("Make it visible");
		pack();
		setVisible(true);
	}

	private void initComponents() {
		System.out.println("Add some components");
		JButton button = new JButton("B1");
		button.addActionListener(new MyAL());
		add(button);
	}

	private void handleEvent() {
		System.out.println("E1");
	}

	
	private class MyAL implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			handleEvent();
		}
	}
}


Das ganze ist aber immer noch zufriedenstellend. Zumindest für mich. Daher würde ich folgendes machen

Eine Klasse Dialog1 die von JDialog erbt und im Konstruktor DialogInhalte übergeben bekommt.
Die Inhalte werden nacheinander aufgerufen und zum Dialog hinzugefügt und dann angezeigt.

Java:
import java.awt.GridLayout;

import javax.swing.JDialog;

public class Dialog1 extends JDialog {
	public Dialog1(DialogInhalt...inhalte) {
		setLayout(new GridLayout(1,0));
		for(DialogInhalt inhalt : inhalte){
		  inhalt.initComponents(this);
		}
		pack();
		setVisible(true);
	}
}

Das Interface für die einzelnen Inhalte sieht so aus
Java:
import javax.swing.JDialog;

public interface DialogInhalt {
  public void initComponents(JDialog dialog);
}

Ein einfacher DialogInhalt

Java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;

public class DialogInhaltEinfach implements DialogInhalt{

	
	public void initComponents(JDialog dialog) {
		System.out.println("Add some components");
		JButton button = new JButton("B1");
		button.addActionListener(new MyAL());
		dialog.add(button);
	}

	private void handleEvent() {
		System.out.println("E1");
	}

	
	private class MyAL implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			handleEvent();
		}
	}
}

und zusätzliche Funktionalität

Java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;

public class DialogInhaltErweiterung implements DialogInhalt{

	public void initComponents(JDialog dialog) {
		System.out.println("Add more Components");
		JButton button = new JButton("B2");
		button.addActionListener(new MyAL2());
		dialog.add(button);
	}

	private void handleEvent() {
		System.out.println("E2");
	}

	private class MyAL2 implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			handleEvent();
		}
	}
}

Das ganze baut sich in einer Main wie folgt zusammen

Java:
public class Main {

	public static void main(String[] args) {
		new Dialog1(new DialogInhaltEinfach(), 
					new DialogInhaltErweiterung()
		);

	}

}

Aber am Schluß bleibt immer noch das Problem ein exaktes Layout zusammenzubekommen.Hier klappt das mit dem GridLayout noch einigermaßen, aber mit anderen Layouts kann das unendlich komplex werden.
 

Ark

Top Contributor
[…] die Komposition, auch Inheritance genannt […]
Auf die Gefahr hin, dass ich mich gerade vollends irre: Nein?! Der wesentliche Unterschied zwischen einer Komposition und einer Vererbung ist, dass bei Letzterer dem Erben ein Typ mitgegeben wird. Wenn du Komposition und Vererbung durcheinanderwürfelst, darfst du dich nicht wundern, wenn plötzlich dein Haus woanders steht, bloß weil der dort ansässige Mensch Auto gefahren ist.

Außerdem kannst du mehrere Dinge des gleichen Typs aggregieren bzw. zur Komposition einsetzen, während du nur einmalig einen Typ erben kannst. Ansonsten müsste ja auch so was gehen wie [c]Auto extends Seitenspiegel,Seitenspiegel[/c] oder sogar [c]B extends A; C extends A,B[/c] (WTF, OO-Inzest :D).

Ark
 

Fu3L

Top Contributor
die einem die Komposition, auch Inheritance genannt

Da mir in Arks Post die Kurzzusammenfassung des Unterschieds von beidem fehlt:
Inheritance - Vererbung. Ist-ein Beziehung: Man Leitet seine Klasse von einer anderen Klasse ab und erbt somit alle non-private (und glaube non-static) Methoden. Das non-private is das für dich, membersound, entscheidende ;)

Komposition. Hat-ein Beziehung: Mein Auto hat ein Nummernschild, also lege ich eine Instanzvariable vom Typ Nummernschild an, anstatt mein Auto von Nummernschild erben zu lassen. Weil ein Auto ist kein Nummernschild^^
 
J

JohannisderKaeufer

Gast
Komposition. Hat-ein Beziehung: Mein Auto hat ein Nummernschild, also lege ich eine Instanzvariable vom Typ Nummernschild an, anstatt mein Auto von Nummernschild erben zu lassen. Weil ein Auto ist kein Nummernschild^^

Richtig ein Auto ist kein Nummernschild.
Ein Auto könnte von einem GegenstandMitNummernschild erben, da es ja ein Gegenstand mit Nummernschild ist. Das wäre dann der Fall mit Vererbung.

Auf die Gefahr hin, dass ich mich gerade vollends irre: Nein?!

Sorry, war eine kleine Verwechslung (Übersetzungsfehler), Inheritance ist Vererbung, Komposition ist Composition. Wenn man bei einer Suche Vererbung vs Komposition eingibt, kommt man auch zu Ergebnissen wie Inheritance vs Composition, daher die Verwechslung zur frühen Stunde.
 
D

dev018

Gast
Richtig ein Auto ist kein Nummernschild.
Ein Auto könnte von einem GegenstandMitNummernschild erben, da es ja ein Gegenstand mit Nummernschild ist. Das wäre dann der Fall mit Vererbung.
Wobei "GegenstandMitNummernschild" konzeptionell keine sauber definierte Superklasse für irgendwas ist, sondern eher die Erweiterung einer anderen Klassen mit zusätzlicher Funktionalität. Dieses Konzept wird gemeinhin auch als "Mixin" oder "Trait" bezeichnet. In Pseudocode:
Code:
class Auto extends Fahrzeug with HatNummernschild {
         ...
}
 

membersound

Bekanntes Mitglied
Das ist ja irgendwie eine endlose Frickelei, wenn ich wirklich die Komponenten des Dialogs vererben will. Ich glaub das mach ich besser einen eigenständigen und kopiere das meisten aus dem ersten.

Trotzdem würd ich ja gerne die nun public gesetzten Methoden, ActionPerformed usw des ersten Dialogs vererben.

Jetzt ist die Frage: Wie kann ich den JDialog extenden, um seine public Methoden zu vererben, aber den Aufruf der visuelle Methode initComponents() vermeiden? Die steht ja im Konstruktor des ersten Dialogs, und wird bei Subklassen somit ja zwangsweise aufgerufen, selbst wenn ich sie dort überschreibe...


/ok, ich denke eine abstrakte Klasse ist hier das Stichwort. Belehrt mich bitte falls es ne bessere Möglichkeit gibt.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Variable von 1. Fenster an 2. Fenster übergeben. Java Basics - Anfänger-Themen 7
javalux123 Keylistener auf andere Fenster Java Basics - Anfänger-Themen 3
T Java FXML selbes Fenster verschiedene Stellen im Programm Java Basics - Anfänger-Themen 5
B Scrollbares Fenster (JScrollPane) mit JPanel scrollt nicht Java Basics - Anfänger-Themen 3
J Überprüfen ob ein Fenster offen ist? Java Basics - Anfänger-Themen 8
T jOptionPane zum schließen von Fenster, wie "Ja" und "Nein" anstatt Yes und No Java Basics - Anfänger-Themen 2
JEP1 Java Dialog Fenster schließen Spiel Java Basics - Anfänger-Themen 0
H Eingabe tätigen bevor Graphics g Fenster öffnet Java Basics - Anfänger-Themen 5
celta_vigo Konsolen-Fenster ist weg Java Basics - Anfänger-Themen 5
Thomathy Interface Wie schließt man ein anderes JFrame Fenster? Java Basics - Anfänger-Themen 6
M PNG als Spieler im Fenster anzeigen Java Basics - Anfänger-Themen 4
S JOptionPane komplett leeres Fenster Java Basics - Anfänger-Themen 4
A Eclipse-Fenster starten statt Konsoleausgabe Java Basics - Anfänger-Themen 2
A Fenster bleibt weiß Java Basics - Anfänger-Themen 7
O Fenster programmieren Java Basics - Anfänger-Themen 2
M JavaFX: Fenster bleibt weiß Java Basics - Anfänger-Themen 3
A Fenster programmieren Java Basics - Anfänger-Themen 1
J JFrame Fenster öffnet sich nicht Java Basics - Anfänger-Themen 7
M aus Fenster anderes Fenster öffnen und wieder umgekehrt Java Basics - Anfänger-Themen 5
J Best Practice DOS Fenster mit Befehlszeile (Lösung) Java Basics - Anfänger-Themen 2
J Fenster wieder unsichtbar machen Java Basics - Anfänger-Themen 2
das_leon Gesamtes Programm in einem Fenster Java Basics - Anfänger-Themen 1
E Knopfdruck neues Fenster öffnen Java Basics - Anfänger-Themen 5
A Fenster mit Button aufrufen Java Basics - Anfänger-Themen 3
D Erste Schritte JPanel verschiebt Fenster via setVisible Java Basics - Anfänger-Themen 5
W Es wird erst gezeichnet, wenn ich das Fenster vergrößere? Java Basics - Anfänger-Themen 20
K Interface Fenster mit 3 ComboBoxen und 1 Button Java Basics - Anfänger-Themen 13
P Erste Schritte durch MenuBar verschiedene Fenster öffnen Java Basics - Anfänger-Themen 2
I Fenster A soll Fenster B schliessen Java Basics - Anfänger-Themen 5
D Java Fenster blockiert ? Java Basics - Anfänger-Themen 5
K Erste Schritte Neues Fenster mit Textinhalt öffnen Java Basics - Anfänger-Themen 6
M Code um per jButton ein neues Fenster zu öffnen Java Basics - Anfänger-Themen 3
A Popup-Fenster Java Basics - Anfänger-Themen 1
L Fenster auf Knopfdruck Java Basics - Anfänger-Themen 3
N Problem mit JOptionPane und Fenster-Fokus Java Basics - Anfänger-Themen 2
J ausgaben von der konsole in das fenster Java Basics - Anfänger-Themen 5
O Finally beim Fenster schliessen Java Basics - Anfänger-Themen 3
F Klassen Zugriff auf Fenster aus versch. Klassen Java Basics - Anfänger-Themen 5
P Eigenes Fenster erstellen Java Basics - Anfänger-Themen 5
M Input/Output Text auf Fenster zeichen Java Basics - Anfänger-Themen 2
T Zu viele Fenster - HILFE! Java Basics - Anfänger-Themen 5
J Extra Fenster (Frame) Java Basics - Anfänger-Themen 20
llabusch Fenster per Button verschieben Java Basics - Anfänger-Themen 5
llabusch Fenster um x Pixel verschieben Java Basics - Anfänger-Themen 4
P Window Builder Reiter im Fenster erstellen Java Basics - Anfänger-Themen 7
S Java Fenster Java Basics - Anfänger-Themen 2
D (zwei) Fenster mit unterschiedlicher Befüllung Java Basics - Anfänger-Themen 11
A JAVA Fenster in ein PDF Konvertieren Java Basics - Anfänger-Themen 1
A Erkennung eines Button im aktiven Fenster Java Basics - Anfänger-Themen 2
B Variable im Fenster anzeigen lassen? Java Basics - Anfänger-Themen 2
S Fenster ist zu groß Java Basics - Anfänger-Themen 8
O GUI: Eigene Fenster "Form"? Java Basics - Anfänger-Themen 13
X JFrame Fenster einzeln schließen Java Basics - Anfänger-Themen 2
E Fehlermeldung und Fenster wird nicht mehr angezeigt Java Basics - Anfänger-Themen 12
I Einlese Abfrage zweier Variablen in einem Fenster Java Basics - Anfänger-Themen 6
F Erste Schritte Aktuelles Fenster durch Event schließen Java Basics - Anfänger-Themen 3
N Java Programm im CMD Fenster öffnen, wie? Java Basics - Anfänger-Themen 17
S Erste Schritte Fenster wechsel im Applet Java Basics - Anfänger-Themen 7
tuttle64 Keine Umlaute im Dos Fenster Java Basics - Anfänger-Themen 12
J Button nimmt das komplette Fenster ein?! Java Basics - Anfänger-Themen 5
M Beim Klicken auf X neues Fenster Java Basics - Anfänger-Themen 4
Athena Schlichtes Fenster mit Windowskomponenten Java Basics - Anfänger-Themen 3
H KeyListener auf ganzes Fenster setzen Java Basics - Anfänger-Themen 14
S Neues Fenster auf Knopfdruck Java Basics - Anfänger-Themen 12
J Button drücken neues Fenster?! Java Basics - Anfänger-Themen 5
A Login Fenster Java Basics - Anfänger-Themen 3
C Button - neues Fenster - Bestellung anzeigen Java Basics - Anfänger-Themen 10
Z GUI-Fenster leeren Java Basics - Anfänger-Themen 5
M Erste Schritte Probleme mit Fenster Schließen Java Basics - Anfänger-Themen 6
J ordentliche Fenster Java Basics - Anfänger-Themen 17
J Problem beim Fenster Java Basics - Anfänger-Themen 4
Z Login Fenster Java Basics - Anfänger-Themen 7
K Aus JFrame-Fenster SuM-Fenster öffnen geht nicht! Java Basics - Anfänger-Themen 8
T Client-Fenster bei Aufruf unvollständig Java Basics - Anfänger-Themen 12
O Größeres Fenster als angegeben?! Java Basics - Anfänger-Themen 2
J Eltern-Fenster ermitteln Java Basics - Anfänger-Themen 2
M Ausklappbares Fenster bei grafischem Taschenrechner Java Basics - Anfänger-Themen 2
V Fenster wird nicht mittig platziert Java Basics - Anfänger-Themen 3
P gui fenster nur einmal aufrufen Java Basics - Anfänger-Themen 5
P Im Fenster bleiben (swing) Java Basics - Anfänger-Themen 16
J Werte ins neue Fenster übertragen Java Basics - Anfänger-Themen 6
S Fenster richtig schließen Java Basics - Anfänger-Themen 8
M Einfacher Fenster-Ablauf Java Basics - Anfänger-Themen 5
M Timer-Thread in Swing öffnet jedes Mal ein neues Fenster Java Basics - Anfänger-Themen 6
J Zweimal im gleichen Paint-Fenster malen Java Basics - Anfänger-Themen 8
SexyPenny90 Wie erstelle ich ein extra Fenster mit einer Meldung Java Basics - Anfänger-Themen 2
S nur neu geöffnetes Fenster schließen Java Basics - Anfänger-Themen 3
J Willkürlich geöffnetes Fenster/Dialog anspielen? Java Basics - Anfänger-Themen 3
T fenster schliesen und mouse events in einer nicht abstrakten klasse Java Basics - Anfänger-Themen 6
M Erste Schritte Fenster Und VB Funktionen Java Basics - Anfänger-Themen 8
G Scrollbares Fenster bei mehr als 5 Objekten Java Basics - Anfänger-Themen 4
L Fenster winzig klein durch GridBagLayout Java Basics - Anfänger-Themen 3
R Welcher Layout Manager-für so ein Fenster? Java Basics - Anfänger-Themen 5
H Java-Fenster ohne Inhalt Java Basics - Anfänger-Themen 2
T Windows Fenster Schließen Java Basics - Anfänger-Themen 4
E JFrame Fenster bewegen Java Basics - Anfänger-Themen 8
K Swing Fenster jede sec.neuzeichnen Java Basics - Anfänger-Themen 14
E javaw öffnet trotzdem ein DOS Fenster Java Basics - Anfänger-Themen 15
M Output Input im Cmd Fenster Java Basics - Anfänger-Themen 7
M Neues Fenster Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben