很多主一听说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:[email]ceponline@yahoo.com.cn[/email] * @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:[email]ceponline@yahoo.com.cn[/email] * @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); }}
本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130224