在线程中使用画布对象制作简单动画-Java

在线程中使用画布对象制作简单动画-Java,java,animation,applet,awt,java-canvas,Java,Animation,Applet,Awt,Java Canvas,我有一个小程序,正如我现在写的,在按下“Run”按钮后,它应该在顶部(代码中的drawingpanel)绘制并弹起一个球。在线查看其他示例,并使用未使用Canvas的不同程序中的代码,我无法找出我的Ball对象未显示的原因。我已经测试了程序的流程,并且所有的方法都按它们应该的方式被调用,所以在这种情况下,代码没有进入paint方法。任何关于使用Canvas/Thread的好资源都会很好,或者任何关于以下applet的建议都会非常有用。谢谢大家! import java.awt.*; import

我有一个小程序,正如我现在写的,在按下“Run”按钮后,它应该在顶部(代码中的
drawingpanel
)绘制并弹起一个球。在线查看其他示例,并使用未使用Canvas的不同程序中的代码,我无法找出我的Ball对象未显示的原因。我已经测试了程序的流程,并且所有的方法都按它们应该的方式被调用,所以在这种情况下,代码没有进入
paint
方法。任何关于使用Canvas/Thread的好资源都会很好,或者任何关于以下applet的建议都会非常有用。谢谢大家!

import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Bounce2 extends Applet implements ActionListener, AdjustmentListener, Runnable
{
    private final static long serialVersionUID = 1L;

    //runtime variables
    boolean running = false;
    boolean currentlyCircle = true;
    boolean showtails = false;
    boolean kill = false;

    //buttons
    Button runbutton = new Button("Run"); 
    Button pausebutton = new Button("Pause");
    Button quitbutton = new Button("Quit");

    //text
    Label speedlabel = new Label("Speed");
    Label sizelabel = new Label("Size");

    //scrollbars
    private final int barHeight = 20;
    private final int SLIDER_WIDTH = 10;
    private final int MAXSPEED = 110;
    private final int MINSPEED = 0;
    private final int MAX_SIZE = 110;
    private final int MIN_SIZE = 10;
    Scrollbar speedbar = new Scrollbar(Scrollbar.HORIZONTAL, MAXSPEED/2, SLIDER_WIDTH, MINSPEED, MAXSPEED);
    Scrollbar sizebar = new Scrollbar(Scrollbar.HORIZONTAL, MAX_SIZE/2, SLIDER_WIDTH, MIN_SIZE, MAX_SIZE);

    //drawn objs
    Ball ball;
    Image buffer;
    int size = 50;  
    private Graphics obj;
    Point currentlocation = new Point(100,100);
    Point previouslocation;
    Point nextlocation;

    Rectangle circle;
    Rectangle screen;
    private Thread ballThread;

    //boundaries
    int bound_x;
    int bound_y;

    //directions
    int dx = 1; //1 = left, -1 = right
    int dy = 1; //1 = up, -1 = down

    //speed
    int speed = speedbar.getValue();
    int delay;

    //initialize the applet and draw everything
    public void init()
    {
        double colWeight[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
        double rowWeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
        int colWidth[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15 cols
        int rowHeight[] = {1,1,1,1,1,1,1,1,1,1}; //10 rows
        GridBagConstraints c = new GridBagConstraints();
        GridBagLayout gbl = new GridBagLayout();
        gbl.rowHeights = rowHeight;
        gbl.rowWeights = rowWeight;
        gbl.columnWeights = colWeight;
        gbl.columnWidths = colWidth;
        c.anchor = GridBagConstraints.CENTER;

        setBounds(0,0,480,640);
        setLayout(new BorderLayout());
        Panel controlpanel = new Panel();
        controlpanel.setLayout(gbl);
        controlpanel.setSize(640,80);

        Panel drawingpanel = new Panel(null);
        drawingpanel.setSize(640,400);
        ball = new Ball();
        drawingpanel.add("Center", ball);
        Rectangle circle = new Rectangle(size, size);
        Rectangle screen = new Rectangle(0,0,640,400);
        drawingpanel.setVisible(true);

        //speed scrollbar
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.gridx = 1;
        c.gridy = 7;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.speedbar,c);

        //run button
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 2;
        c.gridheight = 1;
        c.gridx = 5;
        c.gridy = 7;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.runbutton,c);

        //pause button
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 2;
        c.gridheight = 1;
        c.gridx = 8;
        c.gridy = 7;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.pausebutton,c);

        //size scrollbar
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.gridx = 11;
        c.gridy = 7;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.sizebar,c);

        //speed text label
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.gridx = 1;
        c.gridy = 8;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.speedlabel,c);

        //size text label
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.gridx = 11;
        c.gridy = 8;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.sizelabel,c);

        //quit button
        c.weightx = 1;
        c.weighty = 1;
        c.gridwidth = 3;
        c.gridheight = 1;
        c.gridx = 6;
        c.gridy = 9;
        c.fill= GridBagConstraints.HORIZONTAL;
        gbl.setConstraints(this.quitbutton,c);

        //add to the screen
        controlpanel.add(this.speedbar);
        controlpanel.add(this.runbutton);
        controlpanel.add(this.pausebutton);
        controlpanel.add(this.sizebar);
        controlpanel.add(this.speedlabel);
        controlpanel.add(this.sizelabel);
        controlpanel.add(this.quitbutton);

        //add listners
        speedbar.addAdjustmentListener(this);
        runbutton.addActionListener(this);
        pausebutton.addActionListener(this);
        sizebar.addAdjustmentListener(this);
        quitbutton.addActionListener(this);

        //add the panels
        add("South", controlpanel);
        add("Center", drawingpanel);

        //drawing paramaters, draw the first object
        System.err.println(obj);
        obj = drawingpanel.getGraphics();
        nextlocation = new Point(currentlocation.x+dx, currentlocation.y+dy);

        setVisible(true);
        validate();
    }

    public void start()
    {
        if (ballThread == null)
        {
            ballThread = new Thread(this);
            ballThread.start();
            repaint();
        }
    }

        public void run()
{
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    while (!kill)
    {
        if (running)
        {
            ball.move();
            repaint();
        }
        try
        {
            Thread.sleep(delay);
        }
        catch(InterruptedException e){System.err.println("Interrupted.");}
    }
    stop();
}

public void update(Graphics g)
{   
    Graphics buffer;
    Image offscreen = null;

    offscreen = createImage(bound_x, bound_y);
    buffer = offscreen.getGraphics();
    buffer.setColor(getBackground());
    buffer.fillRect(0,0,bound_x, bound_y);
    //update

    previouslocation = new Point(currentlocation);
    currentlocation = nextlocation;

    //draw
    buffer.setColor(Color.black);
    buffer.drawOval(nextlocation.x, nextlocation.y, size, size);
    buffer.fillOval(nextlocation.x, nextlocation.y, size, size);

    //draw rectangles out of vector     
    g.drawImage(offscreen, 0,0, null);
    paint(buffer);
}   

//class to handle animations
class Ball extends Canvas 
{
    public void move()
    {
        nextlocation = new Point(currentlocation.x+dx, currentlocation.y+dy);
        //if it will hit the right or left, flip the x direction and set it 
        if (nextlocation.x+size >= bound_x || nextlocation.x <= 0)
        { dx *= -1; }
        nextlocation.x += dx;
        //if it will hit the top or bottom, flip the y direction and set it
        if (nextlocation.y+size >= bound_y + 100 || nextlocation.y <= 0)
        { dy *= -1; }
        nextlocation.y += dy;
        setBounds(dx,dy,size,size);
        System.out.println(dx + "," + dy);
    }   

    public void paint(Graphics g)
    {
        super.paint(g);
        g.setColor(Color.black);
        g.drawOval(0, 0, size, size);
    }
}

    public void actionPerformed(ActionEvent e)
    {
        Object source = e.getSource();
        if (source == this.runbutton)
        {
            running = true;
        }
        else if (source == this.pausebutton)
        {
            running = false;
        }
        else if (source == this.quitbutton)
        {
            //kill processes
            kill = true;
            //remove listeners
            stop();
        }
    }

    public void adjustmentValueChanged(AdjustmentEvent e)
    {
        Object source = e.getSource();
        //set the new size. 
        if (source == sizebar)
        {
            //check for clipping
            int newsize = sizebar.getValue();

            // x
            if (currentlocation.x+newsize >= bound_x)
            { 
                newsize = bound_x - currentlocation.x - 1;
                sizebar.setValue(newsize);
            }

            // y
            if (currentlocation.y+newsize >= bound_y + 100)
            {
                newsize = bound_y+100 - currentlocation.y - 1;
                sizebar.setValue(newsize);
            }
            size = newsize;
        }
        if (source == speedbar)
        {
            speed = speedbar.getValue();
            delay = MAXSPEED - speedbar.getValue();
        }
    }

    public void stop()
    {
        this.speedbar.removeAdjustmentListener(this);
        this.runbutton.removeActionListener(this);
        this.pausebutton.removeActionListener(this);
        this.sizebar.removeAdjustmentListener(this);
        this.quitbutton.removeActionListener(this);
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
    }
}
import java.awt.*;
导入java.applet.*;
导入java.awt.event.*;
公共类Bounce2扩展小程序实现ActionListener、AdjustmentListener、Runnable
{
私有最终静态长serialVersionUID=1L;
//运行时变量
布尔运行=假;
布尔currentlycirle=true;
布尔showtails=false;
布尔kill=false;
//钮扣
按钮运行按钮=新按钮(“运行”);
按钮暂停按钮=新按钮(“暂停”);
按钮退出按钮=新按钮(“退出”);
//正文
标签速度标签=新标签(“速度”);
标签尺寸标签=新标签(“尺寸”);
//滚动条
私人最终内部酒吧高度=20;
专用最终整数滑块_宽度=10;
专用最终int MAXSPEED=110;
私人最终整数分钟速度=0;
私人最终整数最大值=110;
私人最终整数最小值=10;
Scrollbar speedbar=新的滚动条(Scrollbar.HORIZONTAL,MAXSPEED/2,SLIDER\u WIDTH,MINSPEED,MAXSPEED);
Scrollbar sizebar=新的滚动条(Scrollbar.HORIZONTAL,最大大小/2,滑块宽度,最小大小,最大大小);
//绘制对象
球;
图像缓冲区;
int size=50;
专用图形obj;
点电流位置=新点(100100);
点位置;
点位;
矩形圆;
矩形屏幕;
专用螺纹球螺纹;
//界限
int-bound_x;
内界y;
//方向
int dx=1;//1=左,-1=右
int dy=1;//1=向上,-1=向下
//速度
int speed=speedbar.getValue();
整数延迟;
//初始化小程序并绘制所有内容
公共void init()
{
双colWeight[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15个cols
双行重[]={1,1,1,1,1,1,1,1,1};//10行
int colWidth[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1};//15列
int rowHeight[]={1,1,1,1,1,1,1,1};//10行
GridBagConstraints c=新的GridBagConstraints();
GridBagLayout gbl=新的GridBagLayout();
gbl.rowHeights=行高;
gbl.rowWeights=rowWeight;
gbl.columnWeights=colWeight;
gbl.columnWidths=colWidth;
c、 锚点=GridBagConstraints.CENTER;
立根(0,0480640);
setLayout(新的BorderLayout());
面板控制面板=新面板();
控制面板设置布局(gbl);
控制面板。设置尺寸(640,80);
面板绘制面板=新面板(空);
drawingpanel.setSize(640400);
球=新球();
drawingpanel.添加(“中心”,球);
矩形圆=新矩形(大小、大小);
矩形屏幕=新矩形(0,0640400);
drawingpanel.setVisible(真);
//速度滚动条
c、 权重x=1;
c、 权重=1;
c、 网格宽度=3;
c、 网格高度=1;
c、 gridx=1;
c、 gridy=7;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(此.speedbar,c);
//运行按钮
c、 权重x=1;
c、 权重=1;
c、 网格宽度=2;
c、 网格高度=1;
c、 gridx=5;
c、 gridy=7;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.runbutton,c);
//暂停按钮
c、 权重x=1;
c、 权重=1;
c、 网格宽度=2;
c、 网格高度=1;
c、 gridx=8;
c、 gridy=7;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.pausebutton,c);
//大小滚动条
c、 权重x=1;
c、 权重=1;
c、 网格宽度=3;
c、 网格高度=1;
c、 gridx=11;
c、 gridy=7;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.sizebar,c);
//快速文本标签
c、 权重x=1;
c、 权重=1;
c、 网格宽度=3;
c、 网格高度=1;
c、 gridx=1;
c、 gridy=8;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(此.speedlabel,c);
//大小文本标签
c、 权重x=1;
c、 权重=1;
c、 网格宽度=3;
c、 网格高度=1;
c、 gridx=11;
c、 gridy=8;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(this.sizelabel,c);
//退出按钮
c、 权重x=1;
c、 权重=1;
c、 网格宽度=3;
c、 网格高度=1;
c、 gridx=6;
c、 gridy=9;
c、 填充=GridBagConstraints.HORIZONTAL;
gbl.setConstraints(此.quitbutton,c);
//添加到屏幕上
controlpanel.add(this.speedbar);
controlpanel.add(this.runbutton);
controlpanel.add(this.pausebutton);
controlpanel.add(this.sizebar);
controlpanel.add(此.speedlabel);
controlpanel.add(this.sizelabel);
controlpanel.add(此.quit按钮);
//添加列表器
speedbar.addAdjustmentListener(此);
runbutton.addActionListener(这个);
pausebutton.addActionListener(这个);
sizebar.addAdjustmentListener(此);
quitbutton.addActionListener(此);
//添加面板
添加(“南”,控制面板);
添加(“中心”,绘图面板);
//绘制参数,绘制第一个对象
系统错误打印项次(obj);
obj=drawingpanel.getGraphics();
下一个位置
private Graphics obj;
.
.
.
obj = drawingpanel.getGraphics();
public void paint(Graphics obj)
{
    // I can see you're trying to double buffer the graphics, but I would have a
    // buffer already set up...
    buffer = createImage(640,400);
    // You should NEVER dispose of Graphics context you didn't created...
    if (obj != null)
        obj.dispose();

    // Now we're really stuffed.  You've just overridden the screen graphics context
    obj = buffer.getGraphics();
    obj.setColor(getBackground());
    //update
    previouslocation = new Point(currentlocation);
    currentlocation = nextlocation;

    //draw
    obj.fillRect(currentlocation.x, currentlocation.y, size, size);
    obj.setColor(Color.black);
    obj.drawOval(nextlocation.x, nextlocation.y, size, size);
    obj.fillOval(nextlocation.x, nextlocation.y, size, size);
    /*
     *draw rectangles out of vector
     */
    // Now you drawing the buffer onto itself...???
    obj.drawImage(buffer, 0,0, null);
}   
public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.black);
    g.drawOval(0, 0, size, size);
}
public void move() {
    // You've previous move code
    setBounds(dx, dy, size, size);
}