Java 执着于设计
我有一个小的GUI java程序,我正在工作,但如何设计各部分应该一起工作让我感到沮丧。基本上,我需要做的是在面板上画一辆“汽车”,然后将面板连接到框架上。然后设置面板动画,以产生移动的错觉 我的问题是,我不知道如何将制作动画的代码移动到它自己的类中。当我开始做这个的时候,我先做了UI元素。然后我遇到了Timer类,并在一个UI元素类(CarBody)中使用了该类。我的代码现在的工作方式是,只要我运行这个程序,“汽车”就开始移动,因为我没有将它设置为通过按下按钮触发。我不明白如何将动画代码移动到它的on类中,并通过按下按钮触发它 如果我能在performAction()方法中调用repaint(),我可以在两秒钟内解决这个问题。问题是我不能那样做!它不会那样编译 我所做的是Java 执着于设计,java,swing,timer,Java,Swing,Timer,我有一个小的GUI java程序,我正在工作,但如何设计各部分应该一起工作让我感到沮丧。基本上,我需要做的是在面板上画一辆“汽车”,然后将面板连接到框架上。然后设置面板动画,以产生移动的错觉 我的问题是,我不知道如何将制作动画的代码移动到它自己的类中。当我开始做这个的时候,我先做了UI元素。然后我遇到了Timer类,并在一个UI元素类(CarBody)中使用了该类。我的代码现在的工作方式是,只要我运行这个程序,“汽车”就开始移动,因为我没有将它设置为通过按下按钮触发。我不明白如何将动画代码移动到
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();
}
}
}
如果我能在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) );
}
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
公共类TimerAnimation扩展JLabel实现ActionListener
{
int deltaX=2;
int deltaY=3;
int方向x=1;
int方向y=1;
公共定时(
int startX,int startY,
int deltaX,int deltaY,
int directionX,int directionY,
整数延迟)
{
this.deltaX=deltaX;
this.deltaY=deltaY;
this.directionX=directionX;
this.directionY=directionY;
设置图标(新的图像图标(“dukewaveed.gif”);
//设置图标(新的图像图标(“copy16.gif”);
设置大小(getPreferredSize());
设置位置(startX、startY);
新的javax.swing.Timer(delay,this.start();
}
已执行的公共无效操作(操作事件e)
{
容器父级=getParent();
//确定下一个X位置
int-nextX=getLocation().x+(deltaX*方向x);
如果(nextX<0)
{
nextX=0;
方向x*=-1;
}
if(nextX+getSize().width>parent.getSize().width)
{
nextX=parent.getSize().width-getSize().width;
方向x*=-1;
}
//确定下一个Y位置
int nextY=getLocation().y+(deltaY*directionY);
if(nextY<0)
{
nextY=0;
方向y*=-1;
}
if(nextY+getSize().height>parent.getSize().height)
{
nextY=parent.getSize().height-getSize().height;
方向y*=-1;
}
//移动标签
设置位置(nextX、nextY);
}
公共静态void main(字符串[]args)
{
JPanel面板=新的JPanel();
JFrame=新JFrame();
frame.setContentPane(面板);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
//frame.getContentPane().add(新的TimerAnimation(10,10,2,3,1,1,10));
frame.getContentPane().add(新的TimerAnimation(3001003,2,-1,1,20));
//frame.getContentPane().add(新的TimerAnimation(0,000,5,0,1,1,20));
frame.getContentPane().add(新的TimerAnimation(0,200,5,0,1,1,80));
框架。设置尺寸(400400);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
//frame.getContentPane().add(新的TimerAnimation(10,10,2,3,1,1,10));
//frame.getContentPane().add(新的TimerAnimation(10,10,3,0,1,1,10));
}
}
本例不进行自定义绘制,动画是通过调用标签上的setlocation(…)方法完成的,这将导致重新绘制(),因此解决方案与您的略有不同,但关键点是不要更改paintComponent()中的位置值方法。Amen:paintComponent仅用于绘制,不应包含任何程序逻辑。原始海报必须意识到,他无法完全控制何时或是否调用此方法。