有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java屏幕上的按钮不会将我切换到游戏窗格

屏幕上的按钮不会跟踪我的GamePane类。我想这是因为ActionListener。我也听说过使用MouseListener,但我不知道那是什么

游戏框架:

GameFrame保存游戏屏幕的组件。按下启动按钮时,此屏幕不会显示

import java.awt.CardLayout;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GamePane extends JPanel {// *change GamePane to GamePane
    // This is were the game screen is made and the player is created.

    private static final long serialVersionUID = 1L;
    JLabel player = new JLabel();
    int playerSpeed = 1;
    int FPS = 30;

    // Set the timer
    // Timer tm = new Timer(1000 / FPS, this);
    // tm.start();

    // The keys set holds the keys being pressed
    private final Set<Integer> keys = new HashSet<>();

    public static void main(String[] args) {
        // Open the GUI window
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // Create a new object and
                // run its go() method
                new GamePane().go();
            }
        });
    }

    GamePane() {
        // Run the parent class constructor
        super();
        // Allow the panel to get focus
        setFocusable(true);
        // Don't let keys change the focus
        setFocusTraversalKeysEnabled(false);
    }

    /**
     * The frame that shows my game
     */
    protected void go() {
        // Setup the window
        JFrame GameFrame = new JFrame();
        // Add this panel to the window
        GameFrame.setLayout(new CardLayout());
        GameFrame.setContentPane(this);

        // Set the window properties
        GameFrame.setTitle("game");
        GameFrame.setSize(800, 400);
        GameFrame.setLocationRelativeTo(null);
        GameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GameFrame.setVisible(true);
        GameFrame.add(new ButtonPane(GameFrame), "game");
    }
}

按钮平面:

这是包含按钮的窗格的创建时间。按钮也会在按钮窗格中创建

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class ButtonPane extends JPanel {
    private static final long serialVersionUID = 1L;
    private JButton startBTN;//Calls the JButton
    JFrame game;

    public ButtonPane(JFrame MainFrame) {
        game = MainFrame;
        setLayout(new GridBagLayout());
        MainFrame.setBackground(Color.BLUE);//Sets the menu stages color blue
        startBTN = new JButton("Start");//Creates a new button
        add(startBTN);//Adds the button on the startStage

        startBTN.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button pressed");
//                ((CardLayout) game.getContentPane().getLayout()).show(game.getContentPane(), "game");
                if (game.getContentPane().getLayout() instanceof CardLayout) {
                    System.out.println("is card layout");
                    CardLayout layout = (CardLayout) getParent().getLayout();
                    layout.show(game.getContentPane(), "game");
                }
            }
        });
    }
}

共 (1) 个答案

  1. # 1 楼答案

    您的代码中有太多的内容,而且有太多的“猜测工作”。您还将代码耦合在一起,使得维护或管理几乎不可能

    后退一步,重新评估您的设计。你需要:

    • 充当“主视图”的容器,这是用于在各种视图之间切换的容器,它充当导航的主“控制器”
    • 菜单组件
    • 游戏组件
    • 用于固定“主视图”的框架

    让我们从框架开始。框架应该尽可能地哑。它唯一的任务就是在屏幕上显示“主视图”,其他的很少

    也许像

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame();
            frame.add(new MainPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
    

    MainPane(或主视图)不关心帧,因此我们不需要向它传递任何其他内容。因为“主视图”充当我们的导航控制器,所以您希望避免将其暴露给其他视图。这些视图不应该关心导航是如何工作的,只是它们可以在视图之间移动

    因此,我们没有将MainPane传递给子视图,而是创建了一个“导航控制器”的概念,该概念用于允许子视图发出关于它们想要做什么的请求,然后由实现来实现

    public interface NavigationController {
        public void showGame();
        public void showMenu();
    }
    

    MainPane然后充当所有其他顶级子视图和NavigationController的“主容器”

    public class MainPane extends JPanel implements NavigationController {
    
        public MainPane() {
            setLayout(new CardLayout());
            add(new MenuPane(this), "menu");
            add(new GamePane(this), "game");
        }
        
        protected CardLayout getCardLayout() {
            return (CardLayout) getLayout();
        }
    
        @Override
        public void showGame() {
            getCardLayout().show(this, "game");
        }
    
        @Override
        public void showMenu() {
            getCardLayout().show(this, "menu");
        }
        
    }
    

    它的全部职责是促进顶级子视图之间的切换

    然后我们的子视图

    public class MenuPane extends JPanel {
    
        private NavigationController controller;
        
        public MenuPane(NavigationController controller) {
            this.controller = controller;
            setLayout(new GridBagLayout());
            JButton btn = new JButton("Do you want to play a game?");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    controller.showGame();
                }
            });
            add(btn);
        }
        
    }
    
    public class GamePane extends JPanel {
    
        private NavigationController controller;
    
        public GamePane(NavigationController controller) {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(new JLabel("Ready player one"), gbc);
            
            gbc.weighty = 0;
            JButton btn = new JButton("Had enough");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    controller.showMenu();
                }
            });
            add(btn, gbc);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
        
    }
    

    这些视图只执行一个作业(无论该作业是什么),并将导航职责委托回NavigationController

    如果你想知道,MenuPane将是你的ButtonPane的等价物

    可运行的示例

    Do you want to play a game?

    import java.awt.CardLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new MainPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public interface NavigationController {
    
            public void showGame();
    
            public void showMenu();
        }
    
        public class MainPane extends JPanel implements NavigationController {
    
            public MainPane() {
                setLayout(new CardLayout());
                add(new MenuPane(this), "menu");
                add(new GamePane(this), "game");
            }
    
            protected CardLayout getCardLayout() {
                return (CardLayout) getLayout();
            }
    
            @Override
            public void showGame() {
                getCardLayout().show(this, "game");
            }
    
            @Override
            public void showMenu() {
                getCardLayout().show(this, "menu");
            }
    
        }
    
        public class MenuPane extends JPanel {
    
            private NavigationController controller;
    
            public MenuPane(NavigationController controller) {
                this.controller = controller;
                setLayout(new GridBagLayout());
                JButton btn = new JButton("Do you want to play a game?");
                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        controller.showGame();
                    }
                });
                add(btn);
            }
    
        }
    
        public class GamePane extends JPanel {
    
            private NavigationController controller;
    
            public GamePane(NavigationController controller) {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.weightx = 1;
                gbc.weighty = 1;
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(new JLabel("Ready player one"), gbc);
    
                gbc.weighty = 0;
                JButton btn = new JButton("Had enough");
                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        controller.showMenu();
                    }
                });
                add(btn, gbc);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
    }