Repaint() 方法不调用 draw()



基本上,我有一个接口Shape,它有一个draw()animate()方法。每个将绘制形状的类都实现了这一点。还有一个类包含这些Shape类中的一个arrayList。然后有一个单独的类,它包含我的JFrame。我有一个"动画"按钮,它调用该arrayList中的所有animate()方法

我正在使用netbeans,它说我没有错误。draw()方法运行良好。我对动画有意见。我已经调试过了,很明显,repaint()方法不调用任何其他东西,这就是为什么没有一个形状设置动画/移动。它找不到draw()方法,因此不重新绘制它。

这是我的代码:

它是我的一个形状

public class Circle extends Canvas implements Shape{
int xpos, ypos, diam;
GradientPaint color;
public Circle(){
xpos = 103;
ypos = 88;
diam = 140;
color = new GradientPaint(0, 0, new Color(204, 204, 254), 
120, 100, new   Color(255, 255, 255), true);
}
@Override
public void draw(Graphics g){
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(color);
g.fillOval(xpos, ypos, diam, diam); 
}
@Override
public void animate(){
xpos += 10;
ypos += 10;
repaint();
} 
}

这包含我的数组形状列表

公共类ShapeCanvas扩展Canvas{private ArrayList列表;公共ShapeCanvas(){setBackground(彩色白色);setSize(1000700);list=新数组列表<>();Circle Circle=new Circle();list.add(圆圈);
}
//calls all draw() method
@Override
public void paint(Graphics g){
for (int i = 0; i < list.size(); i++){
list.get(i).draw(g);
}
}
//this method calls all animate() method
public void animateAll(){
for (int i = 0; i < list.size(); i++){
list.get(i).animate();
}
}

}

这是我的JFrame

public class Animation extends JFrame{ public Animation(){ setLayout(new BorderLayout()); final ShapeCanvas sc = new ShapeCanvas(); JButton animate = new JButton("Animate"); animate.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent ae){ sc.animateAll(); } }); add(sc, "Center"); add(animate, "South"); } public static void main(String[] args) { Animation g = new Animation(); g.setVisible(true); g.setSize( 1000, 700 ); g.setTitle( "Animation" ); g.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); g.setResizable(false); } }

我尝试过使用JPanelJLayeredPane,尝试过使用revalidate()、validate(),甚至invalidate()。许多人建议使用一个调用super.paintComponent()的paintComponent(),但有没有任何方法可以在不删除/替换draw()方法的情况下做到这一点??虽然,我可能只是错过了一些重要的细节

显然,很多人已经在这里问过了,我也读过其中的大部分。我为被解雇而道歉。但我们非常感谢您的任何帮助或建议

编辑:我修好了!谢谢你们,伙计们!

据我所知,(仅限于上学期的课程)您需要覆盖paintComponent并调用子组件的draw函数。paint()调用paintComponent。

这是我教授上学期的示例代码。我发现他的代码非常清晰,很容易提取。http://students.cs.byu.edu/~cs240ta/fall2013/rodham_files/week-09/图形编程/code/Drawing/src/noevents/DrawingComponent.java

我知道你的编辑说你已经修复了它,但我想确保并指出OP中代码的问题。据我所知,Circle不应该扩展Canvas。在animate中,它调用重新绘制,但重新绘制不起作用,因为它没有作为组件添加到任何位置。

修正看起来像这样:

class Circle implements Shape {
@Override
void animate() {
/* only set positions */
}
}
class ShapeCanvas extends Canvas {
@Override
void animateAll() {
for(/* all shapes */) {
/* call shape.animate() */
}
/* repaint this Canvas */
repaint();
}
}

顺便说一句,我也同意@AndrewThompson的观点,没有什么理由在Swing上使用AWT。尤其是如果你想把两者混合在一起,不要这样做。

最新更新