java使用panel类中的button调用frame类中的ActionListener
我上周末开始编写CodigJava,我已经阅读了大部分基本内容。我试图将我的框架与主方法分离,并将面板与框架分离,以便它们都位于单独的类文件中。我在调用“框架1”类中的ActionLister时遇到问题,在“TheGame”类中使用按钮(buttonBack)。该按钮应触发监听器,监听器应依次移除游戏面板并将主菜单面板添加到frame1。我知道CardLayout更适合交换面板,但我想先了解一下限制和解决方法,然后再以“简单”的方式进行交换,我觉得这样可以学到更多
以下是我的一些代码:
主要内容:
public class Main {
public static void main(String[] args){
Frame1 frame1 = new Frame1();
frame1.frame1();
}
}
框架1:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
class Frame1 {
private JFrame frame1 = new JFrame("Name");
public void frame1() {
TheGame theGame = new TheGame();
MainMenu mainMenu = new MainMenu();
// Frame options
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setLocationRelativeTo(null);
// Creating a top menu
JMenuBar menubar = new JMenuBar();
frame1.setJMenuBar(menubar);
JMenu file = new JMenu("File");
menubar.add(file);
JMenu help = new JMenu("Help");
menubar.add(help);
JMenuItem exit = new JMenuItem("Exit");
file.add(exit);
JMenuItem about = new JMenuItem("About");
help.add(about);
// Creating action for the menuitem "exit".
class exitaction implements ActionListener{
public void actionPerformed (ActionEvent e){
System.exit(0);
}
}
exit.addActionListener(new exitaction());
// Creating listener for the menuitem "about".
class aboutaction implements ActionListener{
public void actionPerformed (ActionEvent e){
JDialog dialogabout = new JDialog();
JOptionPane.showMessageDialog(dialogabout, "Made by: ");
}
}
about.addActionListener(new aboutaction());
// Add the panels, pack and setVisible
theGame.theGame();
mainMenu.mainMenu();
frame1.add(theGame.getGUI());
// This is the ActionListener i have trouble connecting with the buttonBack in the "theGame" class
class Action implements ActionListener{
public void actionPerformed (ActionEvent e){
frame1.remove(theGame.getGUI());
frame1.add(MainMenu.getGUI());
}
}
frame1.pack();
frame1.setVisible(true);
}
public JFrame getGUI() {
return frame1;
}
}
主菜单:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
class MainMenu {
private JPanel mainMenu = new JPanel (new GridBagLayout());
public void mainMenu() {
// Using the GridBagLayout therefore creating the constraints "grid"
GridBagConstraints grid = new GridBagConstraints();
// Adjusting grid insets
grid.insets = new Insets(10, 10, 10, 10);
// Creating Label
JLabel introduction = new JLabel("Name");
grid.gridx = 1;
grid.gridy = 3;
mainMenu.add(introduction, grid);
// Creating buttons Start Game, Highscore and Exit Game
JButton buttonNewGame = new JButton("New Game");
buttonNewGame.setPreferredSize(new Dimension(200, 50));
grid.gridx = 1;
grid.gridy = 5;
mainMenu.add(buttonNewGame, grid);
JButton buttonHighscore = new JButton("Highscore");
buttonHighscore.setPreferredSize(new Dimension(200, 50));
grid.gridx = 1;
grid.gridy = 6;
mainMenu.add(buttonHighscore, grid);
JButton buttonExit = new JButton("Exit Game");
buttonExit.setPreferredSize(new Dimension(200, 50));
grid.gridx = 1;
grid.gridy = 7;
mainMenu.add(buttonExit, grid);
}
public JComponent getGUI() {
return mainMenu;
}
}
游戏:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
class TheGame {
private JPanel theGame = new JPanel (new GridBagLayout());
public void theGame() {
// Using the GridBagLayout therefore creating the constraints "grid"
GridBagConstraints grid = new GridBagConstraints();
// Adjusting grid insets
grid.insets = new Insets(10, 10, 10, 10);
// Creating a label
JLabel label1 = new JLabel("Press the BACK button to go back to Main Menu");
label1.setVisible(true);
grid.gridx = 1;
grid.gridy = 0;
theGame.add(label1,grid);
// Creating BACK button
JButton buttonBack = new JButton("BACK");
buttonBack.setVisible(true);
grid.gridx = 1;
grid.gridy = 1;
buttonBack.addActionListener(new --); // This is the button i want to connect with the ActionListener on Frame1 class
theGame.add(buttonBack, grid);
}
public JComponent getGUI() {
return theGame;
}
}
我曾尝试将ActionListener移到方法之外、Main内部,声明它是静态的,但无论如何都无法调用它。我也看过其他类似的帖子:Add an actionListener to a JButton from another class,但还没能在我的代码中实现它
感谢您的帮助
# 1 楼答案
最佳答案是使用MVC(模型-视图-控制器)结构(和CardLayout)交换视图。如果您不想这样做,那么您的侦听器应该有一个对进行交换的容器的引用,这样侦听器就可以通知这个容器应该进行交换。然后容器将调用自己的代码来进行交换。要做到这一点,您需要将引用(包括对主GUI的引用)传递到任何需要的地方。这可能会变得一团糟,这就是为什么MVC工作更多,从长远来看,连接/复杂性更少通常更好
旁注:不要将JDialog传递到JOptionPane,因为JOptionPane是专门的JDialog,并且不应该让顶级窗口显示顶级窗口。相反,请交一张JPanel
例如: