我需要帮助了解如何在java applet中编写双缓冲代码

时间:2013-01-05 01:04:03

标签: java applet doublebuffered

我理解它背后的逻辑,但不知道如何将其转换为代码。有人可以告诉我这个我写的例子吗?

所有小程序都是中心矩形自行向上,向下,向右和向左移动。我想用双缓冲区摆脱恼人的闪烁,但我不知道会发生什么变化/添加。

import java.applet.*;

import java.awt.*;

public class Broadway extends Applet implements Runnable {

Thread animation;

int locx,locy; // location of rectangle
int width, height; // dimensions of rectangle

// direction of motion
static final byte UP = 0; 
static final byte DOWN = 1;
static final byte LEFT = 2;
static final byte RIGHT = 3;

byte state; // state the rect is in

// length of pausing interval in ms
static final int REFRESH_RATE = 100;


public void init() {

    setBackground(Color.black);

    locx = 80; // parameters of center rect
    locy = 100;
    width = 110;
    height = 90;
    state = UP;
}

public void start() {

    animation = new Thread(this);

    if (animation != null) {
    animation.start();
    }
}

public void paint(Graphics g) {

    g.setColor(Color.yellow);
    g.fillRect(0,0,90,90);
    g.fillRect(250,0,40,190);
    g.fillRect(80,110,100,20);

    g.setColor(Color.blue);
    g.fillRect(80,200,220,90);
    g.fillRect(100,10,90,80);

    g.setColor(Color.lightGray);
    g.fillRect(locx,locy,width,height);

    g.setColor(Color.red);
    g.fillRect(200,0,45,45);
    g.fillRect(0,100,70,200);

    g.setColor(Color.magenta);
    g.fillRect(200,55,60,135);
}

//update the center rectangle
void updateRectangle() {

    switch (state) {
    case DOWN:
        locy += 2;
        if (locy >= 110) {
        state = UP;
        }
        break;
    case UP:
        locy -= 2;
        if (locy <= 90) {
        state = RIGHT;
        }
        break;
    case RIGHT:
        locx += 2;
        if (locx >= 90) {
        state = LEFT;
        }
        break;
    case LEFT:
        locx -= 2;
        if (locx <= 70) {
        state = DOWN;
        }
        break;
    }
}

public void run() {

    while (true) {
        repaint();  
        updateRectangle();              
        try {
        Thread.sleep (REFRESH_RATE);    
        } catch (Exception exc) { };
    }
}

public void stop() {

    if (animation != null) {
    animation.stop();
    animation = null;
    }
}
}

2 个答案:

答案 0 :(得分:2)

  1. import java.awt.*;
    将其更改为
    import javax.swing.*;
  2. public class Broadway extends Applet ..
    将其更改为
    public class Broadway extends JApplet ..
  3. 将所有自定义绘画移动到JPanel。覆盖paintComponent(Graphics)而不是paint(Graphics)默认情况下,JPanel是双缓冲的。
  4. 使用Swing Timer进行动画。
  5. 作为一般提示

    编码框架&amp;在考虑使用applet之前,使用Java Web Start从链接启动它。

    更新

    此代码实现了上面的大部分建议,并在选项窗格中显示生成的平滑缓冲动画。它可以显示在JFrameJApplet

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    
    public class Broadway extends JPanel {
    
        int locx, locy; // location of rectangle
        int width, height; // dimensions of rectangle
        Timer timer;
    // direction of motion
        static final byte UP = 0;
        static final byte DOWN = 1;
        static final byte LEFT = 2;
        static final byte RIGHT = 3;
        byte state; // state the rect is in
    // length of pausing interval in ms
        static final int REFRESH_RATE = 100;
    
        public Broadway() {
    
            setBackground(Color.black);
    
            locx = 80; // parameters of center rect
            locy = 100;
            width = 110;
            height = 90;
            state = UP;
    
            ActionListener listener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                    updateRectangle();
                }
            };
    
            timer = new Timer(this.REFRESH_RATE, listener);
        }
    
        public void start() {
            timer.start();
        }
    
        public void stop() {
            timer.stop();
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.yellow);
            g.fillRect(0, 0, 90, 90);
            g.fillRect(250, 0, 40, 190);
            g.fillRect(80, 110, 100, 20);
    
            g.setColor(Color.blue);
            g.fillRect(80, 200, 220, 90);
            g.fillRect(100, 10, 90, 80);
    
            g.setColor(Color.lightGray);
            g.fillRect(locx, locy, width, height);
    
            g.setColor(Color.red);
            g.fillRect(200, 0, 45, 45);
            g.fillRect(0, 100, 70, 200);
    
            g.setColor(Color.magenta);
            g.fillRect(200, 55, 60, 135);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }
    
    //update the center rectangle
        void updateRectangle() {
    
            switch (state) {
                case DOWN:
                    locy += 2;
                    if (locy >= 110) {
                        state = UP;
                    }
                    break;
                case UP:
                    locy -= 2;
                    if (locy <= 90) {
                        state = RIGHT;
                    }
                    break;
                case RIGHT:
                    locx += 2;
                    if (locx >= 90) {
                        state = LEFT;
                    }
                    break;
                case LEFT:
                    locx -= 2;
                    if (locx <= 70) {
                        state = DOWN;
                    }
                    break;
            }
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    Broadway bw  = new Broadway();
    
                    bw.start();
                    JOptionPane.showMessageDialog(null, bw);
                    bw.stop();
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
            SwingUtilities.invokeLater(r);
        }
    }
    

答案 1 :(得分:1)

基本上你替换了paint方法,以便它绘制成与Applet大小相同的Image,然后在Graphics g上绘制该图像。

那里有很多实现。

相关问题: