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

时间:2018-06-06 23:41:29

标签: java graphics

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

GameFrame:

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");
    }
}

ButtonPane:

这是创建包含按钮的窗格。该按钮也在按钮窗格中创建。

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 个答案:

答案 0 :(得分:0)

您的代码中有很多内容,而且“猜测工作”太多了。您还将代码耦合在一起,几乎无法维护或管理。

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

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

让我们从框架开始。框架应尽可能愚蠢。唯一的工作就是在屏幕上获得“主视图”,其他方面很少

也许像......

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);
        }

    }

}