如何在jpanel之间切换?

 手机用户2702937405 发布于 2023-01-29 09:45

我仍然是java编程的新手,所以请帮助我纠正我可能忽略的任何错误或提供有关如何改进此程序的提示.

好的,所以很多问题都解决了,现在我有了一个CardLayout,但我仍然对如何让我的管道显示在里面有疑问.

当我尝试添加刷新率计时器和我的速度计时器时,我遇到了如何声明和初始化布尔变量的问题.

此外,当我编译并运行这个游戏时,我得到的文件如Game$1.class.有没有办法让我清理它,有人可以解释为什么会这样吗?这些对成品有影响吗?(当游戏编译并打包成JAR时.)

我想在点击播放按钮时将playerIsReady设置为true.从那里,当if语句为真时,然后切换到显示管道的面板,并开始在屏幕上移动管道.最好是该管道的3个实例,每个实例在不同的时间开始,但无论你能提供什么帮助都很好.

这些代码中的一些需要工作,所以我已经注释了一些部分并留下了注释.

我可以在这里找到关于这个游戏的其他问题.

这是我目前的代码

Game.java

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.SwingUtilities;

public class Game {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {             
                // the GUI as seen by the user (without frame)
                final CardLayout cl = new CardLayout();
                final JPanel gui = new JPanel(cl);
                // remove if no border is needed
                gui.setBorder(new EmptyBorder(10,10,10,10));

                JPanel menu = new JPanel(new GridBagLayout());
                JButton playGame = new JButton("Play!");
                ActionListener playGameListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        cl.show(gui, "game");
                    }
                };
                playGame.addActionListener(playGameListener);
                Insets margin = new Insets(20, 50, 20, 50);
                playGame.setMargin(margin);
                menu.add(playGame);
                gui.add(menu);
                cl.addLayoutComponent(menu, "menu");

                final JPanel pipes = new Pipes();
                gui.add(pipes);
                cl.addLayoutComponent(pipes, "game");

                JFrame f = new JFrame("Pipes Game");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See /sf/ask/17360801/ for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);

                /*if (playerIsReady) { 
                    Timer speed = new Timer(10, new ActionListener() {  //pipe speed
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            pipes.move();
                        }
                    });
                    speed.start();

                    Timer refresh = new Timer(30, new ActionListener() {    //refresh rate
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            pipes.repaint();
                        }
                    });
                    refresh.start();
                }*/
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

Pipes.java

// What import(s) do I need for ArrayList?
public class Pipes {
    List pipes = new ArrayList();

    public Pipes() {
        pipes.add(new Pipe(50, 100));
        pipes.add(new Pipe(150, 100));
        pipes.add(new Pipe(250, 100));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for ( Pipe pipe : pipes ){
            pipe.drawPipe(g);
        }
    }
}

PipeObject.java

import java.awt.Graphics;

public class PipeObject {
    //Declare and initialiaze variables
    int x1 = 754;               //xVal start
    int x2 = 75;                //pipe width
                                //total width is 83
    int y1 = -1;                //yVal start
    int y2 = setHeightVal();    //pipe height
    int gap = 130;              //gap height

    public void drawPipe(Graphics g) {

        g.clearRect(0,0,750,500);                       //Clear screen
        g.drawRect(x1,y1,x2,y2);                        //Draw part 1
        g.drawRect(x1-3,y2-1,x2+6,25);                  //Draw part 2
        g.drawRect(x1-3,y2+25+gap,x2+6,25);             //Draw part 3
        g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap);   //Draw part 4
    }

    public void move() {
        x1--;
    }

    public int getMyX() {   //To determine where the pipe is horizontally
        return x1-3;
    }

    public int getMyY() {   //To determine where the pipe is vertically
        return y2+25;
    }

    public int setHeightVal() {     //Get a random number and select a preset height
        int num = (int)(9*Math.random() + 1);
        int val = 0;
        if (num == 9)
        {
            val = 295;
        }
        else if (num == 8)
        {
            val = 246;
        }
        else if (num == 7)
        {
            val = 216;
        }
        else if (num == 6)
        {
            val = 185;
        }
        else if (num == 5)
        {
            val = 156;
        }
        else if (num == 4)
        {
            val = 125;
        }
        else if (num == 3)
        {
            val = 96;
        }
        else if (num == 2)
        {
            val = 66;
        }
        else
        {
            val = 25;
        }
        return val;
    }
}

Andrew Thomp.. 6

解决这个问题的最佳方法是使用a CardLayout.

在此输入图像描述

在此输入图像描述

笔记

一个带有a的按钮ActionListener远远MouseListener超过一个矩形.

当鼠标指向该按钮时,该按钮将显示焦点,或者通过键盘将该组件标记为按钮.

该按钮可通过键盘访问.

该按钮具有支持内置多个图标的功能(例如,用于"初始外观",聚焦,按下等)

通过添加一个菜单面板和游戏,在GUI中提供空白区域 EmptyBorder

通过设置边距使按钮变大.

根据需要调整边距,边框和首选尺寸.这些尺寸是由我设定的,以免使截图过大.

在代码注释中查看更多提示.

以下是产生上述屏幕截图的MCTaRE(最小完整测试和可读示例).

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class PipesGame {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                // the GUI as seen by the user (without frame)
                final CardLayout cl = new CardLayout();
                final JPanel gui = new JPanel(cl);
                // remove if no border is needed
                gui.setBorder(new EmptyBorder(10,10,10,10));

                JPanel menu = new JPanel(new GridBagLayout());
                JButton playGame = new JButton("Play!");
                ActionListener playGameListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        cl.show(gui, "game");
                    }
                };
                playGame.addActionListener(playGameListener);
                Insets margin = new Insets(20, 50, 20, 50);
                playGame.setMargin(margin);
                menu.add(playGame);
                gui.add(menu);
                cl.addLayoutComponent(menu, "menu");

                JPanel pipes = new Pipes();
                gui.add(pipes);
                cl.addLayoutComponent(pipes, "game");

                JFrame f = new JFrame("Pipes Game");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See /sf/ask/17360801/ for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

class Pipes extends JPanel {

    Pipes() {
        setBackground(Color.BLACK);
        setForeground(Color.WHITE);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString("Pipes game appears here..", 170, 80);
    }

    @Override 
    public Dimension getPreferredSize() {
        // adjust to need
        return new Dimension(500,150);
    }
}


Paul Samsoth.. 5

"我有没有办法将我的GameMenu jpanel添加到我的jframe中,然后用Pipes jpanel替换它?"

正如其他人所建议的那样,你需要一个CardLayout.这对你来说很简单.就我个人而言,我总是把自己包裹CardLayout在一个JPanelJFrame不仅仅是习惯的力量中.

你想要做的是有一个mainPanel,将有CardLayout

CardLayout card = new CardLayout();
JPanel mainPanel = new JPanel();

然后你想将你的面板添加到mainPanel.什么CardLyaout确实是分层的面板,使得仅仅一个在同一时间可见.您添加的第一个将在前景中.此外,当您添加面板时,您还需要向它发出一个可以从中调用的.键,可以是您喜欢的任何字符串.

mainPanel.add(gameMenu, "menu");
mainPnael.add(pipes, "pipe");

现在gameMenu是唯一显示的面板.要显示pipes,您所做的就是使用此方法

public void show(Container parent, String name)- 使用addLayoutComponent 翻转到parent指定的布局中添加的内容name.如果不存在这样的组件,则没有任何反应.

所以你要用, card.show(mainPanel, "pipes");

无论你想触发什么pipes,只需在该事件处理程序中添加该行.您可以添加一个按钮或其他内容GameMenu,以便移动到Pipes面板.

2 个回答
  • 解决这个问题的最佳方法是使用a CardLayout.

    在此输入图像描述

    在此输入图像描述

    笔记

    一个带有a的按钮ActionListener远远MouseListener超过一个矩形.

    当鼠标指向该按钮时,该按钮将显示焦点,或者通过键盘将该组件标记为按钮.

    该按钮可通过键盘访问.

    该按钮具有支持内置多个图标的功能(例如,用于"初始外观",聚焦,按下等)

    通过添加一个菜单面板和游戏,在GUI中提供空白区域 EmptyBorder

    通过设置边距使按钮变大.

    根据需要调整边距,边框和首选尺寸.这些尺寸是由我设定的,以免使截图过大.

    在代码注释中查看更多提示.

    以下是产生上述屏幕截图的MCTaRE(最小完整测试和可读示例).

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    import javax.swing.border.EmptyBorder;
    
    public class PipesGame {
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    // the GUI as seen by the user (without frame)
                    final CardLayout cl = new CardLayout();
                    final JPanel gui = new JPanel(cl);
                    // remove if no border is needed
                    gui.setBorder(new EmptyBorder(10,10,10,10));
    
                    JPanel menu = new JPanel(new GridBagLayout());
                    JButton playGame = new JButton("Play!");
                    ActionListener playGameListener = new ActionListener() {
    
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            cl.show(gui, "game");
                        }
                    };
                    playGame.addActionListener(playGameListener);
                    Insets margin = new Insets(20, 50, 20, 50);
                    playGame.setMargin(margin);
                    menu.add(playGame);
                    gui.add(menu);
                    cl.addLayoutComponent(menu, "menu");
    
                    JPanel pipes = new Pipes();
                    gui.add(pipes);
                    cl.addLayoutComponent(pipes, "game");
    
                    JFrame f = new JFrame("Pipes Game");
                    f.add(gui);
                    // Ensures JVM closes after frame(s) closed and
                    // all non-daemon threads are finished
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    // See /sf/ask/17360801/ for demo.
                    f.setLocationByPlatform(true);
    
                    // ensures the frame is the minimum size it needs to be
                    // in order display the components within it
                    f.pack();
                    // should be done last, to avoid flickering, moving,
                    // resizing artifacts.
                    f.setVisible(true);
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
            SwingUtilities.invokeLater(r);
        }
    }
    
    class Pipes extends JPanel {
    
        Pipes() {
            setBackground(Color.BLACK);
            setForeground(Color.WHITE);
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawString("Pipes game appears here..", 170, 80);
        }
    
        @Override 
        public Dimension getPreferredSize() {
            // adjust to need
            return new Dimension(500,150);
        }
    }
    

    2023-01-29 09:48 回答
  • "我有没有办法将我的GameMenu jpanel添加到我的jframe中,然后用Pipes jpanel替换它?"

    正如其他人所建议的那样,你需要一个CardLayout.这对你来说很简单.就我个人而言,我总是把自己包裹CardLayout在一个JPanelJFrame不仅仅是习惯的力量中.

    你想要做的是有一个mainPanel,将有CardLayout

    CardLayout card = new CardLayout();
    JPanel mainPanel = new JPanel();
    

    然后你想将你的面板添加到mainPanel.什么CardLyaout确实是分层的面板,使得仅仅一个在同一时间可见.您添加的第一个将在前景中.此外,当您添加面板时,您还需要向它发出一个可以从中调用的.键,可以是您喜欢的任何字符串.

    mainPanel.add(gameMenu, "menu");
    mainPnael.add(pipes, "pipe");
    

    现在gameMenu是唯一显示的面板.要显示pipes,您所做的就是使用此方法

    public void show(Container parent, String name)- 使用addLayoutComponent 翻转到parent指定的布局中添加的内容name.如果不存在这样的组件,则没有任何反应.

    所以你要用, card.show(mainPanel, "pipes");

    无论你想触发什么pipes,只需在该事件处理程序中添加该行.您可以添加一个按钮或其他内容GameMenu,以便移动到Pipes面板.

    2023-01-29 09:48 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有