JMenuBar und JPannel übergeben und tauschen mit aktuellem Panel,Bar im Frame


gendadon

Grünschnabel
Hi tutorials.de Gemeinde,

erstmal möchte ich sagen wie genial ich diese seite finde, hab schon ne Menge an Lösungen für so manches Problem hier rausgeholt. also super, immer weiter so :D
Aber nun steh ich vor nem Problem, wo ich zwar auch einige Ansätze mit der Suchfunktion gefunden habe, dieses aber entweder falsch verstanden oder sie mein Problem nicht lösen konnten und deswegen das neue Thema hier.

Also viel bla bla und nun zu meinem Problem. Ich bin gerade dabei einen eshop zu programmieren und hänge mometan bei der GUI, die ich mit Swing per Hand ertellen möchte, weil ich durch den Code dieser Builder nicht durchsteig.
Wie gesagt ich möchte also eine GUI bauen und hänge mometan an dem problem fest, dass ich eine Loginbereich erstellt habe, wo oben eine JMenuBar ist, darunter ein Logo und dann kommt ein JPanel.
Das Frame was ich erstelle, teile ich mit einem Borderlayout ein und füge dann einfach jeweils Logo,JPanel in die Bereiche NORTH und CENTER ein.(Bild von der GUI im Anhang)

Nun habe ich meine Panels und Menubars alle in einzelnen Klassen ausgelagert.
Und mein Zeil bei der ganzen Geschichte soll es eigentlich sein, dass wenn man auf den Button login drückt, dass dann (durch ein Funktionen in den einzelnen Klassen) ein neu erstelltes JPanel und eine JMenuBar übergeben werden an die Hauptklasse (EshopGUIclient) und das diese neu erstellte und übergebenen Panel und Bar dann ausgetauscht werden mit dem aktullen Panel und der aktuellen MenuBar.
Und so wie ich das Problem nun verstehe, funktioniert ja auch alles, das übergeben der beiden Sachen von den externen Klassen an die Hauptklasse, und nun kommt das ABER sobald ich dem Frame sagen möchte, dass es die aktuelle JMenuBar und das aktuelle Panel wegschmeißen soll (mit remove() ), dann kommt diese Fehlermeldung:

Die Fehlermeldung

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.awt.Container.remove(Unknown Source)
at javax.swing.JFrame.remove(Unknown Source)
at gui.EshopGUIclient.tauschePaneluMenuBar(EshopGUIclient.java:84)
at gui.LoginMenue$LoginListener.actionPerformed(LoginMenue.java:116)
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.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)

Also alle Informationen die ich aus dieser Meldung gewinnen kann sind, dass ich irgendwie nicht auf das Frame Objekt zugreifen kann (bzw. es wohl keinen Wert hat) und er die Quelle garnicht kennt von der er das entfernen soll.
Und ich keine Idee mehr hab wie ich ihm das sagen soll.
Da kommt ihr ins Spiel ;)

Ach P.S. ich lese am Anfang eine externe Textdatei ein mit allen angemeldeten Usern.

Hier nochmal die relevanten Quellcodes dazu:

Hauptklasse
package gui;

import javax.swing.*;

import java.awt.*;
import java.util.*;
import java.awt.event.*;

import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.tree.*;

import value.Kunde;
import value.Nutzer;

import java.io.*;
import java.net.*;

import logik.Shopmanager;
import gui.StartMenueBar;

public class EshopGUIclient extends JFrame {

private Shopmanager shopmanager;
protected Nutzer aktuellEingelogterUser;
private JPanel aktuellesPanel;
private JMenuBar aktuelleMenuBar;
private StartMenueBar startMenuBar;
private MitarbeiterMenueBar staffMenu;
private LoginMenue loginScreen;
private RegistrierungsMenue regMenu = new RegistrierungsMenue();
private MitarbeiterMenueBar mMenu;
private PanelKunden pKunden;
private PanelMitarbeiter pMitarbeiter;


public EshopGUIclient(){

}

public EshopGUIclient(String datei) {

super("MET");
shopmanager = new Shopmanager(datei);
createStartScreen();

}

public void createStartScreen() {
startMenuBar = new StartMenueBar();
aktuellesPanel = new JPanel();
aktuelleMenuBar = new JMenuBar();
startMenuBar = new StartMenueBar();
loginScreen = new LoginMenue();

aktuelleMenuBar = startMenuBar.createStartMenuBar();
aktuellesPanel = loginScreen.createLoginMenu();

this.setSize(800, 680);

JLabel Logo = new JLabel(new ImageIcon("Logo2.jpg"));
this.getContentPane().setLayout(new BorderLayout());


this.setJMenuBar(aktuelleMenuBar);


Logo.setSize(800, 200);
this.add(Logo, BorderLayout.NORTH);
this.add(aktuellesPanel, BorderLayout.CENTER);





this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

}

public void tauschePaneluMenuBar(JMenuBar bar,JPanel aPanel){

this.remove(aktuellesPanel);//aktuelles Panel abmelden
//this.getContentPane().remove(aktuellesPanel); //alternativ Panel abmelden
this.remove(aktuelleMenuBar); //aktuelle Menü Bar abmelden
//this.getJMenuBar().remove(aktuelleMenuBar); //alternativ MenuBar abmelden
this.setJMenuBar(bar); //neue MenuBar anmelden
this.add(aPanel,BorderLayout.CENTER); //neues Panel anmelden
this.setVisible(true);
this.validate();
aktuelleMenuBar = bar;
aktuellesPanel = aPanel;

}

public static void main(String[] args) {

JFrame myFrame = new EshopGUIclient("Shop");
//run.regMenu.createRegMenu();

}


}


Die Klasse die das am Anfang erscheinende Login Panel und den Listener für den Login Button verwaltet
package gui;





import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import logik.Shopmanager;
import value.Kunde;
import value.Nutzer;

public class LoginMenue extends JPanel {

private EshopGUIclient eshopClient = new EshopGUIclient();
private Shopmanager loginShopmanager = new Shopmanager("Shop");
protected JButton loginButton;
private JButton registrierenButton;
private JLabel nameLabel;
protected JTextField nameField;
private JLabel passLabel;
protected JTextField passField;
private KundenMenueBar kMenu;
private PanelKunden pKunden;
private MitarbeiterMenueBar mMenu;
private PanelMitarbeiter pMitarbeiter;




public JPanel createLoginMenu() {

JPanel PanelLogin = new JPanel(new GridLayout(20, 1));



nameLabel = new JLabel("Geben sie Ihren Namen ein!");
nameField = new JTextField(20);

passLabel = new JLabel("Geben sie Ihr Kennwort ein!");
passField = new JTextField(20);

// Leere Labels fürs Design
JLabel leer = new JLabel("");
JLabel leer2 = new JLabel("");
JLabel leer3 = new JLabel("");
JLabel leer4 = new JLabel("");
JLabel leer5 = new JLabel("");
JLabel leer6 = new JLabel("");
JLabel leer7 = new JLabel("");
JLabel leer8 = new JLabel("");
JLabel leer9 = new JLabel("");
JLabel leer10 = new JLabel("");
JLabel leer11 = new JLabel("");
JLabel leer12 = new JLabel("");
JLabel leer13 = new JLabel("");

// Login Button und Action Listener
loginButton = new JButton("Login");
loginButton.addActionListener(new LoginListener());



registrierenButton = new JButton("Registrieren");

PanelLogin.add(leer);
PanelLogin.add(leer2);
PanelLogin.add(leer3);
PanelLogin.add(nameLabel);
PanelLogin.add(nameField);
PanelLogin.add(leer4);
PanelLogin.add(passLabel);
PanelLogin.add(passField);

PanelLogin.add(leer5);
PanelLogin.add(leer6);
PanelLogin.add(leer7);
PanelLogin.add(leer8);
PanelLogin.add(leer9);
PanelLogin.add(leer10);
PanelLogin.add(leer11);
PanelLogin.add(loginButton);
PanelLogin.add(leer12);
PanelLogin.add(leer13);

PanelLogin.add(registrierenButton);

return PanelLogin;

}

class LoginListener implements ActionListener{

public void actionPerformed(ActionEvent login){
if(login.getSource().equals(loginButton)){

//ID und Namen aus dem Eingabemakse holen und Login vorgang öffnen
int id = Integer.parseInt(nameField.getText());
String name = passField.getText();
System.out.println(id);
System.out.println(name);
Nutzer user = loginShopmanager.LogIn(name, id);

if (user instanceof Kunde) {

eshopClient.aktuellEingelogterUser = user;
kMenu = new KundenMenueBar();
pKunden = new PanelKunden();
eshopClient.tauschePaneluMenuBar(kMenu.kundenMenue(),pKunden.createPanelKunden());

}
else {
eshopClient.aktuellEingelogterUser = user;
pMitarbeiter.createPanelMitarbeiter();
//eshopClient.tauschePanel();
}

}

}

}

}

Das Kunden Panel was erstellt wird.

package gui;

import javax.swing.JLabel;
import javax.swing.JPanel;


public class PanelKunden extends JPanel{

private EshopGUIclient eshopClient = new EshopGUIclient();

public JPanel createPanelKunden(){
JPanel pKunden = new JPanel();
JLabel kundenLabel = new JLabel("Willkommen "+eshopClient.aktuellEingelogterUser);
pKunden.add(kundenLabel);

return pKunden;
}

}

Die JMenuBar die erstellt wird

package gui;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class KundenMenueBar extends JMenuBar{

public JMenuBar kundenMenue(){

//Karteikarte Datei
JMenuBar kundenMenue = new JMenuBar();

JMenu fileMenu = new JMenu("Datei");
kundenMenue.add(fileMenu);
JMenuItem speichernItem = new JMenuItem("Speichern");
JMenuItem beendenItem = new JMenuItem("Beenden");
fileMenu.add(speichernItem);
fileMenu.addSeparator();
fileMenu.add(beendenItem);

//Karteikarte Warenkorb
JMenu artikelVerwaltung = new JMenu("Warenkorb");
kundenMenue.add(artikelVerwaltung);

JMenuItem kaufen = new JMenuItem("Kaufen");
artikelVerwaltung.add(kaufen);
artikelVerwaltung.addSeparator();

JMenuItem warenkorbAnzeigen = new JMenuItem("Warenkorb anzeigen");
artikelVerwaltung.add(warenkorbAnzeigen);
artikelVerwaltung.addSeparator();


//Karteikarte Persönlicher Bereich
JMenu persoenlicherBereich = new JMenu("Persönlicher Bereich");
kundenMenue.add(persoenlicherBereich);

JMenuItem persoenlicherBereichItem = new JMenuItem("Persönlicher Bereich");
persoenlicherBereich.add(persoenlicherBereichItem);

//Karteikarte Logout
JMenu logout = new JMenu("Logout");
kundenMenue.add(logout);

JMenuItem logoutItem = new JMenuItem("Logout");
logout.add(logoutItem);

return kundenMenue;
}



}


Danke schon ma im Vorraus, vorallem für das Lesen des vielen Textes ;)
 

Anhänge

  • gui_login.jpg
    gui_login.jpg
    64,9 KB · Aufrufe: 77

Kai008

Erfahrenes Mitglied
Die Exception signalisiert, dass eine Variable, auf die zugegriffen wird, auf keine Instanz verweißt. Alternativ wird sie auch oft gethrowt wenn ein Argument null ist.
Laut StackTrace übergibst du remove eine solche Variable. Gehe in die Methode tauschePaneluMenuBar in der Klasse EshopGUIclient.in Zeile 84, gehe rückwärts durch und finde heraus wo du die Variable setzen solltest.
 

Carron

Mitglied
Hi gendadon,

in besagter Zeile wird
Java:
this.remove(aktuelleMenuBar); //aktuelle Menü Bar abmelden
aufgerufen, wobei du die JMenuBar mit
Java:
this.setJMenuBar(bar); //neue MenuBar anmelden
setzt und sie auch nicht von Hand entfernen musst (und wenn doch, dann nur mit setJMenuBar(null).


Grüße
Carron

PS: die Verwendung von [JAVA] statt [CODE] Tags, macht das Lesen einfacher ;)
 

gendadon

Grünschnabel
Erstmal vielen dank für die schnellen Antworten und die Denkanstöße.
Ich hab die beiden Tipps von euch mal berücksichtigt und bin sogar zu einem ersten Ergebnis gekommen.
Und zwar kann ich nun die Panels austauschen.
Ich habs so angestellt, dass ich das erstellte Frame (bzw. die Referenz) in der Hauptklasse nun einfach an die jeweilige Klasse mitgebe, dort (wie oben auch schon) die JMenuBar und das JPanel erstelle und dann einfach das JFrame, JPanel und die JMenuBar an die Methode tauschePaneluMenuBar weitergebe und in der Methode das JFrame wieder zusammenbaue.
Also wie gesagt das austauschen der Panels klappt, nun hab ich zwar noch ein paar kleine Schönheitsfehler, weil die Buttons nicht verschwinden wollen.
Aber ich denke mal das wird ein eher kleiners Problem.

Hier nochmal zur Übersicht die Änderungen in den Klassen:

Hauptklasse

vorher
PHP:
public void createStartScreen() {
startMenuBar = new StartMenueBar();
aktuellesPanel = new JPanel();
aktuelleMenuBar = new JMenuBar();
startMenuBar = new StartMenueBar();
loginScreen = new LoginMenue();

aktuelleMenuBar = startMenuBar.createStartMenuBar();
aktuellesPanel = loginScreen.createLoginMenu();

nacher:

PHP:
public void createStartScreen() {
		
		startMenuBar = new StartMenueBar();
		loginScreen = new LoginMenue(this); //hier wird das JFrame mit this übergeben
...



Klasse die das am Anfang erscheinende Login Panel und den Listener für den Login Button verwaltet:

vorher oben:
PHP:
ganz ohne Konstrucktor und JFrame Objekt

nacher oben:
PHP:
...
private JFrame frame = new JFrame(); // JFrame erstellen um die Referenz abzufangen
	
	public LoginMenue(JFrame frame2){ // JFrame aus Hautklasse mitgegeben
		frame = frame2;
		createLoginMenu();
	}
...

vorher unten
PHP:
if (user instanceof Kunde) {

eshopClient.aktuellEingelogterUser = user;
kMenu = new KundenMenueBar();
pKunden = new PanelKunden();
eshopClient.tauschePaneluMenuBar(kMenu.kundenMenue(),pKunden.createPanelKunden());

nachr unten
PHP:
if (user instanceof Kunde) {
					eshopClient = new EshopGUIclient();
					eshopClient.aktuellEingelogterUser = user;
					kMenu = new KundenMenueBar();
					pKunden = new PanelKunden();
					eshopClient.tauschePaneluMenuBar(frame,kMenu,pKunden); // hier wird das JFrame wieder zurück an die Hauptklasse übergebe


Nochmal in der Hauptklasse unten bei der Methode tauschePaneluMenuBar

vorher:
PHP:
public void tauschePaneluMenuBar(JMenuBar bar,JPanel aPanel){

this.remove(aktuellesPanel);//aktuelles Panel abmelden
//this.getContentPane().remove(aktuellesPanel); //alternativ Panel abmelden
this.remove(aktuelleMenuBar); //aktuelle Menü Bar abmelden
//this.getJMenuBar().remove(aktuelleMenuBar); //alternativ MenuBar abmelden
this.setJMenuBar(bar); //neue MenuBar anmelden
this.add(aPanel,BorderLayout.CENTER); //neues Panel anmelden
this.setVisible(true);
this.validate();
aktuelleMenuBar = bar;
aktuellesPanel = aPanel;

}

nacher:
PHP:
public void tauschePaneluMenuBar(JFrame frame,JMenuBar bar,JPanel aPanel){//hier wird das Frame wieder mitgegeben und alles in das Frame gepackt
		
		loginScreen = new LoginMenue();
		//frame.invalidate();
		frame.remove(loginScreen);//aktuelles Panel abmelden
		frame.setJMenuBar(bar); //neue MenuBar anmelden
		frame.add(aPanel,BorderLayout.CENTER); //neues Panel anmelden
		frame.validate();
		frame.setVisible(true);
	
	}
 
Zuletzt bearbeitet:

Carron

Mitglied
Hi gendadon,

ich hatte jetzt nur kurz Zeit mal über deinen Code drüberzuschauen (die [JAVA] Tags hast du offenbar immer noch nicht ganz entdeckt ;))

auf die Schnelle würde ich folgende Methode hinterfragen:

nacher:
PHP:
public void tauschePaneluMenuBar(JFrame frame,JMenuBar bar,JPanel aPanel){//hier wird das Frame wieder mitgegeben und alles in das Frame gepackt
		
		loginScreen = new LoginMenue();
		//frame.invalidate();
		frame.remove(loginScreen);//aktuelles Panel abmelden
		frame.setJMenuBar(bar); //neue MenuBar anmelden
		frame.add(aPanel,BorderLayout.CENTER); //neues Panel anmelden
		frame.validate();
		frame.setVisible(true);
	
	}

Wenn du dir erst eine neue Instanz erzeugst loginScreen = new LoginMenue(); und diese neue (nirgendwo anliegende) Komponente gleich wieder mit frame.remove(loginScreen); versucht zu entfernen, sehe ich nicht viel Nutzen. Zumal die alte loginScreen-Instanz unverändert im Fenster verweilt.


Viele Grüße
Carron
 

gendadon

Grünschnabel
Warte Test:

Java:
public class JavaTagKlasse{

public static void main(String args[]){

System.out.println("Hi, Carron ");
}

}

:)


Aber mit dem Post von dir haste recht, dass war quasi son Placebo löschen, habs auch schon behoben und lösche das Panel nun anders und es funktioniert sogar ^^
Aber danke für den Hinweis .
Sag ich doch ist ein geniales Forum, Probem vor 2 Tagen gepostet und auch gleich gelöst.
Ich glaub wenn ihr weiblich wärt, dann würde ich euch aufn Eis einladen, aber so müsst ihr euch mit einem Danke begnügen :) :)