Swing ButtonListener Fenster schließen

MarioW1986

Bekanntes Mitglied
Hi zusammen, ich bins ma wieder^^

also ich habe meine Code ejtzt ma ein bisschen strukturiert aber stehe dann wieder vor einem Problem. Habe dazu auch schon en bisschen was im Netz gefunden aber kann es nicht auf mein Beispiel übertragen. Ich habe ein Hauptfenster, dass nicht Mainmenu nennt. dor liegen 4 Buttons drinne und über den einen rufe ich ein LoginFenster auf.

Ich habe meine gesamten Actions in einer extra Klasse um das ganze übersichtlich zu halten. Mein Problem ist jetzt, dass ich wenn ich auf meinen Button Klicke mein Hauptfenster per visible oder hide oder dispose oder wie auch immer ausblenden will und nur das Loginfenster anzeigen will.

Ich poste einfach mal den Code:

Java:
public class Mainmenu extends JFrame {

	private static final long serialVersionUID = 1L;

	JButton start;
	JButton einstellen;
	JButton hilfe;
	JButton ende;

	public Mainmenu() {
		
		super("Hauptmenü");
		
		start = new JButton("Programm starten");
		start.addActionListener(new ButtonListener());
		start.setActionCommand("start");
		add(start);
		
		einstellen = new JButton("Einstellungen");
		einstellen.addActionListener(new ButtonListener());
		einstellen.setActionCommand("openLogin");
		
		add(einstellen);
		
		hilfe = new JButton("Hilfe");
		hilfe.addActionListener(new ButtonListener());
		hilfe.setActionCommand("hilfe");
		add(hilfe);
		
		ende = new JButton("Beenden");
		ende.addActionListener(new ButtonListener());
		ende.setActionCommand("kill");
		add(ende);
		
		setSize(300, 200);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setLayout(new GridLayout(4, 1));
		setResizable(false);
		setVisible(true);
	}
	

	public static void main(String[] args) {
		Mainmenu menu = new Mainmenu();
	}

wenn ich jetzt auf den Button Einstellen klicke kommt mein LoginFrame.

dieses wird hier aufgerufen:

Java:
public class ButtonListener implements ActionListener {
	
	

	@Override
	public void actionPerformed(ActionEvent event) {

             ...
            if ("openLogin".equals(event.getActionCommand())){
        	login();
            }
            ....

            private void login() {
		LoginFrame loginFrame = new LoginFrame();
		loginFrame.loginFrame();
	}
...
}

wie erreiche ich es, dass ich mein Hauptfenster verbergen kann?

ich steh wie immer aufm Schlauch!?!?

jos hoffe das mir jemand helfen kann. und bitte net in nem Fachchinesisch, ich hab immer en bisschen Probleme mit den Begrifflichkeiten. ^^:bahnhof:

danke
 
Machs wie dus gesagt hast mit setVisible.
gib denn aktuellen frame mit und verberge
ihn beim starten des Logins. Am ende setzt
du ihn wieder auf visible und beim login
rufts du dispose auf.
 
je nachdem was du vor hast...wäre evtl. eine Möglichkeit, dass du deiner ActionListenerKlasse eine Referenz des Mainmenu mitgibst:

Mainmenu.java
[java=20]einstellen.addActionListener(new ButtonListener(this));[/code]

ButtonListener.java
Java:
public class ButtonListener implements ActionListener {
Mainmenu mainMenu;
public ButtonListener (Mainmenu mainMenu){
this.mainMenu=mainMenu;}
...
@Override
    public void actionPerformed(ActionEvent event) {
 
             ...
            if ("openLogin".equals(event.getActionCommand())){
            login();
            }
            ....
 
            private void login() {
        LoginFrame loginFrame = new LoginFrame();
        loginFrame.loginFrame();
mainMenu.setVisible(false);
}
 
Also alle Aktions in eine Klasse zu packen halte ich nicht für übersichtlich... Ausserdem ist es ja auch umständlich wenn du (wie ich mal annehme) auf Komponenten in verschiedenen Frames/Panels/LoginScreens von deiner ActionListener Klasse aus zugreifen willst. Wenn du da schon was zusammenfassen willst, dann mach maximal eine Klasse pro Komponente.
 
Guten Morgen,
danke für eure Antworten und danke jgh deine variante funktioniert wunderbar 🙂

jetzt hab ich dann in meiner Klasse Administration auch wieder Buttons liegen die ich genauso abarbeiten möchte. Dort liegt ein Beenden Button der wieder das Mainmenu öffnen soll. Ich dachte mir "logischerweise" das gleiche Prozedere wie vorher auch nur dass ich diesmal einen Konstruktor benutze, der mir eine Referenz der Klasse Administration übergibt und dann wieder das Mainmenu aufruft
leider führt das zu folgender Fehlermeldung

Java:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at Messe.ButtonListener.beenden(ButtonListener.java:61)
	at Messe.ButtonListener.actionPerformed(ButtonListener.java:37)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$200(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Zeile 61 im ButtonListener ist folgende:


Java:
mainmenu.setVisible(true);

in folgender Methode:

Java:
	private void beenden() {
		mainmenu.setVisible(true);
	}

und ich hab das jetzt so gemacht:

Java:
public class ButtonListener implements ActionListener {
	
	Mainmenu mainmenu;
	Administration admin;

	public ButtonListener(Mainmenu mainmenu) {
		this.mainmenu = mainmenu;
	}





	public ButtonListener(Administration administration) {
		this.admin = administration;
	}

....

if ("ende".equals(event.getActionCommand())){
            beenden();
        }

...
private void beenden() {
		mainmenu.setVisible(true);

			
	}
private void login() {
		LoginFrame loginFrame = new LoginFrame();
		loginFrame.loginFrame();
		mainmenu.setVisible(false);
	}

....

und der Button in der Klasse Administration sieht so aus:

Java:
btnEnde = new JButton("Beenden");
		btnEnde.addActionListener(new ButtonListener(this));
		btnEnde.setActionCommand("ende");
		btnEnde.setBounds(380, 10, 100, 30);
		add(btnEnde);
was mach ich ejtzt schon wieder falsch?

Gruß Mario
 
also wenn ich mir mal selbst antworten darf^^
ich glaub ich seh da was
und zwar wenn mein Konstruktor für Administration ausgeführt wird, ist für den ja mein Mainmenu gar nicht bekannt oder?

wie erreiche ich, dass der das erkennt?
 
na ja, scheinbar, oder offensichtlich nutzt du den Konstruktor
Code:
  public ButtonListener(Administration administration) {
        this.admin = administration;
    }

dort wird natürlich nicht das mainMenu gesetzt => das mainMenu null ist...und dir eine NPE schmeißt
wenn du in der Admin-Klasse eine korrekte Referenz auf das Mainmenu hast, dann bau dir einen Konstruktor, der sowohl das Administration, als auch das Mainmenu als Parameter erwartet.

Um das ganze nicht irgendwann komplett unübersichtlich zu gestalten, gibt es bspw. das MVC Pattern...in dem der Controller dieses ganze regelt. Der Controller kennt dann deine View und irgendwelche Aktionen innerhalb der View werden dem Controller mitgeteilt und dieser entscheidet dann was gemacht werden muss. Neue View anzeigen, Model verändern, Daten abspeichern etc

[edit]korrekt^^[/edit]
 
von MVC hab ich während meines Studiums schon gehört aber komme damit noch nicht so zurecht.

mit dem Konstruktor für beide Klassen bzw für mehrere Referenzen hab ich auch schon gedacht.
würde bedeuten

Java:
public ButtonListener(Mainmenu mainmenu, Administration administration) {
		this.mainmenu = mainmenu;
                this.administration = administration;
	}

aber was gebe ich dann jeweils dem New ButtonListener mit?

Java:
btnEnde.addActionListener(new ButtonListener(null, this));

funktioniert das ja offensichtlich nicht (Variante in der Administration Klasse)

Danke

P.S. MVC werde ich mir später nochmal ansehen
 
da beginnt halt Design in der SW (imho)

Du musst dir halt überlgen, ob du in der Admin-Klasse irgendwo eine sinnvolle Referenz auf dein Mainmenu setzen kannst...oder ob das Mainmenu eine Referenz auf die Adminklasse halten soll und diese dann beim initialisieren sich selbst als Referenz in der AdminKlasse setzt, was ist sinniger?

BTW sieht man imho auch hier, dass deine Namensgebung für einen Aussenstehenden nicht sonderlich geschickt gewählt ist. Mainmenu ist bei dir ein JFrame, Adminstrator ist auch ein JFrame, oder ein JPanel oder oder oder...???

Bspw. mit
Code:
btnEnde
weiß sogar ein **** wie ich, dass es sich um ein (J)Button handelt, der irgendetwas beenden soll...das ist für mich sinnige Namengebung.
 
ok ich geb zu meine Benennung ist nicht besonders vorteilhaft gewählt. Das hab ich jetzt angepasst 🙂

Was den anderen Teil deiner Antwort betrifft, verstehe ich nicht wirklich.
Kannst mir en Beispiel geben. Würde gerne das in diesem Konstruktor in meinem ButtonListener-Klasse weiterführen, da dieser eventuell erweitert wird 🙂

möchte kein durcheinander haben, was ich deiner Meinung nach sicher schon habe^^ aber noch komme ich ganz gut zurecht 😉

danke
 
was ist denn die Admin klasse für ein Element? Ein Frame, ein Panel... wenn es es Frame ist, solltest du dir grundlegend Gedanken machen, warum du mehrere Frames brauchst und diese mit visible(true) und (false) sichtbar, bzw. unsichtbar machst!

ansonsten irgendwie sowas:
Java:
public static void main(String[] args{
Mainmenu mainMenu= new MainMenu();
Administrator admin = new Adminstrator(mainMenu);
// oder halt den umgekehrten Weg
Administrator admin = new Adminstrator();
Mainmenu mainMenu= new MainMenu(admin );

...
}

gibt halt 100 von Möglichkeiten...
 
danke 🙂

ja es ist ein Frame und ich arbeite mit mehreren Fenstern. Ist doch nicht sonderlich schlimm oder?

wie würdest du es denn machen?^^😛ueh:
 
na ja, wenn du im Browser auf eine andere Website klickst schließt sich doch dein BrowserFenster(==Frame) doch auch nicht und ein neues Frame geht auf oder wenn du mit Word arbeitest, dann ist dein Frame immer der gleiche, egal wieviele Dokumente du geöffnet hast...es sei denn du willst es explizit!

Imho hat eine Anwendung ein einzigen Frame, klar Ausnahmen bestätigen die Regel...aber für dein Projekt sollte ein Frame langen!

Und dann packst du in deinen JFrame halt JPanels die du dann mit Buttons, Textfeldern etc vollpackst wie du willst. So brauchst du dich um dieses visible-Geschisse nicht kümmern. Evtl. ist es als Anfänger auch ok, ich weiß meine erste Anwendung hatte auch für jede Interaktion mit dem User einen eigenen Frame^^ also progge erstmal weiter. Wenn du dann später auch bspw. JMenuBar nutzt usw, wirst du schon merken, dass ein JFrame sinnvoller ist.
 
ja klar ist das schöner aber ich hab in meinem studium java kennengelernt (eigentlich sollte ich es können aber ich hab mich sozusagen durchgemogelt, ejtzt weiß ich das das net die optimale lösung war) und versuche dass jetzt in der Anwendung zu vertiefen. Hab schon en Buch gelesen und meine Studienunterlagen nochmal durchgeguckt aber alles versteh ich immernoch net.

ich werd mir das mit den Panels mal vornehmen. Was denskt du über InternalFrames? auch ne gute Lösung oder eher weniger?
 
Ich weis nicht wie das andere sehen, aber wenn ich mit JFrame arbeite erbe ich nicht von ihm und erstell immer einen Statischen JFrame um den Zugriff von anderen Klassen gut zu steuern.

Zusätzlich hätte ich den Buttonlistener von der Mainklasse erben lassen. Falls du es noch nicht weist, implements und extends, funktionieren nebeneinander perfekt, du musst nur die Hierarchie beachten und fallst du von deiner GUI Klasse erbst immer den JFrame statisch setzen!

mfg

JDKarl
 

Zurück
Oben