第九章补充 图形图像编程基础 主要内容: 1 、图形操作 2 、图象操作 3 、播放声音 重点: 掌握 Java2D 、 ImageIo 的使用 难点: 了解 JMF
1 、图形操作 进行绘图操作的注意事项: 1 、需要在组件上进行, Component 具有 paint(Graphics g) 、 repaint() 、 update(Graphics g) 方法用于进行绘图操作; 2 、绘图操作涉及的包: java.awt.*—— Image 、 Color 、 Font 、 Graphics 、 Graphics2D 等类 java.awt.geom.*—— 各种 2D 形状 java.awt.font.*——FontRenderContext 等类
1 、图形操作 ——paint() 、 update() 和 repaint() AWT 组件有三个显示相关的方法: paint() 、 update() 和 repaint() 。 显示更新是由一个 AWT 线程来控制完成的,它主要负责 两种显示更新情况:第一是曝光,表示部分显示区域被 遮盖、调整大小、最大最小化等,这种情况随时会发生, 需要系统调用 paint() 方法;第二是程序需要重画显示区域, 添加一些新的显示内容,需要程序调用 repaint() 方法。
AWT thread ( waiting ) update() : clear area call paint() paint() 程序调用 repaint() Exposure : 遮盖、调整大小、 最大最小化等 1 、图形操作 ——paint() 、 update() 和 repaint()
paint( Graphics g ) 方法 应用首次被装载,以及每次窗口放大、缩小、刷新时都要调 用 paint() 方法。 paint() 是由 AWT 线程调用的,而不是由程序 调用,当程序希望调用 paint 方法时,用 repaint() 方法。 paint() 方法的参数是 Graphics 类的对象 g ,该对象不是由 new 产生的,而是由系统或其他方式直接将生好的 Graphics 对 象当作方法的参数,再交给 paint() 方法。 paint() 方法必须被重写以绘制自己所需的内容。 1 、图形操作 ——paint() 、 update() 和 repaint()
1 、图形操作 ——paint() 、 update() 和 repaint() update() 方法 update() 方法用于更新图形。它首先清除背景,然后设置 前景,再调用 paint() 方法完成 Applet 中的具体绘图。为了消除 图像的抖动现象,可以重写 update() 方法。 repaint() 方法 repaint() 方法主要用于重绘图形,它是通过调用 update() 方 法来实现图形重绘的。当组件外形发生变化时,系统自动调 用 repaint() 方法。一般不要重写 repaint() 方法。 AWT 线程要处理组件的绘图工作,并负责其输入事件, 因此必须尽量缩短 paint() 方法和 update() 方法的长度,特别是 在 paint() 方法中,不要执行太消耗时间的操作。
1 、图形操作 ——Graphics 、 Font 和 Color 类的使用 在 paint() 方法中有一个 Graphics 类参数,它是画 图的关键。它支持两种绘制:一是基本的绘图, 包括画点、线、矩形、文字等;二是画图象。在 进行基本画图时,可以设定所需的颜色和字体等, 这需要用到 Font 和 Color 三个类。
1 、图形操作 —— 绘制文本 使用 Graphics 类的 drawString( String str, int x, int y ) 方法; String Font 类:设置字体; FontMetrics 类:获取字体的属性,实现文字换 行、格式化等操作 ; Color 类:设置颜色和透明度;
1 、图形操作 —— 绘制图形 使用 Graphics 类的 drawShape() 方法; 使用 Graphics2D 类的 drawShape() 方法; 使用 Graphics 类的 fillShape() 方法; 使用 Graphics2D 类的 fillShape() 方法; 2D 中所绘图形据 java.awt.geom.* 创建;
1 、图形操作 —— 绘制图形(颜色填充) 使用 Graphics 类的 setXORMode(Color c) 方法进 行颜色异或, setPaintMode() 方法恢复单色; 使用 Paint 接口生成颜色模式: 其中 GradientPaint 、 LinearGradientPaint 类创建 线性渐变颜色, RadialGradientPaint 类创建放射性渐变颜色, TexturePaint 类创建纹理;
1 、图形操作 —— 绘制图形(笔触应用) 使用 Stroke 接口生成颜色模式: BasicStroke 类创建画笔
1 、图形操作 —— 思考 课堂思考: 编写程序绘制图形,笔触、颜色模式任意。 课后思考: 如何利用坐标变换,使图形能够实现缩放、 旋转、平移等? (参考 java.awt.geom.AffineTransform )
2 、图象操作 在 Java 中,其类包 java.awt , java.awt.image 和 java.applet 中都提供了支持图象操作的类和方法。对图象的操作包括 载入、生成、显示和处理。在 Java 中,图象信息是封装在 抽象类 Image 中的,目前 Java 核心类包支持 gif 和 jpeg 两种格 式的图象(但在扩展类包中可以支持更多地图象格式)。 类 Image 是一个抽象类,因此不能直接 new 出一个图象对象, 需要采用特殊的方法载入或生成图象对象。 图象操作在 Applet 和 Application 中都可以进行。
2 、图象操作 —— 载入现有图像文件 在 Applet 中和 Application 中有不同的图象载入方法: 对于 Applet ,由于它主要在网络上运行,因此网络上 图像文件需要用 URL 形式描述: URL picurl= new URL ( “ ” ); 在 Applet 中提供了两个方法来载入图象对象: public Image getImage(URL url)ImageURL public Image getImage(URL url, String name)ImageURLString 例如: Image img1 = getImage(picurl); Image img2 = getImage(getCodeBase(), “ img2.gif ” );
对于Application,必须通过类Toolkit提供的方法来载入图 象: public abstract Image getImage(String filename)ImageString public abstract Image getImage(URL url)ImageURL Toolkit 也是一个抽象类,不能直接生成,有两种方法可以 获得其对象实例:一是通过 Toolkit 类的静态方法 getDefaultToolkit() ,二是用某一个组件对象实例的方法 getToolkit() 。 例如: Image img1 = Toolkit.getDefaultToolkit().getImage(picurl); Image img2 = xxxCom.getToolkit().getImage( “ img2.gif ” ); 2 、图象操作 —— 载入现有图像文件
2 、图象操作 —— 载入现有图像文件 在载入图象时,对于 Applet 或 Application 而言,方法 getImage() 都是立即返回,而由 AWT 生成一个新的线程在 后台异步地完成图象载入任务,使得程序可以执行其他操 作。
显示图象是通过类 Graphics 的方法来实现的: public abstract boolean drawImage(Image img, int x, int y, ImageObserver obs) public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver obs) public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver obs) public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver obs) 在显示图象时,会调用 obs 中的方法 imageUpdate() 以判断 图象的载入情况并做相应的处理。方法 drawImage() 在显示 了已经载入的图象数据后立即返回,因此图象还没有完全载 入前,其显示是不完整的,但可以使用 MediaTracker 类来使 得图象完全载入后再显示。 所有的组件都实现了接口 ImageObserver. 2 、图象操作 —— 显示图像
public class ImageDisplayer extends Applet { Image img; int imgWidth, imgHeight; public void init() { img = getImage(getDocumentBase(), "BALL_ANI.GIF"); MediaTracker tracker = new MediaTracker(this); tracker.addImage( img, 0 ); try{ tracker.waitForID( 0 ); }catch(Exception e){} imgWidth = img.getWidth(this); imgHeight = img.getHeight(this); } public void paint(Graphics g) { //Draw image at its natural size first. g.drawImage(img, 0, 0, this); //Now draw the image scaled. g.drawImage(img, imgWidth, 0, imgWidth+100, imgHeight+100, this); }
2 、图象操作 —— 其他图象处理 在类包 java.awt.image 中,还有很多关于图象生成和图 象处理的类: 图象生成: 接口 ImageProducer ,类 FilteredImageSource 和 MemoryImageSource 等。 图象处理: 类 ImageFilter 及其子类 CropImageFilter 和 RGBImageFilte 等。 这些类的使用,请大家课后自己学习。
3 、播放声音 ——Applet 中 Java 语言提供了播放声音的方法,但目前 Java 核心类包中只支 持 “*.au ,.wav” 格式的声音(扩展类包和其他第三方类包可以支 持更多地声音格式),而且只有在 Applet 中才能播放声音, Application 中是不行的。有两种方法可以在 Applet 中实现播放声 音。 第一种方法是利用 Applet 类提供的方法直接播放声音: public void play(URL url) public void play(URL url, String name) 例: play( getCodeBase(), “boing.au”); 但这两个方法是一次性播放的,不能反复播放。要想反复播 放,就必须使用第二种方法。
3 、播放声音 第二种方法是利用接口 java.applet.AudioClip 和 Applet 类 一起实现声音播放。 接口 AudioClip 中有三个方法: public void play():播放一遍 public void loop() :循环播放 public void stop() :停止播放 AudioClip 是一个接口,因此不能直接 new 出一个声音对 象实例,它必须和 Applet 类一起使用,利用 Applet 类提供的 声音装载方法载入一个声音文件,形成一个声音对象实例: public AudioClip getAudioClip(URL url)AudioClipURL public AudioClip getAudioClip(URL url, String name)AudioClipURLString 装载的声音文件后,就可以利用 AudioClip 的方法来进行 声音操作了。
public class SoundPlay extends Applet { AudioClip sound; public void init() { try { sound = getAudioClip(getDocumentBase(), "spacemusic.au"); }catch(Exception e){} } public void start() { sound.loop(); } public void paint(Graphics g) { g.drawString(“ 正在播放音乐...” + "spacemusic.au", 5, 10); } public void stop() { sound.stop(); } 3 、播放声音 public class SoundPlay1 extends Applet { public void start() { play(getDocumentBase(), "spacemusic.au"); } public void paint(Graphics g) { g.drawString(“ 正在播放音乐...” + getDocumentBase() + ": spacemusic.au", 5, 10); }
3 、播放声音 ——Application 中 第一种方法是利用 sun.audio 包实现声音播放。 import sun.audio.*; import java.io.*; public class Sound { public static voie main(String args[]) { try { FileInputStream fileau=new FileInputStream("sloop.au"); AudioStream as=new AudioStream(fileau); AudioPlayer.player.start(as); } catch (Exception e) {} } }
3 、播放声音 ——Application 中 第二种方法是利用 javax.sound 包及子包实现声音播放。 AudioInputStream AudioFormat AudioSystem 第三种方法是利用 JMF 媒体框架,需要下载和安装 wnload.html
3.1 、所有小应用程序的根源 Java 小应用程序( Java Applet )是使用 Java 语言编写的 一段代码,它能够在浏览器环境中运行。 Applet 与 Application 地主要区别在于它们的执行方式不 同: Application 是使用命令行命令直接运行,从其 main() 方法开始运行的;而 Applet 则是在浏览器中运行的,首先 必须创建一个 HTML 文件,通过编写 HTML 语言代码告诉 浏览器载入何种 Applet 以及如何运行,再在浏览器中给出 该 HTML 文件的 URL 地址即可, Applet 本身的执行过程也 较 Application 复杂。
3.1 、所有小应用程序的根源 回忆一下小应用程序的书写格式 import java.applet.*; public class MyApplet extends Applet{ … ; } 每一个小应用程序都继承自 java.applet.Applet 类,并且每 个小应用都有一个主程序类,之前必须加上 public 。
2.1 所有小应用程序的根源 1. Browser loads URL 2. Browser loads HTML document Applet class 3. Browser loads applet classes Location: Loading Browser run applet
3.1 、所有小应用程序的根源 applet Browser SERVER 本地程序 file SERVER local connection applet 被下载的 与 applet 无关的 本地方法 小应用程序的限制
3.1 、所有小应用程序的根源 一个简单例子: import java.applet.*; import java.awt.*; public class HelloApplet extends Applet { public String s; public void init() { s = new String(“Hello World!”); } public void paint(Graphics g) { g.drawString(s,25,25); } Hello World <applet code="HelloApplet.class" width=300 height=300> HelloApplet.java
Java.applet.Applet public void init()public void destroy() public void start() public void stop() public void paint(Graphics g) 3.2 、小应用程序的执行 ——Applet 的运行控制 Applet 的运行控制
Applet 的生命周期 初始态(瞬态) 运行态 停止态 消亡态 离开 Web 页面:极小 化或装入其他页面, 调用 stop() 方法 重新装入或改变页面 大小或返回 Web 页面, 调用 start() 方法 关闭浏览器,调用 stop() 、 destroy() 方法 第一次装入,构造 applet 类,调用 init() 方法 调用 start() 方法 3.2 、小应用程序的执行 ——Applet 的运行控制
Applet 中没有 main() 方法。当 Applet 被浏览器运行时, init() 、 start() 、 stop() 、 destroy() 方法等自动执行: init() 方法:初始化,自动调用,只执行一次。本方法 主要完成一些在 Applet 构造方法所不能完成的工作。 start() 方法:初始化后,重入等都将自动调用。本方 法是 Applet 的主体,在其中可以执行一些任务或启动相 关的线程来执行任务。 stop() 方法:离开 Applet 所在页面时调用,以停止消 耗系统资源。 destroy() 方法:浏览器关闭时自动调用,以清除 Applet 所用的所有资源。 3.2 、小应用程序的执行 ——Applet 的运行控制
除了四个 Applet 生命周期控制的方法外, Applet 类还提供 了一些其他有用的方法: public String getAppletInfo(): 返回 applet 信息String public URL getDocumentBase() : 返回 html 文件所在的 urlURL public URL getCodeBase() : 返回 applet 程序所在的 urlURL public String getParameter(String name): 返回指定参数 值String public boolean isActive() 3.2 、小应用程序的执行 ——Applet 的运行控制
HTML 中 applet 标记的使用 < APPLET [CODEBASE = codebaseURL] CODE = appletFile [ALT = alternateText] [NAME = appletInstanceName] WIDTH = pixels HEIGHT = pixels [ALIGN = alignment] [VSPACE = pixels] [HSPACE = pixels] > [ ]... [alternateHTML] 3.2 、小应用程序的执行 ——Applet 与 HTML
CODEBASE = codebaseURL 指明 Applet 类文件所在 URL 基址,在 Applet 类中,方法 getCodeBase() 可以获取该属性。如果这个属性没有指明,那么 Applet 类文件必须与 包含它的 HTML 页面在同一个目录下,方法 getCodeBase() 返回的值与 getDocumentBase() 相同。 CODE = appletFile 指明需要运行的 Applet 类文件(.class 文件),该文件是与 codebaseURL 相关的。 NAME = appletInstanceName 给出了 Applet 类运行时的实例名,这使得同处于一个页面的不同 Applet 之间能够相互通信。方法getAppletContext()可以得到同一个方 页面中其它Applet类。 3.2 、小应用程序的执行 ——Applet 与 HTML
ALT = alternateText 如果浏览器支持 Applet 但不能运行它,就显示 alternateText 中所给出 的文字。否则就忽略它。 WIDTH = pixels HEIGHT = pixels Applet 在浏览器中所显示的高度和宽度(以象素为单位)。 ALIGN = alignment Applet 在浏览器中显示时的对齐方式,其含义与效果与图片在 HTML 中的一样。其取值有: left, right, top, texttop, middle, absmiddle, baseline, bottom, absbottom 。 VSPACE = pixels HSPACE = pixels Applet 在浏览器中显示时上下、左右要预留的高度和宽度,其含义与 效果与图片在 HTML 中的一样 ( 间距 ) 。 3.2 、小应用程序的执行 ——Applet 与 HTML
属性可以使得 Applet 能够从页面中获取所需的参数。 Applet 可以用其方法 getParameter()获取 属性指定的 参数。 属性的作用与应用程序中 main() 方法里参数 String args[] 的作用是一样的。 一个好的小应用程序,应该提供用户能够设置外部参数的功能,以 使得用户能够根据自己的需要来应用它。方法getParameterInfo()可 以得到有关 属性的说明信息。 alternateHTML 如果浏览器不支持 Applet ,就解释 alternateHTML 所给出的 HTML 代 码。否则就忽略它。 3.2 、小应用程序的执行 ——Applet 与 HTML
public class AppletPara extends Applet { String s1,s2; public void init() { s1 = getParameter("p1"); s2 = getParameter("p2"); } public void paint(Graphics g) { g.drawString(s1,10,10); g.drawString(s2,10,30); } Applet Parameter Test <applet code=“ AppletPara.class" width=300 height=300> 两个步骤: 在 Applet 类中: s1 = getParameter("p1"); 在页面中设置 Applet 参数: 3.2 、小应用程序的执行 ——Applet 与 HTML
public class AppletApp extends Applet { public String s; public void init() { s = new String(“Hello World!”); } public void paint(Graphics g) { g.drawString(s,25,25); } 一个 Java 类文件可以既是一个 Java Applet ,又是一个 Java Application ,只不过在编写时稍微复杂一些而已,但它 却既可以在浏览器中运行,又可以作为 Application 单独运行。 public static void main( String args[] ) { Frame f = new Frame(“Applet-App”); AppletApp app = new AppletApp(); f.add(app, “Center”); f.setSize(200, 200); f.setVisible(true); f.addWindowListener( new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); app.init(); app.start(); } AppletApp.java 3.2 、小应用程序的执行 ——Applet 与 Application
Java Applet 浏览器是指可以运行包含 Applet 的 HTML 文件 的一切软件系统。 HotJava 、 Netscape Navigator 以及 Microsoft Internet Explorer 等支持 Java 的网络浏览器都是 Applet 浏览器, Java Applet 都可以在其中运行。 AppletViewer 是一个 Java 应用程序,它可以使得用户无须 使用网络浏览器而直接运行 Java Applet 。但 AppletViewer 仅 仅是一个 Applet 浏览器, HTML 文件中的其他内容将不会被 显示出来。 AppletViewer 是从 java.awt.Frame 中继承而来。 使用方法: AppletViewer 3.2 、小应用程序的执行 ——Java Applet 浏览器
图像加声音结合在一起可以使得程序更加有吸引力。 1. 在 init() 中既取图像也取声音片断 Image img = getImage(getCodeBase(), "img.gif"); AudioClip sound = getAudioClip(getCodeBase(),"boing.au"); 2. 在 start() 中加入 sound.loop(); 3. 在 paint() 中加入 g.drawImage( img, 0,0, obs); 4. 在 stop() 中加入 if ( sound != null ) sound.stop(); 3 、图象操作 —— 图像和声音的结合 ImageSound.java
4 、 SWT SWT 是一个低级的 GUI 工具包。 JFace 是一组用 来简化使用 SWT 构建 GUI 的增强组件和工具服务; 也是基于一个对等体实现的,在这一点上它与 AWT 非 常类似; SWT 不支持 GUI 控件的自动销毁。这意味着 我们必须显式地销毁所创建的任何控件和资源, SWT 只能自顶向下地构建 GUI ; SWT 组件也不是线程安全 的 , SWT 和 JFace 并不是 Java 技术的标准配置.
4 、 SWT 程序组成: 显示界面 Display :管理事件循环和控制 UI 线程和其他线程间的通 讯; 命令界面 Shell :可视窗口; 窗口部件 Widgets :组件 环境配置: 将 org.eclipse.swt.* 库导入项目; 在运行时配置变量 : 1 、 -Djava.library.path={} 使用原生库; 2 、在操作系统的环境变量中加入 DLL 文件的路径: Linux/UNIX 下修改 “ LD_LIBRARY_PATH ” Windows 下修改 “ PATH ” ; 3 、 Windows 下将 DLL 文件拷贝到 Windows\System32 文件夹中 ( 辅助 ) ; 4 、将 DLL 文件拷贝到项目文件夹的根目录下 ; 5 、把 DLL 文件拷贝到..\Java\jdk1.5.0\jre\bin 文件夹的根目录下 ( 推荐 )
4 、 SWT 开发流程: 创建一个 display ; 创建一个或多个 Shell ,并设置其 Layout ; 创建 shell 中的 widgets ; 开启 Shell 窗口; 写一个事件循环; 销毁 display 。