java - 我需要帮助了解如何在 Java 小程序中编写双缓冲代码

标签 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;
    }
}
}

最佳答案

  1. 导入java.awt.*;
    将其更改为
    导入javax.swing.*;
  2. public class Broadway 扩展 Applet ..
    将其更改为
    public class Broadway 扩展 JApplet ..
  3. 将所有自定义绘画移至 JPanel 中。覆盖 paintComponent(Graphics) 而不是 paint(Graphics)JPanel 默认情况下是双缓冲的。
  4. 使用 Swing Timer 制作动画。

作为一般提示

编写一个框架并使用 Java Web Start 从链接启动它在考虑使用小程序之前。

更新

此代码实现了上面的大部分建议,并在选项 Pane 中显示生成的平滑缓冲动画。它可以显示在 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);
    }
}

关于java - 我需要帮助了解如何在 Java 小程序中编写双缓冲代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14167412/

相关文章:

java - 使用 JSch 打开 SSH channel 时出现 "session is down"错误

java - 小程序。 java.lang.reflect.InvocationTargetException异常

Java:JPanel 在 CardLayout 中无法正确显示

opengl - 如果使用双缓冲,是否需要清除缓冲区?

Java AWT drawImage 竞争条件 - 如何使用同步来避免它

java - 在 Java 中从 rgb 字符串创建颜色

java - 如何使用 Jackson/其他库将 json 响应对象映射到首选格式?

android - 使用表面 View 时闪烁

java - 多边形之间的区别

html - 如何在 Chrome 中的 Java 小程序上显示 <div>