是否协助使用java repaint()方法?

是否协助使用java repaint()方法?,java,swing,animation,Java,Swing,Animation,我试图制作一个矩形在屏幕上移动,但它只是重新绘制,没有去掉前面的矩形,使它看起来像一个巨大的矩形在屏幕上移动。任何帮助都将不胜感激,以下是我的代码: import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.Timer; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener

我试图制作一个矩形在屏幕上移动,但它只是重新绘制,没有去掉前面的矩形,使它看起来像一个巨大的矩形在屏幕上移动。任何帮助都将不胜感激,以下是我的代码:

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;

@SuppressWarnings("serial")
public class Test extends JFrame implements ActionListener{
int x=50;
Timer tm = new Timer(30,this);

public static void main(String[] args){
    new Test();
}

public Test(){
    this.setSize(700, 500);
    this.setTitle("Drawing Shapes");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
}

public void paint(Graphics g){
     Graphics2D graph2 = (Graphics2D)g;

     Shape Rect = new Rectangle2D.Float(x, 50, 50, 30);
     graph2.setColor(Color.RED);
     graph2.fill(Rect);
     tm.start();
    }

public void actionPerformed(ActionEvent e){
    x=10+x;
    repaint();
}
}
  • 在JFrame中保存并显示的JPanel中绘制。不要直接在JFrame中绘制,因为这样会有绘制不应该被弄乱的东西的风险,例如根窗格、边框、子组件等等,。。。此外,如果直接在JFrame的绘制方法中绘制,则会导致动画的起伏,从而失去自动双缓冲的好处
  • 您应该重写JPanel的paintComponent方法,而不是它的paint方法
  • 始终在您自己的绘制方法中调用super的绘制方法(这里应该再次调用paintComponent)这是您的问题。同样,您的
    paintComponent(Graphics g)
    override-painting方法应该调用
    super.paintComponent(g)在其第一行。这将删除旧图像

    • 你正在打破油漆链

      public void paint(Graphics g){
          // Broken here...
          Graphics2D graph2 = (Graphics2D)g;
      
          Shape Rect = new Rectangle2D.Float(x, 50, 50, 30);
          graph2.setColor(Color.RED);
          graph2.fill(Rect);
          tm.start();
      
      }
      
      您必须调用
      super.paint
      。有关在Swing中绘制的更多详细信息,请参见和

      顶级容器不是双缓冲的,不建议直接对其进行绘制,而是创建一个自定义组件,该组件从
      JPanel
      扩展,并覆盖其
      paintComponent
      方法(在执行任何自定义绘制之前调用
      super.paintComponent

      一般来说,您应该避免从顶级容器(如
      JFrame
      )进行扩展,因为您没有向类添加任何新功能,它们将您锁定在单个用例中,从而降低了类的可重用性


      不要在
      paint
      方法中调用
      tm.start
      ,在paint方法中除了paint之外不应执行任何操作,切勿尝试修改状态或执行可能间接修改组件状态的操作,这是一个很好的方法,让你的程序消耗你的CPU来增加其他人已经说过的内容

      我注意到您使用
      this.setLocationRelativeTo(null)
      来实现一个简单的应用程序。不是说它不好,但您可能希望检查此线程以确保它是您想要的


      出于某种原因,在他的代码上调用super.paint只会画不出任何东西。@Jean-FrançoisSavard你是先调用它的吗?是否有其他组件已添加到框架中?是的,正在尝试找出原因,没有添加任何内容。。。它对你有用吗?有可能在重新绘制框架时,它也在绘制
      JRootPane
      ,它是
      contentPane
      ,在你身上绘制…另一个不覆盖顶级容器的
      paint
      的好理由-基于我的快速测试,这似乎是这样的情况…很有趣,我将尝试对此进行更多调试。很好,现在您已经绘制了整个框架,包括它的子框架:P,另外,请注意,当绘制子组件时,Swing不必通知父容器(它们可以独立绘制)这可能会导致无休止的问题和瑕疵…这就是为什么不建议覆盖顶级容器的
      paint
      ,尤其是
      paint
      …你试图用儿童创可贴来阻止出血…@MadProgrammer我同意这不是最好的解决方案,只是想给OP一个替代方案,因为另一个不起作用,也许他不想重新设计他的应用程序。如果OP想要一个无故障的体验,他们需要。他们可以与API抗争,也可以与API合作it@MadProgrammer我再次表示同意。然而,也许他的经理不是因为钱的原因?或者这是一个学校项目,重新编写应用程序并不值得。他不重新设计有很多可能的原因,我的解决方案可以不必重新设计。最重要的是他从错误中吸取教训,不再重蹈覆辙。如果不值得在这里重新设计,则无需重新设计。“但是,也许他的经理出于金钱原因不需要重新设计?”以后修复它会花费更多的维护费用。最好现在就修!顺便说一句,我正要否决投票,直到我看到最后一段+链接,并决定+1取消否决投票