屏幕上的按钮不会将我切换到游戏窗格 [英] The button on my screen won't switch me towards my game pane

查看:72
本文介绍了屏幕上的按钮不会将我切换到游戏窗格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我屏幕上的按钮不会将我追踪到我的GamePane班级.我认为是因为ActionListener.我也听说过使用MouseListener,但是我不知道那是什么.

The button on my screen won't track me towards my GamePane class. I think it's because of the ActionListener. I have also heard of using a MouseListener but I don't know what that is.

GameFrame:

GameFrame:

GameFrame包含游戏屏幕的组件.按下开始按钮时,不会显示此屏幕.

The GameFrame holds the component for the game screen. This screen won't show up when the start button is pressed.

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:

ButtonPane:

这是包含按钮的窗格被创建的地方.该按钮也在按钮窗格中创建.

This is were the pane containing the button is created. The button is also created in the button pane.

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

推荐答案

您的代码中发生了很多事情,并且猜测工作"过多.您还将代码耦合在一起,几乎无法维护或管理.

There is to much going on in your code and too much "guess work". You've also coupled you code together making it near impossible to maintain or manage.

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

Step back and reassess you design. You need:

    一种用作主视图"的容器,这是用于在各种视图之间切换的容器,它用作主视图的控制器".导航
  • 菜单组件
  • 游戏组件
  • 用于容纳主视图"的框架
  • A container which acts as the "main view", this is the container which is used to switch between various views, it acts as the main "controller" for the navigation
  • A menu component
  • A game component
  • A frame to hold the "main view"

让我们从框架开始.框架应该尽可能的笨.唯一的工作就是获得主视图"在屏幕上,几乎没有其他

Let's start with the frame. The frame should be as dumb as possible. It's sole job is to get the "main view" on the screen, very little else

也许像...

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(或主视图)不关心框架,因此我们不需要将其他任何内容传递给它.因为主视图"充当我们的导航控制器,您要避免将其暴露给其他视图.这些视图不应该在乎导航的工作原理,而只是在视图之间移动即可.

The MainPane (or main view) doesn't care about the frame, so we don't need to pass anything else to it. Because the "main view" is acting as our navigation controller, you want to avoid exposing it to other views. Those views shouldn't care how the navigation works, only that they can move between views.

因此,我们没有将MainPane传递给子视图,而是创建了一个导航控制器"概念.用来允许子视图提出关于他们想做的事情的请求,然后取决于实现该工作的实现.

So, instead of passing MainPane to the subviews, we create a concept of "navigation controller" which is used to allow the subviews to make requests about what they would like to do, it's then up to the implementation to make that work.

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

然后,

MainPane充当主容器".用于所有其他顶级子视图和NavigationController

MainPane then acts as the "main container" for all the other top level subviews and the 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");
    }
    
}

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

It's whole responsibility is to facilitate the switching between the top level subviews

然后我们的子视图....

Then our subviews....

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

These views do a single job (what ever that job is) and delegate the navigation responsibility back to the NavigationController

如果您想知道,MenuPane等于ButtonPane

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

    }

}

这篇关于屏幕上的按钮不会将我切换到游戏窗格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆