Java 如何修复JPanel循环?

Java 如何修复JPanel循环?,java,swing,jpanel,Java,Swing,Jpanel,我已经完成了我简单的形状游戏。有3个JPanel的代码,包含开始、游戏和游戏结束。在代码中,一切都是完美的,但游戏结束时,我必须包括计算鼠标点击的游戏分数,即分数。我不能包括该分数。JPanel中的分数页是最后一个面板。我包括了诸如{重试}和{退出}之类的JButton。当我按下重试按钮时,我无法完全看到我的第一个Jpanel,它包含开始按钮。我怎样才能修好它? 这是沉重的代码,我希望它不是一团糟 public class myshapestry implements ActionLi

我已经完成了我简单的形状游戏。有3个JPanel的代码,包含开始、游戏和游戏结束。在代码中,一切都是完美的,但游戏结束时,我必须包括计算鼠标点击的游戏分数,即分数。我不能包括该分数。JPanel中的分数页是最后一个面板。我包括了诸如{重试}和{退出}之类的JButton。当我按下重试按钮时,我无法完全看到我的第一个Jpanel,它包含开始按钮。我怎样才能修好它? 这是沉重的代码,我希望它不是一团糟

    public class myshapestry  implements ActionListener {

        JFrame frame= new JFrame();
        MyPanel panel=new MyPanel();
        Container l ;
        private int ballXSpeed=150;
        private  int ballSpeed=90;
        private  int ballX=150;
        private  int ballY=200;
        Color c=Color.BLACK;
        JLabel statusbar = new JLabel("This game is developed by Asuskobay");
        Startthegame panelstart= new Startthegame();//this is start JPanel
        chooselevel panellevel= new chooselevel();//this is difficulties JPanel
        thegameover gameover=new thegameover();//End of page
       private int mouseclicks;//mouseclicks score
       private int mouse;

         public myshapestry() {

             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.pack();
             frame.setLocationRelativeTo(null);
             frame.add(panel);
             frame.add(panellevel);
             frame.add(gameover);
             frame.add(panelstart);
            frame.add(statusbar, BorderLayout.SOUTH);
            frame.setVisible(true);
             frame.setSize(getPreferredSize());
            frame.setTitle("Game of Shapes");
              HandlerClass handler=new HandlerClass();
                panel.addMouseListener(handler);
                panel.addMouseMotionListener(handler);
                Timer timer=new Timer(100,panel) ;
                timer.start();
            }

         public Dimension getPreferredSize() {
               return new  Dimension(900,730);
           }
         private  class HandlerClass implements MouseMotionListener, MouseListener {
               public void mouseClicked(MouseEvent e){

                 mouseclicks++;
                 statusbar.setText(String.format("MouseLoc ( %d, %d ) \t \t Mouse Click \t", e.getX(), e.getY()) + mouseclicks);
                 mouseclicks=mouse;
               }
              @Override
                public void mousePressed(MouseEvent event) {
                    if(event.getX() <= (ballX+90) && event.getX() >= (ballX)  && event.getY() <= (ballY+90) && event.getY() >= (ballY))
                       c=Color.RED;

                } }
          public  class MyPanel extends JPanel implements ActionListener {

               public void paintComponent(Graphics g){
                   super.paintComponent(g);
                   g.setColor(c);
                   g.fillOval(ballX, ballY, 90 , 90);
                  }
               public void actionPerformed(ActionEvent e) { //balls movement
                  ballX = ballX + ballXSpeed;
                  ballY = ballY + ballSpeed;
                  if(ballY>=730-185){

                     ballSpeed = -ballSpeed;
                  }

                  if(ballX>=900-180){
                      ballXSpeed = -ballXSpeed;
                  }

                  if(ballY<=0+60){
                      ballSpeed= -ballSpeed;

                  }

                  if (ballX<=0+60){
                      ballXSpeed= -ballXSpeed;
                  }

                  repaint();
                 if(c==Color.RED){
                     frame.remove(panel);
                     frame.add(gameover);
                     frame.validate();
                 }}}
           public class chooselevel extends JPanel implements ActionListener {
               private JButton easy;
               private JButton normal;
               private JButton hard;

               public chooselevel(){
                   setLayout(null);
                   easy=new JButton("Easy");
                   normal=new JButton("Normal");
                   hard=new JButton("Hard");

                   easy.setBounds(380,330,90,20);
                   normal.setBounds(380,370,90,20);
                   hard.setBounds(380,410,90,20);
                   add(hard);
                   add(easy);
                   add(normal);
                        hard.addActionListener(new ActionListener(){

                       public void actionPerformed(ActionEvent l){
                           String level=l.getActionCommand();
                           if(level.equals("Hard")){
                               ballXSpeed=190;
                               ballSpeed=184;
                               frame.remove(panellevel);
                               frame.add(panel);
                               frame.validate();
                           }} });  

                   normal.addActionListener(new ActionListener(){

                       public void actionPerformed(ActionEvent l){
                           String level=l.getActionCommand();
                           if(level.equals("Normal")){
                               ballXSpeed=157;
                               ballSpeed=123;
                               frame.remove(panellevel);
                               frame.add(panel);
                               frame.validate();

                           }}});

                   easy.addActionListener(new ActionListener(){

                       public void actionPerformed(ActionEvent l){
                           String level=l.getActionCommand();

                             if(level.equals("Easy")){
                               ballXSpeed=85;
                               ballSpeed=74;
                               frame.remove(panellevel);
                               frame.add(panel);
                               frame.validate();
                              }} });

               } 
              public Dimension getPreferredSize() {
                   return new Dimension(900,730);
               } }
           public class Startthegame extends JPanel implements ActionListener {
               private JButton Start;
                private JButton Exit;

                public Startthegame() {
                    setLayout(null);

                    Start = new JButton("Start");
                    Exit = new JButton("Exit");

                    Start.setBounds(380,330,70,20);
                    Exit.setBounds(380,370,70,20);
                    add(Start);
                    add(Exit);
                     Exit.addActionListener(new ActionListener() {

                     public  void  actionPerformed(ActionEvent i){
                       String action= i.getActionCommand();
                       if(action.equals("Exit")) {
                         System.exit(0);
                       }}
                 });
                    Start.addActionListener(new ActionListener() {

                         public  void  actionPerformed(ActionEvent i){
                           String action= i.getActionCommand();
                           if(action.equals("Start")) {
                               frame.remove(panelstart);
                               frame.add(panellevel);
                               frame.validate();
                               repaint();
                           } }});
}
    @Override
                public Dimension getPreferredSize() {
                    return new Dimension(900, 730);
                } }
           public class thegameover extends JPanel {
               private JLabel gameisover;
               private JLabel yourscore;
               private JButton tryagain;
               private JButton Exit;
               thegameover(){
                   setLayout(null);

                   gameisover= new JLabel("GAME OVER");
                   yourscore=new JLabel();

                  add(gameisover);
                  add(yourscore);
                   gameisover.setBounds(170,200,600,70);
                   yourscore.setBounds(380,380,120,70);

                  gameisover.setFont(new Font(null, Font.PLAIN, 90));
                  yourscore.setFont(new Font(null, Font.PLAIN, 20));
                  yourscore.setText ("Your Score " + mouseclicks);

                  tryagain=new JButton("Try Again");
                  Exit=new JButton("Exit");
                  add(tryagain);
                  add(Exit);

                  tryagain.setBounds(280,550,100,20);
                  Exit.setBounds(490,550,100,20);

                  tryagain.addActionListener(new ActionListener() {

                      public void actionPerformed(ActionEvent ac){
                          String tryit=ac.getActionCommand();
                                if(tryit.equals("Try Again")){
                                     frame.remove(gameover);
                                       frame.add(panelstart);
                                       frame.validate();
                                       repaint();
                                }
                            }
                  });
               }
               public Dimension getPreferredSize(){
                   return new Dimension(900,73);
               }}
            public static void main (String args[]){
               EventQueue.invokeLater(new Runnable() {
                   @Override
                   public void run() {

                       myshapestry tr=new myshapestry();
                   }
               });
             }  }
错误

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
    at java.awt.CardLayout.checkLayout(Unknown Source)
    at java.awt.CardLayout.show(Unknown Source)
    at example.myshapestry$collectionpanel.<init>(myshapestry.java:100)
    at example.myshapestry.<init>(myshapestry.java:58)
    at example.myshapestry$1.run(myshapestry.java:393)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
线程“AWT-EventQueue-0”java.lang.IllegalArgumentException中的异常:CardLayout的父级错误 位于java.awt.CardLayout.checkLayout(未知源) 在java.awt.CardLayout.show(未知源代码) 例如.myshapestry$collectionpanel.(myshapestry.java:100) 例如,myshapestry.(myshapestry.java:58) 例如.myshapestry$1.run(myshapestry.java:393) 在java.awt.event.InvocationEvent.dispatch(未知源)处 位于java.awt.EventQueue.dispatchEventImpl(未知源) 位于java.awt.EventQueue.access$200(未知源) 在java.awt.EventQueue$3.run处(未知源) 在java.awt.EventQueue$3.run处(未知源) 位于java.security.AccessController.doPrivileged(本机方法) 位于java.security.ProtectionDomain$1.doIntersectionPrivilege(未知源) 位于java.awt.EventQueue.dispatchEvent(未知源) 位于java.awt.EventDispatchThread.pumpOneEventForFilters(未知源) 位于java.awt.EventDispatchThread.pumpEventsForFilter(未知源) 位于java.awt.EventDispatchThread.pumpEventsForHierarchy(未知源) 位于java.awt.EventDispatchThread.pumpEvents(未知源) 位于java.awt.EventDispatchThread.pumpEvents(未知源) 位于java.awt.EventDispatchThread.run(未知源)
存在一系列问题,所有这些问题共同作用导致混乱

  • 当游戏“结束”时,您永远不会停止
    计时器
    ,这意味着当您尝试显示“游戏结束”屏幕或尝试重新启动时,“游戏面板”仍在尝试更新屏幕
  • 对屏幕的管理使这一点更加复杂。您首先添加所有屏幕,然后再删除/添加它们,这只会造成混乱
  • 相反

  • 在显示“游戏屏幕”之前,请启动
    计时器
    。当您检测到游戏“结束”时,在显示“结束”屏幕之前,请停止
    计时器
  • 改用
    卡片布局
    。有关更多详细信息,请参阅
  • 例如

    创建一个
    CardLayout
    实例字段,并将
    Timer
    作为一个实例字段

    public class MyShapes {//implements ActionListener {
        //...       
        private CardLayout cardLayout;
        private Timer timer = new Timer(100, panel);
    
    卡片布局
    应用于
    框架
    并命名每个视图

    public MyShapes() {
        //...       
        cardLayout = new CardLayout();
        frame.setLayout(cardLayout);
    
        frame.add(panel, "game");
        frame.add(panellevel, "level");
        frame.add(gameover, "over");
        frame.add(panelstart, "start");
        frame.add(statusbar, BorderLayout.SOUTH);
    
        cardLayout.show(frame.getContentPane(), "start");
        //...
    }
    
    当用户选择“开始”时,使用
    CardLayout

    Start.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent i) {
            String action = i.getActionCommand();
            if (action.equals("Start")) {
                //frame.remove(panelstart);
                //frame.add(panellevel);
                //frame.validate();
                cardLayout.show(frame.getContentPane(), "level");
            }
        }
    });
    
    开始游戏时,启动
    计时器
    并使用
    卡片布局
    切换视图

    hard.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent l) {
            String level = l.getActionCommand();
            if (level.equals("Hard")) {
                ballXSpeed = 190;
                ballSpeed = 184;
                //frame.remove(panellevel);
                //frame.add(panel);
                //frame.validate();
                timer.start();
                cardLayout.show(frame.getContentPane(), "game");
            }
        }
    });
    
    if (c == Color.RED) {
        //frame.remove(panel);
        //frame.add(gameover);
        //frame.validate();
        timer.stop();
        cardLayout.show(frame.getContentPane(), "over");
    }
    
    当您检测到“游戏结束”情况时,停止
    计时器
    ,并使用
    卡片布局
    切换视图

    hard.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent l) {
            String level = l.getActionCommand();
            if (level.equals("Hard")) {
                ballXSpeed = 190;
                ballSpeed = 184;
                //frame.remove(panellevel);
                //frame.add(panel);
                //frame.validate();
                timer.start();
                cardLayout.show(frame.getContentPane(), "game");
            }
        }
    });
    
    if (c == Color.RED) {
        //frame.remove(panel);
        //frame.add(gameover);
        //frame.validate();
        timer.stop();
        cardLayout.show(frame.getContentPane(), "over");
    }
    
    现在,关于得分问题

    创建
    thegameover
    面板时,使用
    yourscore.setText(“yourscore”+mouseclicks)
    ,但是
    mouseclicks
    0
    创建视图时,需要某种方法来更新此值

    在类的
    thegameover
    中添加一个名为
    setScore
    的方法,并相应地更新标签

    public void setScore(int score) {
        yourscore.setText("Your Score " + score);
    }
    
    当你检测到游戏结束时,更新分数

    timer.stop();
    gameover.setScore(mouseclicks);
    cardLayout.show(frame.getContentPane(), "over");
    
    您可能希望有一个通读版本,这将使人们更容易阅读您的代码,您也更容易阅读其他代码


    读一读

    也很有价值,因为有一连串的问题,所有这些问题共同作用,导致混乱

  • 当游戏“结束”时,您永远不会停止
    计时器
    ,这意味着当您尝试显示“游戏结束”屏幕或尝试重新启动时,“游戏面板”仍在尝试更新屏幕
  • 对屏幕的管理使这一点更加复杂。您首先添加所有屏幕,然后再删除/添加它们,这只会造成混乱
  • 相反

  • 在显示“游戏屏幕”之前,请启动
    计时器
    。当您检测到游戏“结束”时,在显示“结束”屏幕之前,请停止
    计时器
  • 改用
    卡片布局
    。有关更多详细信息,请参阅
  • 例如

    创建一个
    CardLayout
    实例字段,并将
    Timer
    作为一个实例字段

    public class MyShapes {//implements ActionListener {
        //...       
        private CardLayout cardLayout;
        private Timer timer = new Timer(100, panel);
    
    卡片布局
    应用于
    框架
    并命名每个视图

    public MyShapes() {
        //...       
        cardLayout = new CardLayout();
        frame.setLayout(cardLayout);
    
        frame.add(panel, "game");
        frame.add(panellevel, "level");
        frame.add(gameover, "over");
        frame.add(panelstart, "start");
        frame.add(statusbar, BorderLayout.SOUTH);
    
        cardLayout.show(frame.getContentPane(), "start");
        //...
    }
    
    当用户选择“开始”时,使用
    CardLayout

    Start.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent i) {
            String action = i.getActionCommand();
            if (action.equals("Start")) {
                //frame.remove(panelstart);
                //frame.add(panellevel);
                //frame.validate();
                cardLayout.show(frame.getContentPane(), "level");
            }
        }
    });
    
    开始游戏时,启动
    计时器
    并使用
    卡片布局
    切换视图

    hard.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent l) {
            String level = l.getActionCommand();
            if (level.equals("Hard")) {
                ballXSpeed = 190;
                ballSpeed = 184;
                //frame.remove(panellevel);
                //frame.add(panel);
                //frame.validate();
                timer.start();
                cardLayout.show(frame.getContentPane(), "game");
            }
        }
    });
    
    if (c == Color.RED) {
        //frame.remove(panel);
        //frame.add(gameover);
        //frame.validate();
        timer.stop();
        cardLayout.show(frame.getContentPane(), "over");
    }
    
    当您检测到“游戏结束”情况时,停止
    计时器
    ,并使用
    卡片布局
    切换视图

    hard.addActionListener(new ActionListener() {
    
        public void actionPerformed(ActionEvent l) {
            String level = l.getActionCommand();
            if (level.equals("Hard")) {
                ballXSpeed = 190;
                ballSpeed = 184;
                //frame.remove(panellevel);
                //frame.add(panel);
                //frame.validate();
                timer.start();
                cardLayout.show(frame.getContentPane(), "game");
            }
        }
    });
    
    if (c == Color.RED) {
        //frame.remove(panel);
        //frame.add(gameover);
        //frame.validate();
        timer.stop();
        cardLayout.show(frame.getContentPane(), "over");
    }
    
    现在,关于得分问题

    创建
    thegameover
    面板时,使用
    yourscore.setText(“yourscore”+mouseclicks)
    ,但是
    mouseclicks
    0
    创建视图时,需要某种方法来更新此值

    在类的
    thegameover
    中添加一个名为
    setScore
    的方法,并相应地更新标签

    public void setScore(int score) {
        yourscore.setText("Your Score " + score);
    }
    
    当你检测到游戏结束时,更新分数

    timer.stop();
    gameover.setScore(mouseclicks);
    cardLayout.show(frame.getContentPane(), "over");
    
    您可能希望有一个通读版本,这将使人们更容易阅读您的代码,您也更容易阅读其他代码


    读一读

    也很有价值,因为有一连串的问题,所有这些问题共同作用,导致混乱

  • 当游戏“结束”时,你永远不会停止
    计时器
    ,这意味着当你尝试和