Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
habe ein JMenu erstellt und versuche es jetzt mit dem ActionListener anzusprechen! Leider funzt das nicht so ganz wie es soll! Kann mir vllt jemand helfen?
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui extends JFrame implements ActionListener {
public Gui() {
setSize(500,500);
setLocation(10,10);
//Menü anlegen im ersten Panel p
JPanel p = new JPanel();
JMenuBar mb = new JMenuBar();
JMenu d = new JMenu("Datei");
JMenuItem l = new JMenuItem("LogIn");
JMenuItem s = new JMenuItem("Suche");
JMenuItem b = new JMenuItem("beenden");
d.add(l);d.add(s);d.add(b);
mb.add(d);
p.add(mb);
add(p);
setVisible(true);
}
public void ActionPerformed(ActionEvent e) {
if (e.equals(l)) {
JLabel l1 = new JLabel("Benutzername");
JLabel l2 = new JLabel("Passwort");
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
p1.add(l1);p1.add(t1);
p2.add(l2);p2.add(t2);
add(p1);add(p2);
}
}
}
dein Code beinhaltet leider relativ viele Fehler. Das zeigt das du noch nicht so viel erfahrung im Bereich Java und Swing hast. Aber kein Problem (und keinesfalls negativ gemeint!) - jeder war mal Anfänger. ;-)
Bringen wir erstmal deinen Code dazu zu kompilieren...
Code:
public void ActionPerformed(ActionEvent e) {
Hier hast du dich vertippt - es muss heißen actionPerformed - also mit kleinem a.
Code:
if (e.equals(l)) {
Die Variable l existiert in diesem Scope nicht. Deklarierst du zwischen { und } eine Variable, ist diese nach der schliessenden Klammer nicht mehr zugänglich.
Genau das ist dir hier passiert. Im Konstruktor hast du mit "JMenuItem l" die Variable deklariert. Daher ist sie im Konstruktor auch gültig - nicht aber in allen anderen Methoden. Um dies zu korrigieren muss du die Variable l als Klassenvarible deklarieren. Das bedeutet:
Code:
public class Gui extends JFrame implements ActionListener {
JMenuItem l;
und dort wo du zuvor diese Variable deklariert hattest steht jetzt nur noch:
Code:
l = new JMenuItem("LogIn");
Jetzt lässt sich dein Code übersetzen.
Wenn du diesen Code jetzt ausprobierst, wirst du sehen das er leider nicht das tut was er soll. Auch sollte dir auffallen das die Menuleiste irgendwie nicht am richtigem Platz ist.
Ein Menü fügt man i.A. nicht einem JPanel sondern einem JFrame hinzu. Auch packt man ein Menü nicht in den Layoutmanager - sondern nutzt dazu die Mehtode setJMenuBar() des JFrame. Lösche also die Zeile "p.add(mb);" und ersetze sie durch "setJMenuBar(mb);". Jetzt ist dein Menü am richtigem Platz.
Da jetzt erst einmal alles an seinem Platz ist, kommen wir nun zu den ActionListener. Wie du bemerkt hast passiert nix wenn du auf deinen Menüeintrag klickst. Dies liegt daran das du jedem Menueintrag (und jedem Button, etc. pp.) sagen musst welchen ActionListener er aufrufen soll, wenn er geklickt wird.
Da du einen ActionListener selbst bereits mit der Methode actionPerformed() implementiert hast fehlt nur noch dem JMenuItem zu sagen das er eben diesen Aufrufen soll. Dazu fügst du in den Konstruktor nach der Zeile "l = new JMenuItem("LogIn");" einfach folgendes ein:
Code:
l.addActionListener(this);
Dein Code sollte jetzt etwa wie folgt aussehen. Ich habe alle JMenuItem zu Klassenvariablen gemacht und eine main-Methode zum schnelleren Testen hinzugefügt. Auch habe ich ein System.out.println() eingefügt damit man sehen kann ob die Methode actionPerformed() aufgerufen wird.
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui extends JFrame implements ActionListener {
JMenuItem l, s, b;
public Gui() {
setSize(500,500);
setLocation(10,10);
//Menü anlegen im ersten Panel p
JPanel p = new JPanel();
JMenuBar mb = new JMenuBar();
JMenu d = new JMenu("Datei");
l = new JMenuItem("LogIn");
l.addActionListener(this);
s = new JMenuItem("Suche");
s.addActionListener(this);
b = new JMenuItem("beenden");
b.addActionListener(this);
d.add(l);d.add(s);d.add(b);
mb.add(d);
add(p);
setJMenuBar(mb);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed...");
if (e.equals(l)) {
System.out.println("actionPerformed from JMenuItem l.");
JLabel l1 = new JLabel("Benutzername");
JLabel l2 = new JLabel("Passwort");
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
p1.add(l1);p1.add(t1);
p2.add(l2);p2.add(t2);
add(p1);add(p2);
}
}
public static void main(String[] args) { new Gui(); }
}
Wie du siehst, wenn du den Code ausführst, wird von jedem JMenuItem nun die Methode actionPerformed() gerufen. Allerdings macht sie noch nicht das was sie soll. Das bedeutet das der Vergleich "if(e.quals(l))" wohl nicht wie erwartet funktioniert. Das kann er auch nicht - den was vergleichst du hier? Du vergleichst ein Objekt vom Typ ActionEvent (Variable e) auf inhaltliche Gleichheit mit einem Objekt vom Typ MenuItem (Variable l). Das kann nicht gehen.
Um das Objekt zu bekommen das einen ActionEvent ausgelöst hat musst du die Methode getSource() der Klasse ActionEvent verwenden. Ersetzt du "if(e.equals(l))" durch "if(e.getSource().equals(l))" funktioniert auch dieser Vergleich wie erwartet - vorerst.
Überlege aber nochmal was du nun vergleichst und berücksichtige den Unterschied zwischen equals und ==. Equals ist dafür da auf inhaltliche Gleichheit zu testen wohingegen == auf gleiche Identität prüft. Das bedeutet das "new Integer(1000) == new Integer(1000)" nicht true ergibt denn beide Objekte haben zwar den gleichen Inhalt - liegen aber an verschiedenen stellen im Speicher.
In deinem Fall verwendest du equals um die beiden Objekte zu vergleichen. Nun könnte es aber theoretisch sein das es zwei oder mehr JMenuItem in deinem Programm gibt die inhaltlich Gleich sind. Ich denke das ist nicht was man hier möchte. Hier möchtest du die Identität überprüfen - daher musst du == verwenden.
Code:
if(e.getSource() == l) {
Wie du aber siehst funktioniert zwar dieser Vergleich nun, aber es wird immer noch kein Login-Bereich angezeigt.
Aber wieder eine Frage - was soll beim Klick auf Login eigentlich passieren? Stell dir vor der Benutzer würde zweimal nacheinander auf Login klicken (Benutzer tun soetwas!). Es würde zweimal ein Login-Bereich erstellt werden. Du hättest, würde deine Implementierung funktionieren, also nach jedem Klick einen weiteren Login-Bereich. Das willst du nicht - oder?
Deshalb machen wir das etwas anders. Wir erstellen im Konstruktor jedes Panel (das zum Suchen, das für den Login, etc.) aber machen sie vorerst nicht sichtbar -> setVisible(false). Klickt der Benutzer nun auf z.B. Login so machen wir das normale Panel unsichtbar und das Login Panel sichtbar...
So... Schluss mit lustig - es folgt der umgeschriebene (und leicht ergänzte) Code deiner Anwendung. Ich hoffe du wirst ihn verstehen - ansonsten einfach nochmal Fragen:
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui extends JFrame {
JMenuItem loginMenuItem, searchMenuItem, exitMenuItem;
JPanel mainPanel, loginPanel, searchPanel;
public Gui() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,300);
// Das Fenster schön zentriert einblenden...
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation( (dimension.width - getSize().width)/2, (dimension.height - getSize().height)/2 );
Box mainbox = Box.createVerticalBox();
// Das Main-Panel (das was normalerweise angezeigt wird)
mainPanel = new JPanel();
mainPanel.add(new JLabel("Main Panel"));
mainbox.add(mainPanel);
// Das Login-Panel (wird angezeigt wenn der Benutzer auf Login klickt)
loginPanel = new JPanel();
Box horizontalBox = Box.createHorizontalBox();
Box verticalBox1 = Box.createVerticalBox();
verticalBox1.add(new JLabel("Benutzername"));
verticalBox1.add(new JTextField());
horizontalBox.add(verticalBox1);
horizontalBox.add(Box.createHorizontalStrut(10));
Box verticalBox2 = Box.createVerticalBox();
verticalBox2.add(new JLabel("Passwort"));
verticalBox2.add(new JTextField());
horizontalBox.add(verticalBox2);
loginPanel.add(horizontalBox);
loginPanel.setVisible(false); // Soll ja erst später angezeigt werden.
mainbox.add(loginPanel);
// Das Search-Panel (wird angezeigt wenn der Benutzer suchen möchte)
mainbox.add(Box.createVerticalGlue());
searchPanel = new JPanel();
searchPanel.add(new JLabel("Search Panel"));
searchPanel.setVisible(false); // Soll auch später erst angezeigt werden.
mainbox.add(searchPanel);
// Die Menüleiste
JMenuBar menubar = new JMenuBar();
setJMenuBar(menubar);
// Das Datei-Menü
JMenu fileMenu = new JMenu("Datei");
loginMenuItem = new JMenuItem("LogIn");
searchMenuItem = new JMenuItem("Suche");
exitMenuItem = new JMenuItem("beenden");
fileMenu.add(loginMenuItem);
fileMenu.add(searchMenuItem);
fileMenu.add(exitMenuItem);
menubar.add(fileMenu);
// Die ActionListener für das Datei-Menü
loginMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainPanel.setVisible(loginPanel.isVisible());
loginPanel.setVisible(!loginPanel.isVisible());
}});
searchMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
loginPanel.setVisible(false);
mainPanel.setVisible(true);
searchPanel.setVisible(!searchPanel.isVisible());
}});
exitMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(JOptionPane.showConfirmDialog(getRootPane(), "Programm beenden?") == JOptionPane.YES_OPTION)
System.exit(0);
}});
add(mainbox);
setVisible(true);
}
public static void main(String[] args) { new Gui(); }
}
Wie kann ich den Code vom SearchPanel in ne neue Klasse schreiben? Bzw. was muss ich da genau beachten?
Je mehr Menüpunkte ich habe, umso unübersichtlicher wird das Ganze ja!!
Danke + Grüße, Jule
Hier der Code für die neue Klasse:
Code:
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class searchPanel {
JPanel searchPanel;
public searchPanel() {
searchPanel = new JPanel();
JLabel Info = new JLabel("Übersicht über alle Mitglieder");
JButton Uebersicht = new JButton("Anzeigen");
searchPanel.add(Info);
searchPanel.add(Uebersicht);
searchPanel.setVisible(false); // Soll auch später erst angezeigt werden.
}
}
so kann ich es leider nicht im Panel einfügen
Code:
searchPanel p= new searchPanel();
mainbox.add(p);
Wie kann ich das ganze also in die mainbox einfügen??
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class searchPanel extends JPanel {
public searchPanel() {
JLabel Info = new JLabel("Übersicht über alle Mitglieder");
JButton Uebersicht = new JButton("Anzeigen");
add(Info);
add(Uebersicht);
setVisible(false); // Soll auch später erst angezeigt werden.
}
}
Du musst einfach nur von einem JPanel ableiten (so wie du auch von JFrame abgeleitet hast).