如何实现主类JPanel中按钮关闭JFrame并打开其他类的JOptionPane
解决JPanel按钮点击关闭当前JFrame并打开另一个类JOptionPane的问题
没问题,我来帮你梳理下代码里的问题,然后给出修改方案,实现点击ButtonNewGame按钮时关闭当前窗口并弹出角色选择的对话框。
原代码存在的几个关键问题
- 你的
StartingScreen类已经继承了JFrame,但又额外创建了一个JFrame StartingScreen实例,这会造成逻辑混淆,完全没必要,直接用继承的窗口实例即可。 - 类没有实现
ActionListener接口,所以ButtonNewGame.addActionListener(this)这行代码会编译报错。 NewGame类中的JOptionPane代码直接写在类的成员位置,这会导致程序启动时就弹出对话框,而不是点击按钮时才触发。
修改后的完整代码
主类 StartingScreen 修改:
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class StartingScreen extends JFrame implements ActionListener { // 实现ActionListener接口 JPanel SidePanel = new JPanel(); JPanel CenterPanel = new JPanel(); JPanel BottomPanel = new JPanel(); JButton ButtonNewGame = new JButton("New Game"); JButton ButtonLoadGame = new JButton("Load Game"); JButton ButtonDeleteGame = new JButton("Delete Game"); public static void main(String[] args) { new StartingScreen(); // 这里不需要提前实例化FileLoader,除非有其他需求 } StartingScreen() { // 直接用继承的JFrame实例,不用再新建一个 super("StartingScreen"); this.setSize(880, 520); this.setResizable(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); // 面板配置不变 SidePanel.setBackground(Color.YELLOW); SidePanel.setPreferredSize(new Dimension(300, 520)); BottomPanel.setPreferredSize(new Dimension(880, 80)); BottomPanel.setBackground(Color.RED); CenterPanel.setBackground(Color.BLUE); // 按钮配置 ButtonNewGame.setBackground(Color.GREEN); ButtonNewGame.setPreferredSize(new Dimension(280, 130)); // 设置贴合功能的actionCommand,用于判断点击事件 ButtonNewGame.setActionCommand("NewGame"); ButtonNewGame.addActionListener(this); // 现在因为实现了接口,这行不会报错 ButtonLoadGame.setBackground(Color.GREEN); ButtonLoadGame.setPreferredSize(new Dimension(280, 130)); ButtonDeleteGame.setBackground(Color.GREEN); ButtonDeleteGame.setPreferredSize(new Dimension(280, 130)); // 添加组件 this.add(SidePanel, BorderLayout.WEST); this.add(CenterPanel, BorderLayout.CENTER); this.add(BottomPanel, BorderLayout.PAGE_END); SidePanel.add(ButtonNewGame); SidePanel.add(ButtonLoadGame); SidePanel.add(ButtonDeleteGame); this.setVisible(true); } // 重写ActionListener的actionPerformed方法,处理按钮点击事件 @Override public void actionPerformed(ActionEvent e) { // 判断是否是NewGame按钮被点击 if ("NewGame".equals(e.getActionCommand())) { // 关闭当前JFrame this.dispose(); // 打开NewGame类中的对话框 new NewGame().showClassSelectionDialog(); } } }
次级类 NewGame 修改:
import javax.swing.JOptionPane; public class NewGame { String[] classes = { "Paladin", "Mage", "Warlock" }; // 把弹出对话框的逻辑封装成方法,需要时再调用 public void showClassSelectionDialog() { int classes_index = JOptionPane.showOptionDialog( null, "Choose a class", "Classes", 0, JOptionPane.INFORMATION_MESSAGE, null, classes, 0 ); // 这里可以根据classes_index做后续处理,比如用户选择了哪个职业 if (classes_index != JOptionPane.CLOSED_OPTION) { System.out.println("你选择了:" + classes[classes_index]); } } }
关键改动说明
- 实现ActionListener接口:让
StartingScreen类实现ActionListener,并重写actionPerformed方法,这样才能处理按钮的点击事件。 - 移除多余的JFrame实例:直接用
this指代当前继承的JFrame对象,避免窗口实例混乱。 - 封装NewGame的对话框逻辑:把弹出JOptionPane的代码放到方法里,只有当按钮点击时调用这个方法,才会弹出对话框,而不是程序启动就弹出。
- 点击事件处理:在
actionPerformed中判断点击的是ButtonNewGame,先调用dispose()关闭当前窗口,再实例化NewGame并调用显示对话框的方法。
这样修改后,点击"New Game"按钮就会关闭当前的StartingScreen窗口,然后弹出角色选择的JOptionPane了。
内容的提问来源于stack exchange,提问作者user9174440
相关产品推荐
相关产品推荐

