gpt4 book ai didi

java - 使用面板类中的按钮调用框架类中的ActionListener

转载 作者:行者123 更新时间:2023-11-30 03:06:44 24 4
gpt4 key购买 nike

我上周末开始学习 codig Java,并且阅读了大部分基本内容。我试图将我的框架与主方法分开,并将面板与框架分开,以便它们都位于单独的类文件中。我在使用“TheGame”类中的按钮(buttonBack)调用“Frame1”类中的 ActionLister 时遇到问题。该按钮应触发监听器,监听器又应删除游戏面板并将 mainMenu 面板添加到第 1 帧。我知道 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但无法将其实现到我的代码中。

感谢任何帮助。

最佳答案

最好的答案——使用 MVC(模型- View - Controller )结构(和 CardLayout)来交换 View 。如果您不想这样做,那么您的监听器应该具有对执行交换的容器的引用,以便监听器可以通知该容器应该发生交换。然后容器将调用自己的代码来进行交换。为此,您需要将引用(包括对主 GUI 的引用)传递到需要的地方。这可能会变得困惑,这就是为什么 MVC(工作量更大)通常更好——从长远来看,连接/复杂性更少。

旁注 - 不要将 JDialog 传递到 JOptionPane,因为 JOptionPane 专用的 JDialog,并且您不应该让顶级窗口显示顶级窗口。相反,传入 JPanel。

例如:

import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class PassRef {

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

private static void createAndShowGui() {
MyMain mainPanel = new MyMain();
JFrame frame = new JFrame("Pass Reference");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}

class MyMain extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 450;
private CardLayout cardLayout = new CardLayout();
private MenuView menuView = new MenuView(this);
private ActionView1 actionView1 = new ActionView1(this);

public MyMain() {
setLayout(cardLayout);
add(menuView, MenuView.NAME);
add(actionView1, ActionView1.NAME);
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(PREF_W, PREF_H);
}
}

public void showCard(String key) {
cardLayout.show(this, key);
// or swap by hand if you don't want to use CardLayout
// but remember to revalidate and repaint whenever doing it by hand
}
}

class MenuView extends JPanel {
public static final String NAME = "Menu View";

public MenuView(MyMain myMain) {
setName(NAME);
setBorder(BorderFactory.createTitledBorder("Menu"));
add(new JButton(new GoToAction("Action 1", ActionView1.NAME, myMain)));
}

}

class ActionView1 extends JPanel {
public static final String NAME = "Action View 1";

public ActionView1(MyMain myMain) {
setName(NAME);
setBorder(BorderFactory.createTitledBorder(NAME));
add(new JButton(new GoToAction("Main Menu", MenuView.NAME, myMain)));
}

}

class GoToAction extends AbstractAction {
private String key;
private MyMain myMain;

public GoToAction(String name, String key, MyMain myMain) {
super(name);
this.key = key;
this.myMain = myMain;
}

@Override
public void actionPerformed(ActionEvent e) {
myMain.showCard(key);
}
}

关于java - 使用面板类中的按钮调用框架类中的ActionListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34580464/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com