摇摆中的球动画

问题是,当我调整JFrame的大小时,动画继续使用它为JComponent提供的预提供的维度。 有没有一种方法可以在我调整JFrame大小时更新我的widthheight变量,以便动画可以与新的坐标一起运行。

简单来说,假设JComponent初始width = 300height = 300 ,那么BALL会在这些指定Co-ordinates内移动。 现在,如果我调整JFrame的大小, JComponent的大小仍保持原样,即width = 300height = 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, 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 = 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 = 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 = 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 = 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); } } } 

现在这是一个完整的堆积’帮助代码! 试试这个变种(打破一两件事,但解决了主要问题)。 修复方法是将宽度/高度基于组件的当前大小。

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

只需简单地将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); 

我希望你只需要将各种监听器( WindowEventListener ?)绑定到JFrame,这样只要窗口尺寸发生变化,就会更新widthheight