我怎样才能jpanels之间切换? [英] How can I switch between jpanels?

查看:317
本文介绍了我怎样才能jpanels之间切换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还是很新的Java编程,所以请帮我纠正我可能忽略了任何错误或提供关于如何改进这个方案的提示。

好吧,所以很多问题已经解决了,现在我有一个CardLayout,但我仍然对我应该怎么做我的管道表明里面的问题。

当我试图在我的刷新率定时器和我的速度增加计时器,我有我需要如何声明和初始化布尔变量的问题。

此外,当我编译和运行这个游戏,我得到的文件,如游戏$ 1.class 。有我的方式来打扫一下,并可能有人解释为什么出现这种情况?难道这些都在对成品的影响? (当游戏被编译并打包成一个JAR)。

我要被点击播放按钮时playerIsReady设置为true。从那里,当if语句是真的,然后切换到显示的管面板,并开始在屏幕上移动的管道。 preferably该管3实例,每个实例开始在不同的时间,但无论你可以帮助是好的。

这一些code需要的工作,所以我评论某些部分并留下记录。

我对这场比赛的其他问题,可以发现<一个href=\"http://stackoverflow.com/questions/21587972/how-can-i-scroll-more-than-one-object-at-the-same-time\">here.

这是我的电流 code

Game.java

 进口java.awt中的*。
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口的javax.swing *。
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;
进口javax.swing.border.EmptyBorder中;
进口javax.swing.SwingUtilities中;公共类游戏{    公共静态无效的主要(字串[] args){
        可运行R =新的Runnable(){
            @覆盖
            公共无效的run(){
                //由用户看到的GUI(无边框)
                最后CardLayout CL =新CardLayout();
                最终的JPanel GUI =新JPanel(CL);
                //删除如果不需要边框
                gui.setBorder(新EmptyBorder(10,10,10,10));                JPanel的菜单=新JPanel(新的GridBagLayout());
                JButton的琐事=的新的JButton(玩!);
                ActionListener的playGameListener =新的ActionListener(){                    @覆盖
                    公共无效的actionPerformed(ActionEvent的五){
                        cl.show(GUI,游戏);
                    }
                };
                playGame.addActionListener(playGameListener);
                插图余量=新插图(20,50,20,50);
                playGame.setMargin(保证金);
                menu.add(玩笑);
                gui.add(菜单);
                cl.addLayoutComponent(菜单,菜单);                最终的JPanel管道=新管道();
                gui.add(管道);
                cl.addLayoutComponent(管道,游戏);                JFrame的F =新的JFrame(管道游戏);
                f.add(GUI);
                //确保JVM结束后架(S)关闭
                //所有非守护线程都完成
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                //见http://stackoverflow.com/a/7143398/418556的演示。
                f.setLocationByPlatform(真);                //保证帧是它需要的最小尺寸
                //为了显示它内部的组件
                f.pack();
                //应最后完成,避免闪烁,移动,
                //调整文物。
                f.setVisible(真);                / *如果(playerIsReady){
                    定时器速度=新的定时器(10,新的ActionListener(){//管速度
                        @覆盖
                        公共无效的actionPerformed(ActionEvent的五){
                            pipes.move();
                        }
                    });
                    speed.start();                    定时刷新=新的定时器(30,新的ActionListener(){//刷新率
                        @覆盖
                        公共无效的actionPerformed(ActionEvent的五){
                            pipes.repaint();
                        }
                    });
                    refresh.start();
                } * /
            }
        };
        //摇摆的GUI应创建和更新的EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(R);
    }
}

Pipes.java

  //什么进口(S)我需要的ArrayList?
公共类管道{
    清单&LT;管道和GT;管道=新的ArrayList&LT;管道和GT;();    公共管道(){
        pipes.add(新管(50,100));
        pipes.add(新管(150,100));
        pipes.add(新管(250,100));
    }    保护无效paintComponent(图形G){
        super.paintComponent方法(G);        对于(管管材:管){
            pipe.drawPipe(G);
        }
    }
}

PipeObject.java

 进口java.awt.Graphics;公共类PipeObject {
    //声明和initialiaze变量
    INT X1 = 754; // XVAL启动
    INT X2 = 75; //宽管
                                //总宽度为83
    INT Y1 = -1; //利用yval启动
    INT Y2 = setHeightVal(); //管高度
    INT差距= 130; //间隙高度    公共无效drawPipe(图形G){        g.clearRect(0,0,750,500); //清屏
        g.drawRect(X1,Y1,X2,Y2); //绘制第1部分
        g.drawRect(X1-3,Y2-1,2 + 6,25); //绘制第2部分
        g.drawRect(X1-3,Y2 + 25 +的差距,X2 + 6,25); //绘制第3部分
        g.drawRect(X1,Y2 + 25 +缺口+ 25,x2,500-y2-49间隙); //绘制部分4
    }    公共无效移动(){
        x1--;
    }    公众诠释getMyX(){//若要确定管水平
        返回X1-3;
    }    公众诠释getMyY(){//若要确定管道垂直
        回Y2 + 25;
    }    公众诠释setHeightVal(){//获得一个随机数,选择preSET高度
        INT NUM =(int)的(9 *的Math.random()+ 1);
        INT VAL = 0;
        如果(NUM == 9)
        {
            VAL = 295;
        }
        否则,如果(NUM == 8)
        {
            VAL = 246;
        }
        否则,如果(NUM == 7)
        {
            VAL = 216;
        }
        否则,如果(NUM == 6)
        {
            VAL = 185;
        }
        否则,如果(NUM == 5)
        {
            VAL = 156;
        }
        否则,如果(NUM == 4)
        {
            VAL = 125;
        }
        否则,如果(NUM == 3)
        {
            VAL = 96;
        }
        否则,如果(NUM == 2)
        {
            VAL = 66;
        }
        其他
        {
            VAL = 25;
        }
        返回VAL;
    }
}


解决方案

接近最好的方法是使用 CardLayout

注释


  • 的ActionListener 远远超过的MouseListener 在一个长方形更好的按钮。结果

    • 按钮将显示焦点当鼠标指向它,或者该部件通过键盘向标签

    • 的按钮键盘访问。

    • 按钮有设施,以支持内置的多个图标(例如,用于最初看,重点突出,pressed等)


  • 在GUI白色空间是通过将围绕提供菜单面板和游戏中的 EmptyBorder

  • 按钮由通过设置保证金更大。

  • 调整页边距,边框和$ P $根据需要pferred大小。这些大小是由我设定为不使截图太大。

  • 请参见code注释的提示。

code

下面是 MCTaRE (最小完备测试和可读例)所产生上面的截图。

 进口java.awt中的*。
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口的javax.swing *。
进口javax.swing.border.EmptyBorder中;公共类PipesGame {    公共静态无效的主要(字串[] args){
        可运行R =新的Runnable(){
            @覆盖
            公共无效的run(){
                //由用户看到的GUI(无边框)
                最后CardLayout CL =新CardLayout();
                最终的JPanel GUI =新JPanel(CL);
                //删除如果不需要边框
                gui.setBorder(新EmptyBorder(10,10,10,10));                JPanel的菜单=新JPanel(新的GridBagLayout());
                JButton的琐事=的新的JButton(玩!);
                ActionListener的playGameListener =新的ActionListener(){                    @覆盖
                    公共无效的actionPerformed(ActionEvent的五){
                        cl.show(GUI,游戏);
                    }
                };
                playGame.addActionListener(playGameListener);
                插图余量=新插图(20,50,20,50);
                playGame.setMargin(保证金);
                menu.add(玩笑);
                gui.add(菜单);
                cl.addLayoutComponent(菜单,菜单);                JPanel的管道=新管道();
                gui.add(管道);
                cl.addLayoutComponent(管道,游戏);                JFrame的F =新的JFrame(管道游戏);
                f.add(GUI);
                //确保JVM结束后架(S)关闭
                //所有非守护线程都完成
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                //见http://stackoverflow.com/a/7143398/418556的演示。
                f.setLocationByPlatform(真);                //保证帧是它需要的最小尺寸
                //为了显示它内部的组件
                f.pack();
                //应最后完成,避免闪烁,移动,
                //调整文物。
                f.setVisible(真);
            }
        };
        //摇摆的GUI应创建和更新的EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(R);
    }
}一流的管道继承JPanel {    管(){
        的setBackground(Color.BLACK);
        setForeground(Color.WHITE);
    }    @覆盖
    公共无效的paintComponent(图形G){
        super.paintComponent方法(G);
        g.drawString(管游戏中出现在这里。,170,80);
    }    @覆盖
    公共尺寸的get preferredSize(){
        //调整需要
        返回新的Dimension(500150);
    }
}

I'm still very new to java programming, so please help me to correct any mistakes I might have overlooked or give tips on how to improve this program.

Okay, so a lot of problems have been solved, and now I have a CardLayout, but I still have questions about how I should make my pipes show inside it.

When I tried to add in my refresh rate timer and my speed timer, I have problems about how I need to declare and initialize boolean variables.

Also, when I compile and run this game, I get files such as Game$1.class. Is there a way for me to clean this up, and could someone explain why this happens? Do these have an affect on the finished product? (When the game is compiled and packaged into a JAR.)

I want to set playerIsReady to true when the play button is clicked. And from there, when the if statement is true, then switch to a panel that displays the pipes, and start moving the pipe across the screen. Preferably 3 instances of that pipe, each starting at different times, but whatever you can help with is fine.

Some of this code needs work, so I have commented some parts out and left notes.

My other questions about this game can be found here.

This is my current code

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 http://stackoverflow.com/a/7143398/418556 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<Pipe> pipes = new ArrayList<Pipe>();

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

解决方案

The best way to approach this is using a CardLayout.

Notes

  • A button with an ActionListener is far better than a MouseListener over a rectangle.
    • The button will show focus when the mouse is pointed at it, or the component is tabbed to via the keyboard.
    • The button is keyboard accessible.
    • The button has facility to support multiple icons built in (e.g. for 'initial look', focused, pressed etc.)
  • White space in the GUI is provided around the menu panel and game by adding an EmptyBorder
  • The button is made larger by setting a margin.
  • Adjust margins, borders and preferred size according to need. These sizes were set by me so as not to make the screenshots too large.
  • See more tips in the code comments.

Code

Here is the MCTaRE (Minimal Complete Tested and Readable Example) that produced the above screenshots.

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 http://stackoverflow.com/a/7143398/418556 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);
    }
}

这篇关于我怎样才能jpanels之间切换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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