我正在研究一个小的GUI java程序,但设计这些部分应该如何协同工作让我感到沮丧。基本上我需要做的是在面板上画一个“汽车”并将该面板连接到框架上。然后为面板设置动画,以产生运动的幻觉。
我的问题是我不明白如何将动画的代码移动到它自己的类。当我开始研究这个时,我首先制作了UI元素。然后我遇到了Timer类,并将该类用于本应该只是一个UI元素类(CarBody)。我的代码现在的工作方式是,一旦我运行程序,“汽车”开始移动,因为我没有将它设置为按下按钮触发。我不明白如何将动画代码移动到它上面的类,并按下按钮触发它。
如果我可以在performAction()方法中调用repaint(),我可以在两秒内解决这个问题。问题是我做不到!它不会那样编译。
我所做的是
class CarBody extends JPanel {
private int xCoordinate = 0;
CarBody(){
Timer timer = new Timer(1000,new TimerListener());
timer.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//g.fillRect(10, 10, 60, 50);
if(xCoordinate > getWidth()){
xCoordinate = -20;
}
xCoordinate +=100;
g.fillRect(xCoordinate,10,60,50);
}
class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
repaint();
}
}
}
答案 0 :(得分:2)
如果我可以在performAction()方法中调用repaint(),我可以在两秒内解决这个问题。
您不应该在paintComponent()方法中更改汽车坐标。您应该有一个方法来设置坐标,然后重新绘制汽车。
创建ActionListener类时,将要重新绘制的面板作为参数传递给类。然后你可以调用“changeLocation”方法,它将更新汽车的位置,然后自己调用repaint()。
对于另一种方法,您可以向标签添加图标,只需更改标签的位置,它就会自动重新绘制。这是一个简单的例子:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerAnimation extends JLabel implements ActionListener
{
int deltaX = 2;
int deltaY = 3;
int directionX = 1;
int directionY = 1;
public TimerAnimation(
int startX, int startY,
int deltaX, int deltaY,
int directionX, int directionY,
int delay)
{
this.deltaX = deltaX;
this.deltaY = deltaY;
this.directionX = directionX;
this.directionY = directionY;
setIcon( new ImageIcon("dukewavered.gif") );
// setIcon( new ImageIcon("copy16.gif") );
setSize( getPreferredSize() );
setLocation(startX, startY);
new javax.swing.Timer(delay, this).start();
}
public void actionPerformed(ActionEvent e)
{
Container parent = getParent();
// Determine next X position
int nextX = getLocation().x + (deltaX * directionX);
if (nextX < 0)
{
nextX = 0;
directionX *= -1;
}
if ( nextX + getSize().width > parent.getSize().width)
{
nextX = parent.getSize().width - getSize().width;
directionX *= -1;
}
// Determine next Y position
int nextY = getLocation().y + (deltaY * directionY);
if (nextY < 0)
{
nextY = 0;
directionY *= -1;
}
if ( nextY + getSize().height > parent.getSize().height)
{
nextY = parent.getSize().height - getSize().height;
directionY *= -1;
}
// Move the label
setLocation(nextX, nextY);
}
public static void main(String[] args)
{
JPanel panel = new JPanel();
JFrame frame = new JFrame();
frame.setContentPane(panel);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().setLayout(null);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
frame.getContentPane().add( new TimerAnimation(300, 100, 3, 2, -1, 1, 20) );
// frame.getContentPane().add( new TimerAnimation(0, 000, 5, 0, 1, 1, 20) );
frame.getContentPane().add( new TimerAnimation(0, 200, 5, 0, 1, 1, 80) );
frame.setSize(400, 400);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
// frame.getContentPane().add( new TimerAnimation(10, 10, 3, 0, 1, 1, 10) );
}
}
这个例子,不做自定义绘画,动画是通过调用标签上的setlocation(...)方法完成的,这会导致重绘()所以解决方案与你的略有不同,但关键点不要更改paintComponent()方法中的位置值。