Mehrere Panels auf JFrame

HerrInfo

Mitglied
Hallo zusammen,

ich habe mehrere Panels auf einem JFrame und würde gerne zwischen ihnen mittels einer Methode wechseln. Leider funktioniert es nicht richtig, wenn ich setVisible(false) setze. Ich habe auch versucht, sie zu entfernen, aber dann werden die neuen Panels nicht angezeigt, sondern laufen nur im Hintergrund. Habt ihr eine Idee für eine Lösung? Hier ist der entsprechende Code:
Java:
package net.tim.gui;

import net.tim.core.Verwaltung;

import javax.swing.*;

public class Frame extends JFrame {
    Verwaltung verwaltung;

    public GamePanel gamePanel = new GamePanel(this);
    GlassPanel glassPanel = new GlassPanel(gamePanel);
    MenuPanel menuPanel = new MenuPanel(this);
    public Frame(Verwaltung verwaltung) {
        this.verwaltung = verwaltung;

        setTitle("A* Pathfinding");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(GamePanel.screenWidth, GamePanel.screenHeight);
        setResizable(false);

        add(gamePanel);

        setGlassPane(glassPanel);
        getGlassPane().setVisible(true);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void gameEnd(){
        glassPanel.gameEnd = true;
        glassPanel.repaint();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        switchToMenu();
    }

    public void switchToMenu(){
        remove(gamePanel);
        glassPanel.setVisible(false);
        add(menuPanel.panel);

        System.out.println("Switched to menu");
    }

    public void switchToGame(){
        menuPanel.panel.setVisible(false);

        gamePanel = new GamePanel(this);
        add(gamePanel);

        remove(menuPanel.panel);



        glassPanel.setVisible(true);
        glassPanel.gameEnd = false;
        glassPanel.repaint();

        Verwaltung.gameRunning = true;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        verwaltung.startGame();
    }

    public void switchToShop(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
    }

    public void switchToSettings(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
    }

    public void switchToCredits(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
        menuPanel.panel.setVisible(false);
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Also generell sollte es funktionieren. Aber was mir etwas ins Auge fällt ist dein Thread.sleep mit den Aufrufen von Methoden in verwaltung.

Kann es sein, dass Du den UI Thread blockierst und daher wird einfach das Fenster nicht neu gemalt?
Bei UI Anwendungen gilt generell:
a) Nie den UI Thread blockieren - länger laufende Dinge immer in einem separaten Thread durchführen.
b) Nie UI Komponenten außerhalb des UI Threads verändern

Und gegen eine der Regeln verstößt Du in switchToGame auf jeden Fall.
 

KonradN

Super-Moderator
Mitarbeiter
Neben den ersten Hinweis noch zusätzlich ein weiterer Hinweis:
Evtl. reicht das unsichtbar machen nicht - nicht dass es da noch Probleme gibt, weil ein unsichtbares Control womöglich noch den Fokus hat oder einen Mausclick abfangen kann. Daher würde ich vorsichtshalber auch setEnabled aufrufen mit false beim verstecken und true beim sichtbar machen.
Aus der Dokumentation:
Sets whether or not this component is enabled. A component that is enabled may respond to user input, while a component that is not enabled cannot respond to user input.
 

HerrInfo

Mitglied
Erst einmal vielen Dank für die schnelle Antwort. Ich habe das gesamte Layout jetzt mit CardLayout umgesetzt, aber es passiert immer noch nichts, nachdem der Start-Game Button gedrückt wurde. Das Panel wechselt immer noch nicht. Hier ist der aktualisierte Code:
Java:
package net.tim.gui;

import net.tim.core.Verwaltung;

import javax.swing.*;
import java.awt.*;

public class Frame extends JFrame {
    Verwaltung verwaltung;

    public GamePanel gamePanel = new GamePanel(this);
    GlassPanel glassPanel = new GlassPanel(gamePanel);
    MenuPanel menuPanel = new MenuPanel(this);
    CardLayout cardLayout = new CardLayout();
    public Frame(Verwaltung verwaltung) {
        this.verwaltung = verwaltung;
        setLayout(cardLayout);

        setTitle("A* Pathfinding");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(GamePanel.screenWidth, GamePanel.screenHeight);
        setResizable(false);

        add(gamePanel, "game");
        add(menuPanel.panel, "menu");

        setGlassPane(glassPanel);
        getGlassPane().setVisible(true);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void gameEnd(){
        glassPanel.gameEnd = true;
        glassPanel.repaint();

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        switchToMenu();
    }

    public void switchToMenu(){
        glassPanel.setVisible(false);
        cardLayout.show(getContentPane(), "menu");

        System.out.println("Switched to menu");
    }

    public void switchToGame(){
        glassPanel.setVisible(true);
        glassPanel.gameEnd = false;
        glassPanel.repaint();

        cardLayout.show(getContentPane(), "game");

        Verwaltung.gameRunning = true;
        verwaltung.startGame();
    }

    
    //Ab hier ignorieren
    public void switchToShop(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
    }

    public void switchToSettings(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
    }

    public void switchToCredits(){
        remove(menuPanel.panel);
        glassPanel.setVisible(false);
        menuPanel.panel.setVisible(false);
    }
}

So sieht es dann aus und die GUI reagiert nicht mehr.
 

Anhänge

  • Bild_2024-03-01_153005355.png
    Bild_2024-03-01_153005355.png
    20,7 KB · Aufrufe: 0

mihe7

Top Contributor
Beim CardLayout musst Du nichts removen. Du addest einmal Deine Panels und kannst dann einfach hin und her wechseln.

Und ja, wie @KonradN schon geschrieben hat: UI blockieren = nix gut.

Java:
import javax.swing.*;
import java.awt.*;

public class Frame extends JFrame {

    private JPanel gamePanel = new JPanel(new BorderLayout());
    JPanel menuPanel = new JPanel(new BorderLayout());
    CardLayout cardLayout = new CardLayout();
    Thread endGameThread;

    public Frame() {
        setLayout(cardLayout);

        JButton startGameButton = new JButton("Start Game");
        startGameButton.addActionListener(e -> switchToGame());
        menuPanel.add(startGameButton, BorderLayout.SOUTH);
        menuPanel.add(createLabel("MENU"));

        JButton endGameButton = new JButton("End Game");
        endGameButton.addActionListener(e -> gameEnd());
        gamePanel.add(endGameButton, BorderLayout.SOUTH);
        gamePanel.add(createLabel("GAME"));

        setTitle("A* Pathfinding");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);
        setResizable(false);

        add(gamePanel, "game");
        add(menuPanel, "menu");

        setLocationRelativeTo(null);
        setVisible(true);
    }

    private JLabel createLabel(String text) {
        JLabel label = new JLabel(text);
        label.setFont(label.getFont().deriveFont(72f));
        label.setHorizontalAlignment(JLabel.CENTER);
        return label;
    }

    public void gameEnd() {
        if (endGameThread != null) {
            return;
        }

        endGameThread = new Thread(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // hier mal ignoieren...
            }

            endGameThread = null;
            switchToMenu();
        });

        endGameThread.start();
    }

    public void switchToMenu() {
        cardLayout.show(getContentPane(), "menu");
    }

    public void switchToGame() {
        cardLayout.show(getContentPane(), "game");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Frame());
    }
}
 

HerrInfo

Mitglied
Vielen Dank für die schnelle Antwort! Der blockierende Thread war in einer anderen Klasse, daher war er nicht direkt zu finden. Mit dem Code kann ich auch etwas anfangen, da ich nirgendwo ein sauberes Beispiel gefunden habe. Nochmals vielen Dank! Jetzt werde ich mich daran machen, den Code etwas aufzuräumen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F AWT mehrere Panels in einem Frame AWT, Swing, JavaFX & SWT 17
Thallius Swing Mehrere tausend "Panels" erstellen AWT, Swing, JavaFX & SWT 3
M Handling 1 Fenster mehrere Panels AWT, Swing, JavaFX & SWT 2
Java-Insel LayoutManager Ein GridBagLayout-Objekt für mehrere Panels? AWT, Swing, JavaFX & SWT 2
H Frames oder Panels für mehrere Ansichten? AWT, Swing, JavaFX & SWT 4
T GUI Steuerung (mehrere Panels) AWT, Swing, JavaFX & SWT 5
T Swing Mehrere Ausgaben in JTextArea AWT, Swing, JavaFX & SWT 2
S Mehrere Tabellen Zellen gleichzeitig färben AWT, Swing, JavaFX & SWT 5
Apfelbaum2005 Swing JFrame mehrere JPanels mit unterschiedlichen Formen hinzufügen AWT, Swing, JavaFX & SWT 1
K JavaFX unterschiedliche (mehrere Fenster) in seperater Main Methode AWT, Swing, JavaFX & SWT 26
I Scene Builder - mehrere Seiten AWT, Swing, JavaFX & SWT 6
P Swing Mehrere JLabels mit ImageIcon in JPanel lesen AWT, Swing, JavaFX & SWT 1
schoel27 Mehrere JButtons sollen das gleiche Event auslösen AWT, Swing, JavaFX & SWT 2
Z GUI Forms - Mehrere Fenster in einem Projekt AWT, Swing, JavaFX & SWT 18
M mehrere jTextField untereinander AWT, Swing, JavaFX & SWT 1
N Bilder auf Button einfügen und mehrmals ändern (ein Button, mehrere ActionListener) AWT, Swing, JavaFX & SWT 2
B Swing Sudoku: Laden / Speichern von Zahlen aus/in mehrere JTextFields aus/in eine(r) Textdatei AWT, Swing, JavaFX & SWT 9
M JavaFX JavaFX in mehrere Controller AWT, Swing, JavaFX & SWT 21
R mehrere buttons mit forschleife kreieren und individuell bearbeiten AWT, Swing, JavaFX & SWT 1
N JavaFX 1 Listener für mehrere ChoiceBoxen AWT, Swing, JavaFX & SWT 3
N Textdatei GUI, Text in Textarea anzeigen mehrere Zeilen AWT, Swing, JavaFX & SWT 1
temi JavaFX Mehrere Views mit Stage.setScene() oder mit Scene.setRoot()? AWT, Swing, JavaFX & SWT 7
P Swing Mehrere JPanels auf ein JFrame hinzufügen? AWT, Swing, JavaFX & SWT 2
T Swing Tetraeder - mehrere Punkte verbinden? - Ansätze gesucht AWT, Swing, JavaFX & SWT 2
K JavaFX in mehrere Controller aufteilen AWT, Swing, JavaFX & SWT 29
K JavaFX in mehrere Controller aufteilen AWT, Swing, JavaFX & SWT 0
stroggi Swing Mehrere transparentes Objekte (Grafiken) über einem Bild (JLabel) darstellen AWT, Swing, JavaFX & SWT 4
K Mehrere Linien zeichnen AWT, Swing, JavaFX & SWT 8
J JavaFX - mehrere Views, Model durchreichen AWT, Swing, JavaFX & SWT 10
it_is_all Swing Mehrere JComboBoxen - wie die versch. Boxen mit ItemStateChange auslesen? AWT, Swing, JavaFX & SWT 3
M Swing Mehrere Textfelder mit ScrollBars - Größe der Felder AWT, Swing, JavaFX & SWT 0
W JavaFX Mehrere Klassen in ein TableView AWT, Swing, JavaFX & SWT 6
L JavaFX Mehrere JavaFX Szenen mit einem Menü AWT, Swing, JavaFX & SWT 1
D Java FXML mehrere Fenster AWT, Swing, JavaFX & SWT 4
F JavaFX Mehrere Stages "managen" AWT, Swing, JavaFX & SWT 2
r4w Changelistener auf mehrere Textfelder AWT, Swing, JavaFX & SWT 5
H Swing + Paint: Mehrere Objekte zeichnen lassen AWT, Swing, JavaFX & SWT 3
S Swing Mehrere Modal-Dialoge übereinander AWT, Swing, JavaFX & SWT 5
T 2D-Grafik JFreeChart mehrere Y-Achsen AWT, Swing, JavaFX & SWT 2
C JavaFX mehrere Kreise nach Eingabeprozess ausgeben AWT, Swing, JavaFX & SWT 2
C Java FX Warnmeldung: Mehrere Fonts gehören derselben Familie und Stil AWT, Swing, JavaFX & SWT 2
J Mehrere JInternalFrame; GetValues AWT, Swing, JavaFX & SWT 1
JG12111989 mehrere Polyline-Objekte zeichnen AWT, Swing, JavaFX & SWT 3
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
V Tastatur KeyListener für mehrere Buttons AWT, Swing, JavaFX & SWT 1
K JavaFX Mehrere Cell Editors in einem TreeView Item AWT, Swing, JavaFX & SWT 2
KaffeeFan mehrere JTextField durchlaufen AWT, Swing, JavaFX & SWT 4
J Java -8 Action Listener für mehrere Buttons AWT, Swing, JavaFX & SWT 9
T Dynamisch mehrere Checkboxen anlegen AWT, Swing, JavaFX & SWT 2
G JavaFX Menü und mehrere Scenes AWT, Swing, JavaFX & SWT 16
R Swing Mehrere JTextFields mit einem Document Listener AWT, Swing, JavaFX & SWT 2
D Mehrere RadiButtons auswählar AWT, Swing, JavaFX & SWT 3
P Swing JTable mehrere Zeilen markieren AWT, Swing, JavaFX & SWT 1
M Mehrere Jpanel in einem JScrollPane (Layout) AWT, Swing, JavaFX & SWT 2
T JavaFX FXMLController für mehrere FXML? AWT, Swing, JavaFX & SWT 7
G mehrere Action-Abfolgen erfassen AWT, Swing, JavaFX & SWT 6
elischa JFrame über mehrere JPanel und Listener AWT, Swing, JavaFX & SWT 17
X Swing JPanel mehrere Ebenen zeichnen AWT, Swing, JavaFX & SWT 13
J Mehrere Hyperlinks "stilvoll" darstellen. AWT, Swing, JavaFX & SWT 1
G Mehrere Strings um Kreis zeichnen und positionieren AWT, Swing, JavaFX & SWT 0
S JavaFX Mehrere TreeTableView's synchron scrollen AWT, Swing, JavaFX & SWT 0
U Mehrere Oberflächeninstanzen seperat schließen AWT, Swing, JavaFX & SWT 5
J Rahmen um mehrere GUI Einzelteile AWT, Swing, JavaFX & SWT 2
S Layouts, mehrere Buttons nebeneinander AWT, Swing, JavaFX & SWT 2
M Mehrere Fenster innerhalb einer Application AWT, Swing, JavaFX & SWT 3
T Über mehrere Panel zeichnen AWT, Swing, JavaFX & SWT 2
M ActionListener für mehrere Klassen AWT, Swing, JavaFX & SWT 4
T [LWJGL] mehrere Displays? AWT, Swing, JavaFX & SWT 19
SexyPenny90 Mehrere Fenster AWT, Swing, JavaFX & SWT 2
Y Mehrere JSlider verlinken AWT, Swing, JavaFX & SWT 6
O Swing JLabel mehrere Zeilen AWT, Swing, JavaFX & SWT 2
P mehrere Rectangles per JButton AWT, Swing, JavaFX & SWT 9
B JToolBar dynamisch auf mehrere Zeilen erweitern AWT, Swing, JavaFX & SWT 2
Jats Zeichen auf mehrere JPanels AWT, Swing, JavaFX & SWT 7
G Mehrere Probleme mit Java's GUI AWT, Swing, JavaFX & SWT 6
G Mehrere Layoutprobleme AWT, Swing, JavaFX & SWT 2
Kenan89 JTable mehrere ListSelections AWT, Swing, JavaFX & SWT 2
M TextArea über mehrere Zeilen - wie Zeileanzahl abfragen? AWT, Swing, JavaFX & SWT 5
J Swing JDialog blokiert mehrere JFrames - soll aber nur den aufrufenden blockieren AWT, Swing, JavaFX & SWT 4
A mehrere Zeilen in GUi ausgeben AWT, Swing, JavaFX & SWT 2
N Mehrere Tasks nacheinander ausführen AWT, Swing, JavaFX & SWT 7
C SWT Mehrere Bilder in GUI laden AWT, Swing, JavaFX & SWT 5
propra Mehrere Objekte gleichzeitig verschieben AWT, Swing, JavaFX & SWT 7
M 2D-Grafik Mehrere Linien (nacheinander) übereinander Zeichnen AWT, Swing, JavaFX & SWT 6
M Mehrere JPanel nacheinander?! AWT, Swing, JavaFX & SWT 11
Furtano AWT mehrere Bilder in einen Frame zeichnen + Layout Manager AWT, Swing, JavaFX & SWT 10
K SWT Mehrere Einträge ins Clipboard legen AWT, Swing, JavaFX & SWT 2
C Swing Ein JFrame mehrere Ansichten AWT, Swing, JavaFX & SWT 8
C Swing Mehrere JSlider sollen aufeinander reagieren AWT, Swing, JavaFX & SWT 4
GUI-Programmer JFilechooser, mehrere Datein selektieren und Reihenfolge (2) AWT, Swing, JavaFX & SWT 8
S Mehrere JLists - Wie kennzeichnen? AWT, Swing, JavaFX & SWT 2
S Swing MVC Ein JFrame, mehrere JPanels AWT, Swing, JavaFX & SWT 6
J Mehrere JRadioButtons, aber nur 1 darf ausgewählt sein AWT, Swing, JavaFX & SWT 4
L Swing Mehrere Button die selbe Größe AWT, Swing, JavaFX & SWT 4
B AWT mehrere Fenster schließen AWT, Swing, JavaFX & SWT 8
I Wie mehrere JComboBoxen in Abhängigkeit einer anderen Box ändern? AWT, Swing, JavaFX & SWT 8
G mehrere JPanel in ein (vertikales) JScrollPane AWT, Swing, JavaFX & SWT 8
F Swing Mehrere Textfelder in Scrollpane einfügen und dann zum Scrollen bringen? AWT, Swing, JavaFX & SWT 4
GianaSisters Swing jTable - Feldtext soll mehrere Zeilen haben AWT, Swing, JavaFX & SWT 3
K JFileChooser mehrere Dateien markieren ohne STRG AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben