我正在尝试做一个简单的动画,其中一个绿色圆圈在一个名为panel
的小部件上以模糊图案对角移动,该小部件是class MyPanel
的一个实例,扩展了JPanel
。
JFrame
有一个开始按钮,当按下该按钮时,应该通过调用actionPerformed
方法启动动画(我在其中调用animate方法,调用repaint
方法同时在主类中连续递增圆的x和y坐标,而主类本身就是监听器。
相反,当按下按钮时,圆圈显示在初始坐标处,然后在延迟之后,另一个圆圈显示在最终坐标处。有人可以帮我弄清楚我哪里错了吗?我是Java的初学者,他在C年前做过一些基本编程。
提前致谢。这是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Smear implements ActionListener{
JFrame frame;
MyPanel panel;
JButton button;
Smear animgui1;
int x=70;
int y=70;
public static void main(String[] args) {
Smear animgui=new Smear();
animgui.project();
animgui.set(animgui);
}
public void set(Smear anim) {
animgui1=anim;
}
public void project() {
frame=new JFrame();
panel=new MyPanel();
button=new JButton("Start");
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.NORTH, button);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void animate() {
while(x!=200) {
panel.repaint();
x++;
y++;
System.out.println("++++");
try {
Thread.sleep(50);
}
catch(Exception ex) {};
}
}
public void actionPerformed(ActionEvent event) {
animgui1.animate();
}
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillOval(x,y,40,40);
}
}
}
但与此同时,我在没有该按钮的情况下创建了另一个程序SmearGui(我删除了与按钮和监听器有关的代码),它按照预期的方式工作;圆圈以涂抹模式慢慢移动。代码是:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SmearGui{
JFrame frame;
MyPanel panel;
//JButton button;
SmearGui animgui1;
int x=70;
int y=70;
public static void main(String[] args){
SmearGui animgui=new SmearGui();
animgui.project();
animgui.set(animgui);
animgui.animate();
}
public void set(SmearGui anim){
animgui1=anim;
}
public void project(){
frame=new JFrame();
panel=new MyPanel();
//button=new JButton("Start");
//button.addActionListener(this);
//frame.getContentPane().add(BorderLayout.NORTH, button);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void animate(){
while(x!=200){
panel.repaint();
x++;
y++;
try{
Thread.sleep(50);
}
catch(Exception ex){};
}
}
/*public void actionPerformed(ActionEvent event){
animgui1.animate();
}*/
class MyPanel extends JPanel{
public void paintComponent(Graphics g){
g.setColor(Color.green);
g.fillOval(x,y,40,40);
}
}
}
上面的代码将animate方法放在main本身。
答案 0 :(得分:1)
重绘是异步的,因此您的代码不会等待面板重绘,然后才能继续。您的循环代码比重绘面板要快得多。使用在重绘发生的同一个线程上执行的swing计时器,这样你就不会在计算和重绘时间上出现这种不匹配。