Анимация мяча в качелях - PullRequest
4 голосов
/ 21 марта 2012

Проблема в том, что когда я изменяю размер JFrame, анимация продолжается с предварительно заданными размерами для JComponent.Есть ли способ, которым я могу обновить мои width и height переменные при изменении размера JFrame, чтобы анимация могла работать вместе с новыми координатами.

Проще говоря, скажем, что JComponent имеет начальные width = 300 и height = 300, поэтому BALL перемещается внутри этих указанных Co-ordinates.Теперь, если я изменю размер моего JFrame, размер для JComponent все еще останется как есть, то есть width = 300 и height = 300, но то, на что я надеялся, - это способ изменить эти переменные в соответствии с текущим размером окна,Дайте мне знать, если мне не хватает объяснения моей проблемы.

Вот код, который я использую:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BallAnimation
{
    private int x;
    private int y;
    private int count;
    private int width;
    private int height;
    private int speedValue;
    private boolean flag;
    /*
     * These variables are used to keep track of 
     * the ball, either it is going LEFT or RIGHT
     * depending on that, we will set the 
     * Co-ordinates.
     */
    private boolean toLeft, toRight;

    private boolean fromTop, fromBottom;

    private Timer timer;

    private JButton button;

    private ActionListener actionTimer; 
    private ActionListener buttonAction;

    public BallAnimation()
    {
        x = y = count = 0;
        flag = toLeft = false;
        toRight = true;
        fromTop = true;
        fromBottom = false;
        speedValue = 5;
    }

    public static void main(String args[])
    {
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                BallAnimation animation = new BallAnimation();
                animation.go();
            }
        };      
        SwingUtilities.invokeLater(runnable);
    }

    public void go()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //JPanel contentPane = new JPanel();

        /*
         * Class Name : 
         * Java Naming Convention says that class names 
         * should be in Pascal Case, i.e. the first
         * letter of the class name should be capitalized
         * and every new word must start with a capitalized 
         * Alphabet.
         * For Example : 
         * public class ClassName{...}
         * ----------------------------------------------------------
         * Variable Name : 
         * Java Naming Convention says that the variable name
         * should be in Camel Case, i.e. the first letter of 
         * the variable name should be small case or _ (underscore)
         * and every new word must start with a capitalized
         * Alphabet.
         * ---------------------------------------------------------
         */
        final MyDraw drawPanel = new MyDraw(0, 0);
        x = drawPanel.getXValue();
        y = drawPanel.getYValue();
        //contentPane.add(drawPanel);

        actionTimer = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {               
                if (fromTop && !fromBottom && x < width && y < height 
                            && toRight && !toLeft)
                {
                    x += speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x < width && y >= height
                                 && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the TOP LEFT Side
                     * touched the BOTTOM of the JPanel.
                     */
                    y -= speedValue;
                    x += speedValue;
                    fromTop = false;
                    fromBottom = true;
                }
                else if (!fromTop && fromBottom && x < width && y <= 0
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from BOTTOM LEFT Side
                     * touched the TOP of the JPanel. 
                     */
                    fromTop = true;
                    fromBottom = false;
                    x += speedValue;
                    y += speedValue;
                }
                else if (!fromTop && fromBottom && x < width && y < height
                                  && toRight && !toLeft)
                {
                    x += speedValue;
                    y -= speedValue;
                }
                else if (!fromTop && fromBottom && x >= width && y < height
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM LEFT Side
                     * touched the RIGHT Side of the JPanel.
                     */
                    toRight = false;
                    toLeft = true;
                    x -= speedValue;
                    y -= speedValue;
                }                
                else if (!fromTop && fromBottom && x < width && y <= 0
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM RIGHT Side
                     * touched the Top Side of the JPanel.
                     */
                    fromTop = true;
                    fromBottom = false;
                    x -= speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x <= 0 && y < height
                                 && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the TOP RIGHT Side
                     * touched the LEFT Side of the JPanel.
                     */
                    toRight = true;
                    toLeft = false;
                    x += speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x >= width && y < height
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the TOP LEFT Side
                     * touched the RIGHT Side of the JPanel
                     */
                    toRight = false;
                    toLeft = true;
                    x -= speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x < width && y < height
                                  && !toRight && toLeft)
                {
                    x -= speedValue;
                    y += speedValue;
                }
                else if (!fromTop && fromBottom && x <= 0 && y < height
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM RIGHT Side
                     * touched the LEFT Side of the JPanel.
                     */
                    toRight = true;
                    toLeft = false;
                    x += speedValue;
                    y -= speedValue;
                }
                else if (!fromTop && fromBottom && x < width && y < height
                                  && !toRight && toLeft)
                {
                    x -= speedValue;
                    y -= speedValue;
                }
                else if (fromTop && !fromBottom && x < width && y >= height
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the TOP RIGHT Side
                     * touched the BOTTOM Side of the JPanel.
                     */
                    fromTop = false;
                    fromBottom = true;
                    x -= speedValue;
                    y -= speedValue;
                }
                System.out.println("X : " + x);
                System.out.println("Y : " + y);
                System.out.println("Direction is LEFT : " + toLeft);
                System.out.println("Direction is RIGHT : " + toRight);
                System.out.println("Coming from TOP : " + fromTop);
                System.out.println("Coming from BOTTOM : " + fromBottom);
                drawPanel.setXYValues(x, y);
            }
        };

        buttonAction = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (!flag)
                {
                    timer.start();
                    button.setText("STOP ANIMATION");
                    flag = true;
                }
                else if (flag)
                {
                    timer.stop();
                    button.setText("START ANIMATION");
                    flag = false;
                }
            }
        };

        button = new JButton("START ANIMATION");
        button.addActionListener(buttonAction);

        frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
        frame.getContentPane().add(button, BorderLayout.PAGE_END);
        frame.setSize(300, 300);
        //frame.pack();
        frame.setVisible(true);        

        timer = new Timer(40, actionTimer);
        width = drawPanel.getWidth() - 30;
        System.out.println("WIDTH : " + width);
        height = drawPanel.getHeight() - 30;    
        System.out.println("HEIGHT : " + height);
    }
    class MyDraw extends JComponent
    {
        private int x;
        private int y;
        private Timer timer;

        public MyDraw(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int getXValue()
        {
            return x;
        }

        public int getYValue()
        {
            return y;
        }

        public void setXYValues(int x, int y)
        {
            this.x = x;
            this.y = y;
            repaint();
        }

        public Dimension getPreferredSize()
        {
            return (new Dimension(300, 300));
        }

        public void paintComponent(Graphics g)
        {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.BLUE);
            g.fillOval(x, y, 40, 40);
        }
    }
}

Ответы [ 3 ]

6 голосов
/ 21 марта 2012

Теперь это целая куча кода! Попробуйте этот вариант (ломает одну или две вещи, но исправляет основную проблему). Исправление заключается в том, чтобы основывать ширину / высоту на текущем размере компонента.

package test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BallAnimation
{
    private int x;
    private int y;
    private int count;
    //private int drawPanel.getWidth();
    //private int drawPanel.getHeight();
    private int speedValue;
    private boolean flag;
    /*
     * These variables are used to keep track of 
     * the ball, either it is going LEFT or RIGHT
     * depending on that, we will set the 
     * Co-ordinates.
     */
    private boolean toLeft, toRight;

    private boolean fromTop, fromBottom;

    private Timer timer;

    private JButton button;

    private ActionListener actionTimer; 
    private ActionListener buttonAction;

    MyDraw drawPanel;

    public BallAnimation()
    {
        x = y = count = 0;
        flag = toLeft = false;
        toRight = true;
        fromTop = true;
        fromBottom = false;
        speedValue = 5;
    }

    public static void main(String args[])
    {
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                BallAnimation animation = new BallAnimation();
                animation.go();
            }
        };      
        SwingUtilities.invokeLater(runnable);
    }

    public void go()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //JPanel contentPane = new JPanel();

        /*
         * Class Name : 
         * Java Naming Convention says that class names 
         * should be in Pascal Case, i.e. the first
         * letter of the class name should be capitalized
         * and every new word must start with a capitalized 
         * Alphabet.
         * For Example : 
         * public class ClassName{...}
         * ----------------------------------------------------------
         * Variable Name : 
         * Java Naming Convention says that the variable name
         * should be in Camel Case, i.e. the first letter of 
         * the variable name should be small case or _ (underscore)
         * and every new word must start with a capitalized
         * Alphabet.
         * ---------------------------------------------------------
         */
        drawPanel = new MyDraw(0, 0);
        x = drawPanel.getXValue();
        y = drawPanel.getYValue();
        //contentPane.add(drawPanel);

        actionTimer = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {               
                if (fromTop && !fromBottom && x < drawPanel.getWidth() && y < drawPanel.getHeight() 
                            && toRight && !toLeft)
                {
                    x += speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x < drawPanel.getWidth() && y >= drawPanel.getHeight()
                                 && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the TOP LEFT Side
                     * touched the BOTTOM of the JPanel.
                     */
                    y -= speedValue;
                    x += speedValue;
                    fromTop = false;
                    fromBottom = true;
                }
                else if (!fromTop && fromBottom && x < drawPanel.getWidth() && y <= 0
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from BOTTOM LEFT Side
                     * touched the TOP of the JPanel. 
                     */
                    fromTop = true;
                    fromBottom = false;
                    x += speedValue;
                    y += speedValue;
                }
                else if (!fromTop && fromBottom && x < drawPanel.getWidth() && y < drawPanel.getHeight()
                                  && toRight && !toLeft)
                {
                    x += speedValue;
                    y -= speedValue;
                }
                else if (!fromTop && fromBottom && x >= drawPanel.getWidth() && y < drawPanel.getHeight()
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM LEFT Side
                     * touched the RIGHT Side of the JPanel.
                     */
                    toRight = false;
                    toLeft = true;
                    x -= speedValue;
                    y -= speedValue;
                }                
                else if (!fromTop && fromBottom && x < drawPanel.getWidth() && y <= 0
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM RIGHT Side
                     * touched the Top Side of the JPanel.
                     */
                    fromTop = true;
                    fromBottom = false;
                    x -= speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x <= 0 && y < drawPanel.getHeight()
                                 && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the TOP RIGHT Side
                     * touched the LEFT Side of the JPanel.
                     */
                    toRight = true;
                    toLeft = false;
                    x += speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x >= drawPanel.getWidth() && y < drawPanel.getHeight()
                                  && toRight && !toLeft)
                {
                    /*
                     * Since the ball coming from the TOP LEFT Side
                     * touched the RIGHT Side of the JPanel
                     */
                    toRight = false;
                    toLeft = true;
                    x -= speedValue;
                    y += speedValue;
                }
                else if (fromTop && !fromBottom && x < drawPanel.getWidth() && y < drawPanel.getHeight()
                                  && !toRight && toLeft)
                {
                    x -= speedValue;
                    y += speedValue;
                }
                else if (!fromTop && fromBottom && x <= 0 && y < drawPanel.getHeight()
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the BOTTOM RIGHT Side
                     * touched the LEFT Side of the JPanel.
                     */
                    toRight = true;
                    toLeft = false;
                    x += speedValue;
                    y -= speedValue;
                }
                else if (!fromTop && fromBottom && x < drawPanel.getWidth() && y < drawPanel.getHeight()
                                  && !toRight && toLeft)
                {
                    x -= speedValue;
                    y -= speedValue;
                }
                else if (fromTop && !fromBottom && x < drawPanel.getWidth() && y >= drawPanel.getHeight()
                                  && !toRight && toLeft)
                {
                    /*
                     * Since the ball coming from the TOP RIGHT Side
                     * touched the BOTTOM Side of the JPanel.
                     */
                    fromTop = false;
                    fromBottom = true;
                    x -= speedValue;
                    y -= speedValue;
                }
                System.out.println("X : " + x);
                System.out.println("Y : " + y);
                System.out.println("Direction is LEFT : " + toLeft);
                System.out.println("Direction is RIGHT : " + toRight);
                System.out.println("Coming from TOP : " + fromTop);
                System.out.println("Coming from BOTTOM : " + fromBottom);
                drawPanel.setXYValues(x, y);
            }
        };

        buttonAction = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (!flag)
                {
                    timer.start();
                    button.setText("STOP ANIMATION");
                    flag = true;
                }
                else if (flag)
                {
                    timer.stop();
                    button.setText("START ANIMATION");
                    flag = false;
                }
            }
        };

        button = new JButton("START ANIMATION");
        button.addActionListener(buttonAction);

        frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
        frame.getContentPane().add(button, BorderLayout.PAGE_END);
        frame.setSize(300, 300);
        //frame.pack();
        frame.setVisible(true);        

        timer = new Timer(40, actionTimer);
        System.out.println("WIDTH : " + drawPanel.getWidth());
        System.out.println("HEIGHT : " + drawPanel.getHeight());
    }
    class MyDraw extends JComponent
    {
        private int x;
        private int y;
        private Timer timer;

        public MyDraw(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int getXValue()
        {
            return x;
        }

        public int getYValue()
        {
            return y;
        }

        public void setXYValues(int x, int y)
        {
            this.x = x;
            this.y = y;
            repaint();
        }

        public Dimension getPreferredSize()
        {
            return (new Dimension(300, 300));
        }

        public void paintComponent(Graphics g)
        {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(Color.BLUE);
            g.fillOval(x, y, 40, 40);
        }
    }
}
4 голосов
/ 21 марта 2012

просто нужно addHierarchyBoundsListener (...) , к вашему MyDraw объекту, т.е. drawPanel, как описано ниже:

private HierarchyBoundsListener boundsListener = 
                                new HierarchyBoundsListener()
{
    public void ancestorMoved(HierarchyEvent he)
    {
    }

    public void ancestorResized(HierarchyEvent he)
    {
        JComponent component = (JComponent) he.getComponent();
        width = component.getWidth() - 30;
        height = component.getHeight() - 30;
    }
};

И добавить эток вашему drawPanel объекту вы делаете:

drawPanel.addHierarchyBoundsListener(boundsListener);
2 голосов
/ 21 марта 2012

Полагаю, вам просто нужно привязать некоторое количество слушателей (WindowEventListener?) К JFrame, чтобы width и height обновлялись при изменении размеров окна.

...