Swing自定义绘画动画在到达框架的半宽处后停止

问题描述:

我试图回答与moving a ball across the screen while changing its color over time有关的问题,但是我遇到了一个奇怪的错误(最可能是在我的代码中),并且在询问此问题时我来到related question但是这个问题是使用客户端 - 服务器架构,而我的是一个简单的Swing应用程序。Swing自定义绘画动画在到达框架的半宽处后停止

发生了什么事情是,当圆/球,但是你想命名它,达到JPanelJFrame的半宽度,它变得不可见或停止。

起初我以为这可能是我的JPanel被定位不好,但我添加了一个Border到它,所以我可以看到它的尺寸,但它显示了JFrame的整个空间周围的整个边框。

接下来,我认为这可能是一些算术问题,所以我决定让球大于和小于我最初绘制它,给我相同的结果,当我放大或缩小窗口尺寸。

为了得到下面的输出,我需要通过9,而不是10我最初加入改变增量,因为如果我将其更改为10它变得不可见:

enter image description here

下面的代码产生上面的输出:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.Ellipse2D; 
import java.util.Random; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class ChangingColorBall { 
    private JFrame frame; 
    private Timer timer; 
    private BallPane ballPane; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new ChangingColorBall()::createAndShowGui); 
    } 

    private void createAndShowGui() { 
     frame = new JFrame(getClass().getSimpleName()); 
     ballPane = new BallPane(); 

     timer = new Timer(100, e -> { 
      ballPane.increaseX(); 
     }); 

     ballPane.setBorder(BorderFactory.createLineBorder(Color.RED)); 

     frame.add(ballPane); 

     frame.pack(); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     timer.start(); 
    } 

    @SuppressWarnings("serial") 
    class BallPane extends JPanel { 
     private int x; 
     private static final int Y = 50; 
     private static final int SIZE = 20; 
     private Color color; 
     private Random r; 

     public void increaseX() { 
      x += 9; 
      r = new Random(); 
      color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)); 
      revalidate(); 
      repaint(); 
     } 

     public int getX() { 
      return x; 
     } 

     public void setX(int x) { 
      this.x = x; 
     } 

     public Color getColor() { 
      return color; 
     } 

     public void setColor(Color color) { 
      this.color = color; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 

      g2d.setColor(color); 
//   g2d.fill(new Ellipse2D.Double(x, Y, SIZE, SIZE)); 
      g2d.fillOval(x, Y, SIZE, SIZE); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 100); 
     } 
    } 
} 

我还以为这可能是一些涉及到Shapes API,并决定茶将它改为fillOval以及相同的结果,我无法发布GIF,但是如果需要,稍后将添加它。

我在MacOS塞拉利昂10.12.6(16G29)在MacBook Pro上工作(13 '' 的Retina显示屏,2015年初)编制和Java 1.8下运行它

我稍后会测试该代码以及在我自己的PC上,而不是在我工作的Mac上,但是,这可能是与Swing API有关的错误还是我自己代码中的错误?如果是这样,我做错了什么?由于它对我而言并不明显

+0

创建一个“形状”对象,它具有位置(和颜色)的概念,并可以自己绘制,更新并使面板画上它 – MadProgrammer

问题是您无意中覆盖了BallPane类中的JComponent中定义的getX()方法。

结果每当由getX()访问也在​​改变为getX()现在返回您的字段x其定义如何球移动,从而导致这种行为的JPanel的x坐标。您应该从BallPane中删除方法getX()或重命名它。

+0

我多么愚蠢......我没有注意到IDE的绿色箭头向我展示重写并完全忘记了它... – Frakcool