您的位置:首页 > 编程语言 > Java开发

Java 桌面精灵关键代码

2017-04-04 14:35 239 查看
参考:http://blog.csdn.net/kai_wei_zhang/article/details/8120382 http://www.cnblogs.com/S-E-P/archive/2010/01/27/2045076.html 一、闪烁的原因

动画就是一帧一帧的切换图片。

每次切换都会先用背景色覆盖组件再重绘图像,如此就造成了两帧之间的空白画面。从而导致了闪烁。

注意,这个repaint()函数是从Frame类继承而来的。它先调用update(Graphics
g)函数,update(Graphics g)再调用paint(Graphics g)函数

 二、解决方案 

背景色覆盖、绘图都在内存中进行,最后一次性画到控件上。

也就是我们所说的双缓冲技术。

Frame (收集自网络未实验)
Image ImageBuffer = null;
Graphics GraImage = null;

public void update(Graphics g){     //覆盖update方法,截取默认的调用过程
ImageBuffer = createImage(this.getWidth(), this.getHeight());   //创建图形缓冲区
GraImage = ImageBuffer.getGraphics();       //获取图形缓冲区的图形上下文
paint(GraImage);        //用paint方法中编写的绘图过程对图形缓冲区绘图
GraImage.dispose();     //释放图形上下文资源
g.drawImage(ImageBuffer, 0, 0, this);   //将图形缓冲区绘制到屏幕上
}

public void paint(Graphics g){      //在paint方法中实现绘图过程
g.drawLine(0, 0, 100, 100);
}

JFrame 

在这里说一下,上面所说的不知为啥,我的Update总是 不能调用,怀疑JDK版本更新后,update调用被改变了。

参考自网上

private Image iBuffer;
public void paint(Graphics scr) {
if (iBuffer == null)
iBuffer = createImage(this.getSize().width, this.getSize().height);

Graphics gBuffer = iBuffer.getGraphics();

gBuffer.setColor(getBackground());
gBuffer.fillRect(0, 0, this.getSize().width, this.getSize().height);
gBuffer.setColor(Color.RED);
gBuffer.fillOval(90, ypos, 80, 80);
scr.drawImage(iBuffer, 0, 0, this);
}

例子:实现透明窗体动画效果(好像Swing自带双缓冲技术)。

但是如果在动画上方添加动态String,会失败。

public class Test5 extends JFrame {
private int nowFrame;   //当前帧
private Timer timer;	//定时器每隔几秒换张图
private Image iBuffer = null;  //在内存中创建一个图对象
private Image[] img;
public Test5() {
Toolkit toolkit=getToolkit();
for(int i=0;i<img.length;i++){
img[i]=toolkit.getImage("tupian"  + i + ".gif");
}
this.setAlwaysOnTop(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
this.setIconImage(SoftIcons.ICON_IMG);

// 设置窗体透明
this.setUndecorated(true);
this.setBackground(new Color(0, 0, 0,0));// alpha分量为零

//每隔0.1秒重绘一次窗口
this.timer = new Timer(100, null);
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
timer.start();
}

@Override
public void paint(Graphics g) {
super.paint(g);
gBuffer.drawImage(img[nowFrame],30,100, null);
if (nowFrame == icons.DANCE_IMG.length - 1) {
nowFrame = 1;
}
}
public static void main(String[] args) {
new Test5();
}
}


改进之后,可以在动画上方添加动态String,窗口透明

public class Test extends JFrame {
private Timer timer;
private myPanel panel;

public Test() {
panel = new myPanel();

// 设置窗体透明
this.setUndecorated(true);
this.setBackground(new Color(0, 0, 0,0));// alpha分量为零

// 设置窗体永远在前
this.setAlwaysOnTop(true);
this.setContentPane(panel);
this.setSize(300, 400);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setIconImage(SoftIcons.ICON_IMG);
this.setVisible(true);

this.timer = new Timer(100, null);
timer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
panel.repaint();
}
});
timer.start();
}
public static void main(String[] args) {
new Test();
}

class myPanel extends JPanel{
private int nowFrame;  //当前帧
private int behavior;
private Image[] img;
private String[] word;
public myPanel() {
this.setOpaque(false);
}
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
g.drawString(word[behavior++], 20, 20);
g.drawImage(img[nowFrame++],0,50, null);
if (nowFrame == img.length - 1)
nowFrame = 0;
if (behavior == word.length - 1)
behavior = 0;
}
}
}


因为大部分绘图过程是在内存中进行,所以有效地消除了闪烁。这应用了“以空间换取时间”和“功能分块”的思想
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: