如何从 JPanel 切换到另一个

问题描述 投票:0回答:1

我正在开发一个游戏,用java swing编写。 我创建了一个扩展 JFrame 的 MainGUI 类,以包含应用程序的多个屏幕。在其他类中,我创建了不同的 JPanel,例如 StartPanel 和 GamePanel,它们在执行期间插入到 MainGUI 中。在开始面板中,当用户输入昵称时,可以通过按钮切换到游戏面板。

问题是我无法切换面板。 我尝试使用 CardLayout,但是当我按下面板中的按钮时,我无法处理 MainGUI 中的事件并显示不同的面板。

我使用了MVC设计模式,因此有3个包(控制器、模型、视图)可以相互通信,这要归功于实现了相关接口的类ControllerForModel、ControllerForView、View和Model。

应用程序的启动得益于控制器包中的 Main 类。

package frogger.view;

import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainGUI extends JFrame {

    //---------------------------------------------------------------
    // STATIC FIELDS
    //---------------------------------------------------------------
    
    public MainGUI(String title) {
        super(title);
        
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        StartPanel startPane = new StartPanel();
        
        Container contPane = this.getContentPane();
        contPane.add(startPane);

        this.pack();
    } //end constructor
    

这是MainGUI类的代码,它只显示StartPanel。

package frogger.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class StartPanel extends JPanel {
    
    //---------------------------------------------------------------
    // CONSTANTS FIELDS
    //---------------------------------------------------------------
    private final static String LOGO_PATH = "img/logo.png";
    
    
    //---------------------------------------------------------------
    // STATIC FIELDS
    //---------------------------------------------------------------
    private static Image logoImg;
    
    private static JLabel logoLabel;
    private static JLabel newGameLabel;
    private static JLabel loadGameLabel;
    private static JLabel newGameLabelInCurrentDisplayedPanel;

    private static JButton newGameButton;
    private static JButton loadGameButton;
    private static JButton newGameButtonInCurrentDisplayedPanel;
    
    private static JTextField nicknameTextField;
    
    private static JPanel currentDisplayedPanel;
    
    public StartPanel() {
        //todo
        super();
        this.setLayout(new GridBagLayout());
        
        loadImage(LOGO_PATH);
        this.logoLabel = new JLabel(new ImageIcon(this.logoImg.getScaledInstance(400, 200, Image.SCALE_SMOOTH)));
        locateLogoLabel();
        
        this.newGameLabel = new JLabel("Start a new game:");
        locateNewGameLabel();
        
        this.newGameButton = new JButton("New");
        this.newGameButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                handleShowNewGamePanelEvent();
            }
        });
        locateNewGameButton();
        
        this.loadGameLabel = new JLabel("Load a previously saved game:");
        locateLoadGameLabel();
        
        this.loadGameButton = new JButton("Load");
        this.loadGameButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                handleShowLoadGamePanelEvent(e);
            }
        });
        locateLoadGameButton();
        
        this.currentDisplayedPanel = new JPanel(new GridBagLayout());
        this.currentDisplayedPanel.setPreferredSize(new Dimension(400, 100));
        locateCurrentDisplayedPanel();
        
    } //end constructor

    
    //---------------------------------------------------------------
    // INSTANCE METHODS
    //---------------------------------------------------------------
    private void handleNewGameEvent() {
        //todo
    }
    
    private void handleLoadGameEvent() {
        //todo  
    }
    
    private void handleShowNewGamePanelEvent() {
        System.out.println("New game button pressed");
        
        this.newGameLabelInCurrentDisplayedPanel = new JLabel("Inserisci il tuo nickname:");
        locateNewGameLabelInCurrentDisplayedPanel();
        
        this.nicknameTextField = new JTextField(15);
        locateNicknameTextFieldInCurrentDisplayedPanel();
        
        this.newGameButtonInCurrentDisplayedPanel = new JButton("Conferma");
        this.newGameButtonInCurrentDisplayedPanel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                handleNewGameEvent();
            }
        });
        locateNewGameButtonInCurrentDisplayedPanel();
        
        
        this.currentDisplayedPanel.revalidate();
        this.currentDisplayedPanel.repaint();
        
    }
    
    private void handleShowLoadGamePanelEvent() {
        System.out.println("Load game button pressed");
    }
    
} //end class

这是StartPanel的代码。

package frogger.controller;

import frogger.view.MainGUI;

public class Main {
    
    public static void main(String[] args) {
        ControllerForView.getInstance().openGameWindow();
    }
}

这是启动应用程序的 Main 类的代码。

问题是:当用户按下newGameButton时,如何从StartPanel切换到GamePanel?换句话说,我如何实现handleNewGameEvent()方法来与MainGUI对话?

先谢谢大家了

我尝试在 MainGUI 中使用 CardLayout 来显示一个面板和另一个面板,但我不知道如何与 MainGUI 进行通信,当用户单击使用外部类描述的面板中的按钮时,该 MainGUI 必须切换面板。

java swing cardlayout
1个回答
0
投票
//So you should use 'setVisible methode that comes with most components in 
swing'
import javax.swing.*;
import java.awt.*;

  //Main class with an instance of mainGUI
  public class Main {
public static void main(String[] args) {
    MainGUI mainGUI=new MainGUI("Test");
}


}
/*In the mainGUI I put the JFrame to save time*/
class MainGUI extends JFrame{
PanelOne panelOne=new PanelOne();
PanelTwo panelTwo=new PanelTwo();
public MainGUI(String title) {
    super(title);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
    this.add(panelOne);
    this.add(panelTwo);
    this.pack();
} //end constructor
/*This is the methode that you should use to change between panels.
* In the method there is an array of all the panels you want to toggle, and 
it also accepts a panel as an argument.
* So how it works is that the for loop, loops through the array of panels 
and check if any of the panel matches the argument panel
* ,if they match then it will return true else false
* 
* EXAMPLE  setVisible = panelOne aka the argument
* for loop iteration 1
* panelOne.setVisible(panelOne == panelOne) so this becomes true
* 
* for loop iteration 2
 * panelTwo.setVisible(panelOne == panelTwo) so this becomes false
 * 
*  */
public void switchOff(JPanel setVisible){
    JPanel[] panels ={panelOne,panelTwo};
    for (JPanel panel:panels){
        panel.setVisible(panel == setVisible);
    }
}
}
//Just a standard panel to show u
class PanelOne extends JPanel {

PanelOne(){
    this.setPreferredSize(new Dimension(500,500));
    this.setBackground(Color.yellow);
} //end constructor
}
//same thing
class PanelTwo extends JPanel{
PanelTwo(){
    this.setPreferredSize(new Dimension(500,500));
    this.setBackground(Color.BLACK);
} //end constructor

}
© www.soinside.com 2019 - 2024. All rights reserved.