Ball Swing Animation

The problem is when I resize the JFrame , the animation continues with it. Predefined dimensions for JComponent . Is there a way to update the width and height variables when resizing the JFrame so that the animation can work along with the new coordinates.

In simpler expressions, for example, JComponent has initial width = 300 and height = 300 , so BALL moves inside the specified Co-ordinates . Now, if I resized my JFrame , the size for the JComponent still remains the same as ie width = 300 and height = 300 , but what I was hoping for is a way to change these variables with the current window size.Let me know if I have nothing to explain in my problem.

Here is the code I'm using:

 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, ie 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, ie 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); } } } 
+4
source share
3 answers

Now this is the whole code help! Try this option (breaks one or two things, but fixes the underlying problem). The fix is ​​to base the width / height on the current component size.

 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, ie 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, ie 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); } } } 
+6
source

you just need addHierarchyBoundsListener (...) for your MyDraw object, i.e. drawPanel , as described below:

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

And to add this to your drawPanel object, you do:

 drawPanel.addHierarchyBoundsListener(boundsListener); 
+4
source

I expect that you just need to bind several different listeners ( WindowEventListener ?) To the WindowEventListener so that the width and height updated whenever the window is WindowEventListener .

+2
source

Source: https://habr.com/ru/post/1402614/


All Articles