是否协助使用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)这是您的问题。同样,您的
override-painting方法应该调用paintComponent(Graphics g)
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取消否决投票