Java 把画图和投屏分开 不用双缓冲解决屏幕闪烁问题

本文介绍了一个Java项目,通过将画图与投屏功能分离,实现了更高效的资源利用。MyCanvas类负责投屏,接收外部已绘制的图片进行显示,而画图过程则在独立模块中完成。文章详细解释了MyCanvas类的实现原理,包括如何使用getImageAndPrintIt方法更新屏幕显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

投屏模块——MyCanvas类

运用里面的getImageAndPrintIt(BufferedImage bufferedImage)方法实现投屏,bufferedImage是提前画好的图片。

也就是说,只让Canvas实现投屏功能,把画图功能分离出去。

package madokast;

import java.awt.*;
import java.awt.image.BufferedImage;

public class MyCanvas extends Canvas {
    //用于接收外来图片(已经在外面画好了)
    private BufferedImage ImageToBePaint;

    //对外的接口,用于得到外界的图片,在此中调用repaint()方法
    public void getImageAndPrintIt(BufferedImage bufferedImage)
    {
        //拿到要画的图片
        this.ImageToBePaint = bufferedImage;
        //画图顺序:repaint()->update()->paint()
        super.repaint();
    }

    @Override
    //重写update方法,该方法原本用于清屏+调用paint()

    //这个方法中的Graphics g的和paint(Graphics g)方法中的g,都是直接指向屏幕的画笔
    //原本update()方法带有清屏功能,即g.clearRect(),用背景色重置屏幕
    //在我的MyCanvas类中,这东西没必要,直接用下一张图片覆盖上一张即可,没必要清屏
    //以前需要清屏是因为以前的画图写在了重写的paint()方法中,这个方法里我们只管画图,不管清屏

    //重写update(),覆盖【清屏+调用paint()】的功能(等于paint不再被调用了————实际上还以被调用了一次...大概是初始化的时候)
    //直接用这里的 g 绘制从getImageAndPrintIt(BufferedImage bufferedImage)得到的图片
    public void update(Graphics g) {g.drawImage(ImageToBePaint,0,0,null); }

    //paint(Graphics g)还是被调用了一次...不知道为什么
    //@Override
    //public void paint(Graphics g) {
    //    super.paint(g);
    //    int x=1/0;
    //}

    @Override
    @Deprecated
    //最后。不要用repaint(),应该使用getImageAndPrintIt(BufferedImage bufferedImage)
    public void repaint() { super.repaint(); }
}

画图模块——一段main函数的小测试

package madokast;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class CanvasRelearnMain {
    private static int x=0;

    public static void main(String[] args) {
        final int ImageWidth = 800;
        final int ImageHeight = 600;

        Frame frame = new Frame("测试");
        MyCanvas myCanvas = new MyCanvas();
        myCanvas.setBounds(0,0,ImageWidth,ImageHeight);
        frame.add(myCanvas,BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);


        BufferedImage bufferedImage = new BufferedImage(ImageWidth,ImageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics pen = bufferedImage.createGraphics();
        Color blue = new Color(0x0000FF);
        Color red = new Color(0xFF0000);

        Timer timer = new Timer(10,t->{
            //清屏
            pen.setColor(blue);
            pen.fillRect(0,0,ImageWidth,ImageHeight);

            //画图
            pen.setColor(red);
            pen.fillRect(x++,200,30,30);

            //投屏
            myCanvas.getImageAndPrintIt(bufferedImage);
        });

        timer.start();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值