史上最扯Java图形绘制(J2SE)之一JAVA动画效果
很多主一听说Java界面,一水的头大外带血压高,兄弟我倒觉得没什么必要。
其实Java这东西吧,就简便性和其初衷而言,真他妈就在GUI 这地界是有优势的,单就其2D界面开发的易用性来说,借用《地下交通站》里黑瞎子——黑藤太君骂贾队长的话来说“全中国,不,全东亚,还能找出你这样空前绝后的脸吗?”。所以它不普及,无外两点,1.搞Java的多半不指着这东西混饭吃,比如兄弟目前还被逼用SSH(Struts+Spring+Hibernate)混饭吃。2.效率低,为了改变本来AWT的可移植性而开发Swing,结果搞得层次过多,效率低下,反倒是走回AWT老路的SWT比较吃香,害得SUN从1.6开始又给AWT扩充新类,谁让Swing玩底层要靠AWT的……
兄弟不才,大家也碰上个愣主,我就准备以闲扯的方式鼓捣鼓捣这爹不亲娘不爱的玩意。
既然提到UI,那怎么也得有图像吧?图像,再次也得弄张图来操作吧?所以咱爷们就先从Java图像的加载入手,操练起来~
package org.test;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
/**
* <p>
* Title: 史上最扯Java图形绘制(J2SE)教程之一,图像变换。
* </p>
* <p>
* Description:图像变换
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
*
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class SimpleAnime extends Frame {
/**
* 这个例子我用AWT来讲解,实际上,我们都知道使用Swing时,对图 像绘制上有很多的优化,但是在AWT中,这些都是要我们手动来做得,
* 所以入门我还是以AWT开始。(其实大家都知道,组件名加个J就变 Swing了……几乎不用改别的。)
*/
private static final long serialVersionUID = 1L;
// 用于存储图片
Image act;
// 俗称的帆布啦,做手机开发的话很常见
Canvas canvas = new Canvas() {
private static final long serialVersionUID = 1L;
/**
* 绘制图像,直接调用update方法(顺便说一下,若以paint调用update,
* 再用update调用paint,会出现很好玩的事。^^)
*/
public void paint(Graphics g) {
update(g);
}
/**
* 此方法仅在在发生变更时绘制图形
*/
public void update(Graphics g) {
// 参数分别为加载图像,所在Graphics上的left,所在top,图像width,图像height,目标对象
g.drawImage(act, getWidth() / 2 - act.getWidth(null) / 2,
getHeight() / 2 - act.getHeight(null) / 2, act
.getWidth(null), act.getHeight(null), this);
}
};
/**
* 简单动画的构造
*
*/
public SimpleAnime() {
setTitle("图像变换");
setSize(400, 400);
// 设定背景为黑色
setBackground(Color.BLACK);
// 直接以class路径读取图片资源
URL imageUrl = getClass().getResource("/image/act.jpg");
// 获取image图像实体
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
// 加载帆布作为背景
add(canvas);
class AnimeMouseListener extends MouseAdapter {
// 鼠标进入变更
public void mouseEntered(MouseEvent e) {
// 顺便说一下,水平反转图的效果,是可以用代码做到的,后面讲解。
URL imageUrl = getClass().getResource("/image/act0.jpg");
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
canvas.repaint();
}
// 鼠标离开变更
public void mouseExited(MouseEvent e) {
URL imageUrl = getClass().getResource("/image/act.jpg");
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
canvas.repaint();
}
}
//在帆布上添加鼠标监听
canvas.addMouseListener(new AnimeMouseListener());
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
// 实例化本类
SimpleAnime sa = new SimpleAnime();
// 显示窗体
sa.setVisible(true);
}
}
(鼠标移入)
(鼠标在外)
这他妈才几个字母,抛除我那些狗屁都未必同通得了的注释,不到俩半字,这日本的花姑娘(正经说一句,这是月姬的同人图……)就给小爷跳上舞了,那位缺德主要加个死循环的线程进去,嘿,不赶上停电死机的,还就真格停不下来了。
闲得无聊,丧心病狂的我给加上个线程。
package org.test;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;
/**
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class SimpleAnime0 extends Frame {
private static final long serialVersionUID = 1L;
Image act1;
Image act2;
// 是否令图像移动
boolean actMoving = false;
// 初始图像编号
int actPhase = 1;
Canvas c = new Canvas() {
private static final long serialVersionUID = 1L;
/**
* 绘制图像,直接调用update方法(顺便说一下,若以paint调用update, 再用update调用paint,会出现很好玩的事。^^)
*/
public void paint(Graphics g) {
update(g);
}
/**
* 此方法仅在在发生变更时绘制图形
*/
public void update(Graphics g) {
if (actMoving) {
if (actPhase == 1) {
g
.drawImage(act1, getWidth() / 2
- act1.getWidth(null) / 2, getHeight() / 2
- act1.getHeight(null) / 2, act1
.getWidth(null), act1.getHeight(null), this);
} else {
g
.drawImage(act2, getWidth() / 2
- act2.getWidth(null) / 2, getHeight() / 2
- act2.getHeight(null) / 2, act2
.getWidth(null), act2.getHeight(null), this);
}
}
}
};
/**
* 简单动画的构造
*
*/
public SimpleAnime0(boolean isRun) {
actMoving = isRun;
setTitle("图像变换");
setSize(400, 400);
// 设定背景为黑色
setBackground(Color.BLACK);
//这只是一个图像加载的演示,我们完全可以定义一个Image数组,然后动态加载
//做成动画播放。
URL imageUrl = getClass().getResource("/image/act.jpg");
act1 = Toolkit.getDefaultToolkit().createImage(imageUrl);
imageUrl = getClass().getResource("/image/act0.jpg");
act2 = Toolkit.getDefaultToolkit().createImage(imageUrl);
add(c);
/**
* 顺便介绍一下,在Swing下有Timer类,可以设定运算周期循环触发事件。 大体写法如下,不过很多人还是愿意用线程……
*
* class TimerListener implements ActionListener{ public void
* actionPerformed(ActionEvent e){ if(!actMoving) return; actPhase =
* (actPhase == 1) ? 2 : 1; canvas.repaint(); } } javax.swing.Timer t =
* new javax.swing.Timer(200,new TimerListener()); t.start();
*/
Thread t = new Thread(new Timer());
t.start();
}
/**
* 事件循环处理线程
*
* @author chenpeng
*/
class Timer implements Runnable {
public void run() {
while (true) {
if (!actMoving)
return;
actPhase = (actPhase == 1) ? 2 : 1;
c.repaint();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
// 实例化本类,并触发循环事件
SimpleAnime0 sa = new SimpleAnime0(true);
// 显示窗体
sa.setVisible(true);
}
}
其实Java这东西吧,就简便性和其初衷而言,真他妈就在GUI 这地界是有优势的,单就其2D界面开发的易用性来说,借用《地下交通站》里黑瞎子——黑藤太君骂贾队长的话来说“全中国,不,全东亚,还能找出你这样空前绝后的脸吗?”。所以它不普及,无外两点,1.搞Java的多半不指着这东西混饭吃,比如兄弟目前还被逼用SSH(Struts+Spring+Hibernate)混饭吃。2.效率低,为了改变本来AWT的可移植性而开发Swing,结果搞得层次过多,效率低下,反倒是走回AWT老路的SWT比较吃香,害得SUN从1.6开始又给AWT扩充新类,谁让Swing玩底层要靠AWT的……
兄弟不才,大家也碰上个愣主,我就准备以闲扯的方式鼓捣鼓捣这爹不亲娘不爱的玩意。
既然提到UI,那怎么也得有图像吧?图像,再次也得弄张图来操作吧?所以咱爷们就先从Java图像的加载入手,操练起来~
package org.test;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
/**
* <p>
* Title: 史上最扯Java图形绘制(J2SE)教程之一,图像变换。
* </p>
* <p>
* Description:图像变换
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
*
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class SimpleAnime extends Frame {
/**
* 这个例子我用AWT来讲解,实际上,我们都知道使用Swing时,对图 像绘制上有很多的优化,但是在AWT中,这些都是要我们手动来做得,
* 所以入门我还是以AWT开始。(其实大家都知道,组件名加个J就变 Swing了……几乎不用改别的。)
*/
private static final long serialVersionUID = 1L;
// 用于存储图片
Image act;
// 俗称的帆布啦,做手机开发的话很常见
Canvas canvas = new Canvas() {
private static final long serialVersionUID = 1L;
/**
* 绘制图像,直接调用update方法(顺便说一下,若以paint调用update,
* 再用update调用paint,会出现很好玩的事。^^)
*/
public void paint(Graphics g) {
update(g);
}
/**
* 此方法仅在在发生变更时绘制图形
*/
public void update(Graphics g) {
// 参数分别为加载图像,所在Graphics上的left,所在top,图像width,图像height,目标对象
g.drawImage(act, getWidth() / 2 - act.getWidth(null) / 2,
getHeight() / 2 - act.getHeight(null) / 2, act
.getWidth(null), act.getHeight(null), this);
}
};
/**
* 简单动画的构造
*
*/
public SimpleAnime() {
setTitle("图像变换");
setSize(400, 400);
// 设定背景为黑色
setBackground(Color.BLACK);
// 直接以class路径读取图片资源
URL imageUrl = getClass().getResource("/image/act.jpg");
// 获取image图像实体
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
// 加载帆布作为背景
add(canvas);
class AnimeMouseListener extends MouseAdapter {
// 鼠标进入变更
public void mouseEntered(MouseEvent e) {
// 顺便说一下,水平反转图的效果,是可以用代码做到的,后面讲解。
URL imageUrl = getClass().getResource("/image/act0.jpg");
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
canvas.repaint();
}
// 鼠标离开变更
public void mouseExited(MouseEvent e) {
URL imageUrl = getClass().getResource("/image/act.jpg");
act = Toolkit.getDefaultToolkit().createImage(imageUrl);
canvas.repaint();
}
}
//在帆布上添加鼠标监听
canvas.addMouseListener(new AnimeMouseListener());
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
// 实例化本类
SimpleAnime sa = new SimpleAnime();
// 显示窗体
sa.setVisible(true);
}
}
(鼠标移入)
(鼠标在外)
这他妈才几个字母,抛除我那些狗屁都未必同通得了的注释,不到俩半字,这日本的花姑娘(正经说一句,这是月姬的同人图……)就给小爷跳上舞了,那位缺德主要加个死循环的线程进去,嘿,不赶上停电死机的,还就真格停不下来了。
闲得无聊,丧心病狂的我给加上个线程。
package org.test;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;
/**
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class SimpleAnime0 extends Frame {
private static final long serialVersionUID = 1L;
Image act1;
Image act2;
// 是否令图像移动
boolean actMoving = false;
// 初始图像编号
int actPhase = 1;
Canvas c = new Canvas() {
private static final long serialVersionUID = 1L;
/**
* 绘制图像,直接调用update方法(顺便说一下,若以paint调用update, 再用update调用paint,会出现很好玩的事。^^)
*/
public void paint(Graphics g) {
update(g);
}
/**
* 此方法仅在在发生变更时绘制图形
*/
public void update(Graphics g) {
if (actMoving) {
if (actPhase == 1) {
g
.drawImage(act1, getWidth() / 2
- act1.getWidth(null) / 2, getHeight() / 2
- act1.getHeight(null) / 2, act1
.getWidth(null), act1.getHeight(null), this);
} else {
g
.drawImage(act2, getWidth() / 2
- act2.getWidth(null) / 2, getHeight() / 2
- act2.getHeight(null) / 2, act2
.getWidth(null), act2.getHeight(null), this);
}
}
}
};
/**
* 简单动画的构造
*
*/
public SimpleAnime0(boolean isRun) {
actMoving = isRun;
setTitle("图像变换");
setSize(400, 400);
// 设定背景为黑色
setBackground(Color.BLACK);
//这只是一个图像加载的演示,我们完全可以定义一个Image数组,然后动态加载
//做成动画播放。
URL imageUrl = getClass().getResource("/image/act.jpg");
act1 = Toolkit.getDefaultToolkit().createImage(imageUrl);
imageUrl = getClass().getResource("/image/act0.jpg");
act2 = Toolkit.getDefaultToolkit().createImage(imageUrl);
add(c);
/**
* 顺便介绍一下,在Swing下有Timer类,可以设定运算周期循环触发事件。 大体写法如下,不过很多人还是愿意用线程……
*
* class TimerListener implements ActionListener{ public void
* actionPerformed(ActionEvent e){ if(!actMoving) return; actPhase =
* (actPhase == 1) ? 2 : 1; canvas.repaint(); } } javax.swing.Timer t =
* new javax.swing.Timer(200,new TimerListener()); t.start();
*/
Thread t = new Thread(new Timer());
t.start();
}
/**
* 事件循环处理线程
*
* @author chenpeng
*/
class Timer implements Runnable {
public void run() {
while (true) {
if (!actMoving)
return;
actPhase = (actPhase == 1) ? 2 : 1;
c.repaint();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
// 实例化本类,并触发循环事件
SimpleAnime0 sa = new SimpleAnime0(true);
// 显示窗体
sa.setVisible(true);
}
}
posted on 2007-09-14 22:08 cping 阅读(...) 评论(...) 编辑 收藏