从JFrame中删除后添加JPanel

时间:2014-12-20 19:57:36

标签: java swing jframe jpanel paintcomponent

我正在开发一个Java游戏。我陷入了困境,我需要在GameOver之后重新开始整场比赛。这是我的程序的骨架:

package projectflappy;

import java.awt.*;


public final class TheGame extends JFrame  implements MouseListener{
JPanel jp;
//declaration of the varibles

int x_width = 500;
int y_height = 500;

int count = 5 ;

Ellipse2D Ball;


int x_ball;
int y_ball;
int cord_xup1,cord_xdown1;
int cord_xup2,cord_xdown2;
int cord_xup3,cord_xdown3;
int cord_xup4,cord_xdown4;
int cord_xup5,cord_xdown5;

Boolean flag = true;

RoundRectangle2D up1,down1,up2,down2,up3,down3,up4,down4;

Font font = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,40);
Font font1 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
Font font3 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);

float das[] = {10.0f};
BasicStroke color = new BasicStroke(10,BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL,20.0f,das,0.0f); 


GradientPaint gp2 = new GradientPaint(20, 0, 
Color.DARK_GRAY, 0, 10, Color.GRAY, true);

GradientPaint gp3 = new GradientPaint(30, 0, 
Color.BLACK, 0, 20, Color.GREEN, true);

Toolkit kit = Toolkit.getDefaultToolkit();

 //Getting the "background.jpg" image we have in the folder
Image background = kit.getImage("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\1.png");

JLabel a = new JLabel("Get Ready ! Click to Start.");
JLabel retry = new JLabel(new ImageIcon("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\unnamed.png"));

int score = 0;


    //constructor
    public TheGame() throws IOException 
    {

        super("Simple Drawing");

        setSize(x_width, y_height);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        jp = new DrawingPanel();

        add(jp);

        addMouseListener(this);
    }

      ActionListener action = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
           update();

           repaint();
        }

     };
    Timer t = new Timer(50,action);   


    public void init()
    {
        x_ball = 30;
        y_ball = 200;

        cord_xup1 = 175; cord_xdown1 = 175;
        cord_xup2 = 320; cord_xdown2 = 320;
        cord_xup3 = 460; cord_xdown3 = 460;
        cord_xup4 = 585; cord_xdown4 = 585;
        cord_xup5 = 700; cord_xdown5 = 700;

       retry.setVisible(false);
            retry.setBounds(175,260,46,46);
            a.setForeground(Color.YELLOW);
            a.setFont(font1);
            a.setVisible(true);
            a.setBounds(105,200,300,100);

  }


    @Override
    public void mouseClicked(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        a.setVisible(false);
        if( flag == false)
        {
            t.stop();

        }
        else
        {
            t.start();

        }
       y_ball = y_ball - 40;
        count--; 


    }

    @Override
    public void mousePressed(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.


    }

    @Override
    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    // for drawing on the panel
    class DrawingPanel extends JPanel{
        private static final long serialVersionUID = 1L;

        public DrawingPanel() {
            setPreferredSize(new Dimension(300, 300));
            setLayout(null);
            init();
            add(a);
            add(retry);

           // addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D d = (Graphics2D)g;

            d.drawImage(background, -270,-30, this);
            Ball = new Ellipse2D.Double(x_ball,y_ball,30,30);

            d.setColor(Color.green);
            d.setFont(font3);


            up1 = new RoundRectangle2D.Double(cord_xup1,-5,30,175,20,20);
            down1 = new RoundRectangle2D.Double(cord_xdown1,310,30,155,20,20);

            up2 = new RoundRectangle2D.Double(cord_xup2,-5,30,200,20,20);
            down2 = new RoundRectangle2D.Double(cord_xdown2,310,30,175,20,20);

            up3 = new RoundRectangle2D.Double(cord_xup3,-5,30,230,20,20);
            down3 = new RoundRectangle2D.Double(cord_xdown3,350,30,135,20,20);

            up4 = new RoundRectangle2D.Double(cord_xup4,-5,30,115,20,20);
            down4 = new RoundRectangle2D.Double(cord_xdown4,240,30,115,20,20);

            d.setPaint(gp2);
            d.setStroke(color);
            d.fill(up1);
            d.fill(down1);

            d.fill(up2);
            d.fill(down2);

            d.fill(up3);
            d.fill(down3);

            d.fill(up4);
            d.fill(down4);


            d.setPaint(gp3);
            d.setStroke(color);
            d.fill(Ball);
            d.setColor(Color.BLACK);
            d.setFont(font1);
            d.drawString(""+score ,200,50);
            if( Ball.intersects(up1.getBounds()) || Ball.intersects(down1.getBounds()) || Ball.intersects(up2.getBounds()) || Ball.intersects(down2.getBounds()) || Ball.intersects(up3.getBounds()) || Ball.intersects(down3.getBounds()) || Ball.intersects(up4.getBounds()) || Ball.intersects(down4.getBounds()))
        {
            t.stop();
            flag = false;
            d.setColor(Color.red);
            d.setFont(font);
            d.drawString("Game Over : "+score ,100,250);
            retry.setVisible(true);
        }

            retry.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent event) {
            init(); //reset properties
        }

        //...

                @Override
                public void mousePressed(MouseEvent e) {
                 //   throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                   // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                 //   throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseExited(MouseEvent e) {
                   // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }
    });




        }

    }   
    public void update()
    {

        cord_xdown1 -= 5;
        cord_xup1 -= 5;

        cord_xdown2 -= 5;
        cord_xup2 -= 5;

        cord_xdown3 -= 5;
        cord_xup3 -= 5;

        cord_xdown4 -= 5;
        cord_xup4 -= 5;

        cord_xdown5 -= 5;
        cord_xup5 -= 5;

        if( cord_xup1 <=-20)
        {
            cord_xup1 = 500;
            cord_xdown1 = 500;
        }
        if( cord_xup2 <=-20)
        {
            cord_xup2 = 500;
            cord_xdown2 = 500;
        }
        if( cord_xup3 <=-20)
        {
            cord_xup3 = 500;
            cord_xdown3 = 500;
        }
        if( cord_xup4 <=-20)
        {
            cord_xup4 = 500;
            cord_xdown4 = 500;
        }
        if( cord_xup5 <=-20)
        {
            cord_xup5 = 500;
            cord_xdown5 = 500;
        }

        if(count >= 0)
        {
            y_ball = y_ball - 7;
            count--;

            if( y_ball == y_height)
            {
                t.stop();
            }
        }
        else
        {
            y_ball = y_ball + 7;
            if( y_ball == y_height-70)
            {
                t.stop();
            }
        }

        if(cord_xdown1 == x_ball || cord_xdown2 == x_ball || cord_xdown3 == x_ball || cord_xdown4  == x_ball)
            {   
                score = score+1;

            }

    }



     public static void main(String[] args) throws IOException {
        new TheGame();

    }

}

此处retryJLabel,其中我使用MouseListener来执行操作。 当我运行时,JPanel会从JFrame完全删除,但新的JPanel似乎无效。但只有一个组件,即a.setVisble(true)可以工作。

这是玩家离开时的框架。

enter image description here

当玩家点击重试按钮时,此框架。

enter image description here

2 个答案:

答案 0 :(得分:3)

新面板未显示的原因是组件层次结构无效。您尝试重新验证,但是在添加面板之前已经这样做了。在将组件添加到已经可见的容器之后,您需要执行此操作。查看invalidate()

  

当任何与布局相关的信息发生变化时,会自动调用此方法(例如,设置组件的边界,或将组件添加到容器)。

因此,您必须在添加组件后进行验证,而不是之前。 revalidate()无效,然后重新验证组件层次结构。

处理此的正确方法是将游戏恢复为原始状态;只需将一切改回原来的样子。无需创建新面板。

您可以创建一种方法init(),将您的游戏设置为应该如何:

//Contains the properties that will change during gameplay
void init() {
    retry.setVisible(false);
    a.setForeground(Color.YELLOW);
    //...
}

您可以在创建电路板(在构造函数中)和按重试(在监听器中)时调用:

public DrawingPanel() {
    setPreferredSize(new Dimension(300, 300));
    setPreferredSize(new Dimension(300, 300));
    setLayout(null);

    init(); //sets properties
    a.setFont(font1);
    a.setVisible(true);
    a.setBounds(105,200,300,100);
    add(a);

    retry.setBounds(175,260,46,46);
    retry.addMouseListener(new MouseListener() {
        public void mouseClicked(MouseEvent event) {
            init(); //reset properties
        }

        //...
    });
    add(retry);            
}

您不应该在update()方法中为组件添加侦听器,因为update()将被多次调用。在构造函数中添加它。

如果retryJButton,则应使用ActionListener。我不确定,所以我把它当作一个老鼠听众。

您应该避免使用null布局(absolute positioning)。布局管理器使用特定计算来定位和调整组件,以确保在所有平台上生成的GUI看起来都相同。如教程中所提到的,绝对定位是一种可行的选择有一些用途,但总是最好选择布局管理器。 IMO,null布局是不好的做法,人们使用它的唯一原因是他们不了解布局管理器,这本身就是一个问题。

要了解有关布局管理器的更多信息,请查看Visual Guide to Layout Managers路径。 JDK不仅与布局捆绑在一起,而且您还可以创建自己的布局或使用第三方布局,例如MigLayout


编辑:

  1. 将Swing代码发布到Event Dispatch Thread。 Swing事件处理程序(绘图,侦听器)在Event Dispatch Thread上执行。要确保您编写的Swing代码与EDT同步,请使用invokeLaterinvokeAndWait将任何尚未在EDT上执行的Swing代码发布到EDT。

  2. 请勿直接调整框架尺寸。允许框架根据其内部的内容进行调整。您的DrawingPanel(游戏画布)应确定框架的大小。

  3. TheGame不应展开JFrame,因为它不是框架本身,而是框架中包含的内容。对它进行扩展JPanel对您来说会更容易一些(您不会被迫创建一个新类来覆盖paint方法)。虽然 TheGame不应该扩展任何内容,但它应该具有这些东西(有关系,而不是a-a)。但是既然你还是初学者,我也不想用一个全新的设计来压倒你,所以我认为TheGame是真正的游戏画布(事物将被绘制; {{1 }}将扩展TheGame),因此您不再需要JPanel

  4. 如前所述,您不应在paint方法中添加侦听器(或执行只需要一次的任何任务)。请记住,绘制方法用于绘制,而不是初始化或设置值。如果可能,您应该尝试将逻辑排除在该方法之外。

  5. 保持一致。您使用DrawingBoard进行&#34; 点击开始!&#34;,然后使用JLabel进行&#34; 游戏结束&#34 ;.选择一个或另一个。这个选择真的取决于你。对于此示例,我选择使用drawString,因为它与其他渲染方法(如何绘制背景,球和障碍物)一致

  6. 不要在您的绘画方法中创建新对象。您每50毫秒创建一大堆新对象。这不是必需的,会严重影响 批判 的效果。使用drawString关键字时,可以创建新对象。而不是创建一个新对象来改变它(或将其还原),只需改变它的状态。

  7. 利用面向对象。它可以帮助您保持井井有条,并使您能够轻松管理和扩展您的应用程序。不要将一堆变量推到一个类来代表大量不同的东西(newcordx_up1 ......它绝对不可扩展。)

    < / LI>
  8. 查看一些cordx_up2类,例如AdapterMouseAdapter;它们允许您处理事件而无需声明您可能不使用的方法。

  9. 使用访问修饰符。如果您不熟悉它们,请了解它们。如果您知道可以提前使用它的位置,它可以使代码管理变得更加容易。

  10. 您的路径指向具有特定名称的特定驱动器。不应该是这种情况,因为不是每个人都使用该驱动器和/或文件夹名称。将您的图像打包到您的项目中,然后在本地参考它们。

  11. 话虽如此,你还有很多学习要做。

    我所做的是创建一个KeyAdapter类和一个Ball类,以便更有条理。 Obstacleball_x现在位于ball_y类中,以及它的渐变。我们从这个类创建的对象现在将具有这些属性(状态)。我为你的游戏创建了一个球对象。

    Ball类不是为每个极点(cordx_up1)创建新变量,而是有2 ObstacleRoundRectangle2Dtop,它们是极点你的球应该避免。每个障碍物都有一个渐变,用于bottomtop。现在我可以为2个对齐的杆创建1个障碍物。您可以更改障碍物的起始bottom位置(虽然我不建议允许这样做; x应根据其他障碍物位置动态设置,以及尺寸适用于xtop。我创造了5个障碍物。

    为了在使用bottom代替drawString时保持游戏标签的组织(按颜色,消息,位置,字体),我创建了JLabel类。

    我将主要方法分成了自己的名为GameLabel的类,它创建了一个Launcher并将游戏添加到其中;所有关于事件发送线程:

    JFrame

    您的public class Launcher { public static void main(String[] args) throws IOException { EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.add(new TheGame()); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } }); } } 课程现在扩展Game,因此您可以覆盖JPanel方法来渲染游戏。我为你的障碍创建了1 paintBall。我选择LinkedList,因为从前/后插入/移除是保证恒定的时间,这意味着无论列表中有多少障碍物,它都会花费相同的时间来移除/插入。当球通过障碍物时,我将其从列表的前面移除并将其添加到后面。列表中的第一个障碍始终是下一个障碍。

    我看到了一些字符串是如何被重用的,所以我为它们创建了最终变量,你可以很容易地改变它们。还有LinkedListcurrentlyPlaying布尔值。当用户第一次点击(开始游戏)时,isAlive设置为currentlyPlaying,一旦用户点击重启游戏(失败后),设置为true

    false是我用来将鼠标事件转发到readyToJump方法的标志(从技术上讲是update()方法,但它仍然是#cen;内置的&#34;在updatePlayerPostion()方法中。最好将所有逻辑保存在一个地方。如果您不依赖于update()中的readyToJump = true,那么timer.start()将成为您听众方法中唯一的陈述。由于除非计时器已启动,update()无法启动,mouseEvent启动计时器,我们仍必须按照听众的方式开始游戏。

    @SuppressWarnings("serial")
    public final class TheGame extends JPanel implements MouseListener, ActionListener {
        public static final int WIDTH = 500, HEIGHT = 500;
    
        private final String START_SCORE = "0", 
                START_MESSAGE = "Get Ready ! Click to Start.",
                BACKGROUND_URL = "/res/flappy.png";
    
        private boolean currentlyPlaying, readyToJump, isAlive = true;
        private int score;
    
        private Timer timer;
        private Image background;
        private GameLabel messageLabel, scoreLabel;
        private Collection<Obstacle> obstaclesInOrder;
        private LinkedList<Obstacle> obstacles;
        private Ball ball;
    
        public TheGame() {
            setPreferredSize(new Dimension(WIDTH, HEIGHT));
    
            addMouseListener(this);
            timer = new Timer(50, this);
    
            background = loadBackgroundImage();
            messageLabel = new GameLabel(START_MESSAGE, 150, 240);
            scoreLabel = new GameLabel(START_SCORE, 250, 60);
    
            obstacles = new LinkedList<>();
            obstacles.removeAll(obstacles);
            obstaclesInOrder = Arrays.asList(new Obstacle(175, 20, 45), new Obstacle(320), new Obstacle(460), new Obstacle(585), new Obstacle(700));
            obstacles.addAll(obstaclesInOrder);
            ball = new Ball(30, 100);
        }
    
    
        @Override
        public void mouseClicked(MouseEvent e) {
            if (!currentlyPlaying) {
                startGame();
            } else if (!isAlive) {
                reset();
            }
    
            readyToJump = true;
        }
    
        private void startGame() {
            currentlyPlaying = true;
            messageLabel.update("");
            timer.start();
        }
    
        private void endGame() {
            isAlive = false;
            scoreLabel.update("");
            messageLabel.update("Game Over. Your score was " + Integer.toString(score));
            timer.stop();
        }
    
        private void reset() {
            ball.reset();
            for (Obstacle obstacle : obstacles)
                obstacle.reset();
    
            messageLabel.update(START_MESSAGE, 150, 240);
            scoreLabel.update(START_SCORE, 250, 60);
    
            obstacles.removeAll(obstacles);
            obstacles.addAll(obstaclesInOrder);
    
            score = 0;
            isAlive = true;
            currentlyPlaying = false;
            repaint();
        }
    
        @Override
        public void actionPerformed(ActionEvent ae) {
            update();
            repaint();
        }
    
        private void update() {
            if (isAlive) {
                updateBallPosition();
                updateObstaclePositions();
    
                if(ballOutOfBounds() || playerCollidedWithObstacle()) {
                    endGame();
                } else if(ballPassedObstacle()) {
                    addToScore();
                    setupNextObstacle();
                }
            }
        }
    
        private void updateBallPosition() {
            if (readyToJump) {
                readyToJump = false;
                ball.jump();
            } else {
                ball.fall();
            }
        }
    
        private void updateObstaclePositions() {
            for (Obstacle obstacle : obstacles) {
                if (obstacle.getX() <= -obstacle.getWidth()) {
                    obstacle.moveToBack();
                    continue;
                }
    
                obstacle.moveForward();
            }
        }
    
        private void addToScore() {
            scoreLabel.update(Integer.toString(++score));
        }
    
        private void setupNextObstacle() {
            obstacles.addLast(obstacles.removeFirst());
        }
    
        private boolean ballOutOfBounds() {
            return ball.getY() >= HEIGHT || ball.getY() <= 0;
        }
    
        private boolean ballAtObstacle() {
            Obstacle currentObstacle = obstacles.getFirst();
            return ball.getX() + ball.getWidth() >= currentObstacle.getX() && ball.getX() <= currentObstacle.getX() + currentObstacle.getWidth();
        }
    
        private boolean ballPassedObstacle() {
            Obstacle currentObstacle = obstacles.getFirst();
    
            return ball.getX() >= (currentObstacle.getX() + currentObstacle.getWidth());
        }
    
        private boolean playerCollidedWithObstacle() {
            boolean collided = false;
    
            if(ballAtObstacle()) {
                    for (Obstacle obstacle : obstacles) {
                        RoundRectangle2D top = obstacle.getTop();
                        RoundRectangle2D bottom = obstacle.getBottom();
    
                        if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) {
                            collided = true;
                        }
                    }
            }
    
            return collided;
        }
    
        private Image loadBackgroundImage() {
            Image background = null;
            URL backgroundPath = getClass().getResource(BACKGROUND_URL);
    
            if(backgroundPath == null) {
                background = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
            } else {
                try {
                    background = ImageIO.read(backgroundPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
           }
    
            return background;
        }
    
        @Override
        public void paintComponent(Graphics graphics) {
            super.paintComponent(graphics);
            Graphics2D g = (Graphics2D) graphics;
    
            g.drawImage(background, 0, 0, null);
            ball.paint(g);
            for (Obstacle obstacle : obstacles)
                obstacle.paint(g);
    
            scoreLabel.paint(g);
            messageLabel.paint(g);
        }
    
        //...
    }
    

    loadBackgroundImage()加载并返回图像。如果出现问题(图像可能不存在),则会返回黑色图像。

    (大部分)游戏逻辑采用update()方法。虽然它应该全部存在,但由于设计缺陷(来自您使用管理Timer的{​​{1}},并且您在监听器中启动计时器,因此我们需要一些逻辑在听众中)。您的逻辑应该易于阅读,并且应该监视每个执行步骤并将其设置为最低优先级。

    首先,我检查以确保球没有碰到任何东西或超出范围。如果其中一件事发生,我就结束游戏了。

    如果没有,我会检查玩家是否已通过障碍物。如果玩家通过障碍物,我会加入得分:

    update()

    然后我终于更新了这些职位。

    为了避免不断比较玩家的位置和障碍物的位置(看看玩家是否通过了它),我创建了一个private void update() { if (ballOutOfBounds() || playerCollidedWithObstacle()) { endGame(); } else if (ballPassedObstacle()) { addToScore(); setupNextObstacle(); } updateBallPosition(); updateObstaclePositions(); } 方法,用于检查玩家是否在一个障碍。只有这样才能比较职位:

    boolean ballAtObstacle()

    private boolean playerCollidedWithObstacle() { boolean collided = false; if (ballAtObstacle()) { for (Obstacle obstacle : obstacles) { RoundRectangle2D top = obstacle.getTop(); RoundRectangle2D bottom = obstacle.getBottom(); if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) { collided = true; } } } return collided; } 方法调用有点乱。虽然你可以将intersects方法声明为ball.intersects,但我这样做的形状并不是特定的。

    最后,当你跌倒时,我通过提高坠落速度给它一个更加脆弱的鸟类感觉。当你再次跳跃时,它会恢复正常。跳跃的时间越长,你跌得越快。如果你不喜欢这个功能,并且不知道如何删除它,请告诉我,我会告诉你如何。

    涉及的其他课程:

    GameLabel.java

    boolean intersects(Shape shape)

    Obstacle.java

    public class GameLabel {
        private String message;
        private Font font;
        private Color color;
    
        private int x, y;
    
        public GameLabel(String message, int x, int y, Color color, Font font) {
            update(message, x, y, color, font);
        }
    
        public GameLabel(String message, int x, int y) {
            this(message, x, y, Color.BLACK, new Font("Matura MT Script Capitals", Font.ROMAN_BASELINE, 20));
        }
    
        public GameLabel() {
            this("", 0, 0);
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public void setX(int x) {
            this.x = x;
        }
    
        public void setY(int y) {
            this.y = y;
        }
    
        public void setColor(Color color) {
            this.color = color;
        }
    
        public void setFont(Font font) {
            this.font = font;
        }
    
        public final void update(String message, int x, int y, Color color, Font font) {
            this.message = message;
            this.x = x;
            this.y = y;
            this.color = color;
            this.font = font;
        }
    
        public void update(String message, int x, int y) {
            update(message, x, y, color, font);
        }
    
        public void update(String message) {
            update(message, x, y);
        }
    
        public void paint(Graphics2D g) {
            g.setFont(font);
            g.setColor(color);
            g.drawString(message, x, y);
        }
    
        public Font getFont() {
            return font;
        }
    
        public Color getColor() {
            return color;
        }
    
        public String getMessage() {
            return message;
        }
    
        public int getX() {
            return x;
        }
    
        public int getY() {
            return y;
        }
    }
    

    Ball.java

    public class Obstacle {
        public static final int DEFAULT_TOP_HEIGHT = 175;
        public static final int DEFAULT_BOTTOM_HEIGHT = 175;
        public static final int DEFAULT_WIDTH = 30;
        public static final int DEFAULT_ARCH_WIDTH = 20;
        public static final int DEFAULT_ARCH_HEIGHT = 20;
        public static final int DEFAULT_TOP_INSET = -5;
        public static final int DEFAULT_BOTTOM_INSET = TheGame.HEIGHT + 5;
    
        private RoundRectangle2D top, bottom;
        private BasicStroke stroke;
        private GradientPaint gradient;
        private int initialX, x, width;
    
        public Obstacle(int x, int width, int topHeight, int bottomHeight) {
            this.x = initialX = x;
            this.width = width;
    
            top = new RoundRectangle2D.Double(x, DEFAULT_TOP_INSET, width, topHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);
            bottom = new RoundRectangle2D.Double(x, DEFAULT_BOTTOM_INSET-bottomHeight, width, bottomHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);
    
            stroke = new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 20.0f, new float[] { 10.0f }, 0.0f);
            gradient = new GradientPaint(20, 0, Color.DARK_GRAY, 0, 10, Color.GRAY, true);
        }
    
        public Obstacle(int x, int topHeight, int bottomHeight) {
            this(x, DEFAULT_WIDTH, topHeight, bottomHeight);
        }
    
        public void reset() {
            x = initialX;
            top.setRoundRect(initialX, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
            bottom.setRoundRect(initialX, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
        }
    
        public Obstacle(int x, int width) {
            this(x, width, DEFAULT_TOP_HEIGHT, DEFAULT_BOTTOM_HEIGHT);
        }
    
        public Obstacle(int x) {
            this(x, DEFAULT_WIDTH);
        }
    
        public void moveToBack() {
            x = 600;
        }
    
        public void moveForward() {
            x -= 5;
            top.setRoundRect(x, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
            bottom.setRoundRect(x, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
        }
    
        public RoundRectangle2D getTop() {
            return top;
        }
    
        public RoundRectangle2D getBottom() {
            return bottom;
        }
    
        public int getX() {
            return x;
        }
    
        public int getWidth() {
            return width;
        }
    
        public void paint(Graphics2D g) {
            g.setPaint(gradient);
            g.setStroke(stroke);
            g.fill(top);
            g.fill(bottom);
        }
    }
    

答案 1 :(得分:-3)

通过将初始化代码添加到一个方法(resetAll)来重新初始化所有组件,并在您想要重新初始化时调用该方法

以下是一个例子:

import java.awt.*;
import java.awt.event.*;

 public class ResetTest extends Frame{

Button b;
TextField tf;
Frame f;
Panel p;

public ResetTest(){
    f=this;  //intialize frame f to this to have access to our frame in event handler methods
    resetAll(); //first time call to resetAll will initialize all the parameters of the frame
    f.pack();
    addWindowListener(new WindowAdapter(){

        public void windowClosing(WindowEvent we){
            System.exit(0);
        }

    });


    this.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
    this.setVisible(true);

}

/**
This method will be called on click of button to 
reset all the parameters of the frame so that we
get fresh new frame, everything as it was before.
**/
public void resetAll(){
    b=new Button("Reset");
    p=new Panel(new FlowLayout(FlowLayout.CENTER,20,20));
    p.add(b);
    tf = new TextField("Edit And Reset");
    p.add(tf);

    b.addActionListener(new ActionListener(){

        public void actionPerformed(ActionEvent ae){
            remove(p); //remove the panel that contains all our components
            resetAll(); // reset all the components
            f.pack(); //refreshes the view of frame when everything is reset.
        }

    });

        add(p);     
    }
}

class NewClass{
    public static void main(String[] args) {
         ResetTest fReset = new ResetTest();
    }
}