我正在开发一个游戏,用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 必须切换面板。
//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
}