ich brauche dringend Hilfe, ich bin am Verzweifeln!
Ich bin dabei ein Programm zu schreiben. Ist ein Tetris-Spiel mit Hauptmenü. Ich habe mir also eine GUI für das Menü erstellt und dort Buttons eingebaut. Die Buttons sollen eine andere Menüseite (also einen neuen Frame) öffnen. Und das tun sie auch, kein Thema. Nur dann kommt mein Problem:
Ich möchte also den neuen Frame öffnen (kein Problem), dabei aber den ersten schließen, so dass nur der neue offen ist.
Dann habe ich im neuen Frame wieder einen Button, welcher wieder den ersten Frame öffnen und den aktuellen schließen soll.
Klingt ganz einfach, nur gibt es da einen Knackpunkt, an dem es bei mir scheitert:
Ich habe einen Class für den ersten Frame, eine für den zweiten Frame und in einem dritten Frame habe ich meine ActionListener und WindowListener, wo ich halt alle Aktionen von Buttons und die Fenster-Optionen für alle Frames regle. Daher kann ich aber auch nicht einfach sagen das „this“-Fenster disposed werden soll, weil ich ja den Frame in einer anderen Class erstellt habe.
Help me please
Ist mein Problem so nachvollziehbar? oder soll ich den Code noch hochladen?
Jein. Irgendwo müssen halt irgendwelche Referenzen woanders hingereicht werden, oder ggf. Listener woanders erstellt oder angehängt werden. Ein paar Zeilen Code (zumindest den Teil mit der Erstellung der Frames und der relevanten Listener) würde wohl nicht schaden. Aber vielleicht noch vorneweg: Für “Einstellungsfenster” verwendet man üblicherweise Dialoge: http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html Die kann man auch modal machen, dann erspart man sich vielleicht einiges von dem, was du beschreibst…
In deiner aktuellen GUI-Konstellation wäre auch denkbar, den Einstellungsdialog (Options) ein ein separates JPanel einzubauen (nicht in einen JFrame/JDialog) und dann mit CardLayout zu arbeiten.
Dann wäre alles immer im gleichen Fenster.
Da man davon ausgehen muss, dass das NICHT nur ein Test/Dummybeispiel ist:
Variablennamen klein schreiben
Variablen- und Klassennamen ohne_Unterstrich verwenden
Variablennamen verwenden, die mehr aussagen als “button1” usw. Warum nicht “startButton”, “menuButton”, “exitButton”…?
Von JFrame zu erben ist fast nie notwendig, und wenn es nicht notwendig ist, sollte man es auch nicht tun.
Abgesehen davon wird es SEHR schnell SEHR unübersichtlich, wenn man für alles einen Riesen-ActionListener verwendet, in dem per ActionCommand irgendwelche entscheidungen getroffen werden. Häufig kann man solche Funktionen mit Actions http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html besser umsetzen.
Die pragmatische Lösung für deine Frage wäre: Übergib’ eine Referenz auf den mainFrame an den ActionListener
public class ListenerAdapter implements WindowListener, ActionListener{
private MainFrame mainFrame;
public ListenerAdapter(MainFrame mainFrame)
{
this.mainFrame = mainFrame;
}
....
public void actionPerformed(ActionEvent e){
....
if(e.getActionCommand().equals("3")){
mainFrame.dispose(); // oder setVisible(false); ?
new Options_Frame();
}
}
aber das würde die schon etwas fragwürdige Struktur nicht besser machen. Stattdessen solltest du ggf. auf diese Listener-Klasse verzichten. Du könntest GROB sowas machen wie
public class MainFrame {
...
// Hier braucht man keine Button-Referenzen
...
public MainFrame() {
...
final JFrame window = new JFrame();
window.setTitle("Tetris");
...
JButton controlsButton = new JButton("Controls");
controlsButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
window.setVisible(false); // oder dispose();
new OptionsFrame();
}
});
somePanel.add(controlsButton);
....
window.setVisible(true);
}
}
Für dein eigentliches Problem (das weiterschalten zur nächsten Menüseite) solltest du dir mal das CardLayout ansehen. Es ist nicht notwendig einen neuen Frame zu erstellen. Guck dir mal das beispiel an das ich angehängt habe.
Außerdem mal ins Byte-Welt-Wiki gucken, da gibts ein CardLayout-Tutorial