摘要
Java语言提供了对各种多媒体的良好支持,在本章中我们将学习如何在你的Java语言程序中处理图像、声音、字体等资源,让你的程序更加有趣。
--------------------------------------------------------------------------------
本章目标:
Java语言提供了对各种多媒体的良好支持,在本章中我们将学习如何在你的Java语言程序中处理图像、声音、字体等资源,让你的程序更加有趣。
11.1 图像
传授新知
与其它编程语言不一样,Java语言没有为图像文件提供类于什么图像框的控件(用Java的术语来说,就是类),而是无处不可有图像。我们可以在标签上,在按钮中,在许许多多普通的GUI部件上显示图像。
通常,在Java语言中,使用一个图像需要经过三个步骤:
1.装载图像
Java是伴随着Internet发展起来的,被认为是最优秀的Internet编程语言,因此我们经常会看到许多细节都在体现这一风格或精神。
例如,Java语言是通过URL(统一资源定位,Uniform Resource Location,最常见的URL是用来指向WEB页面的)进行文件引用的。这样的机制,使Java语言引用一个本地文件与引用一个Internet上的文件并没有什么区别。
我们通过getImage()方法装载图像,这个方法的语法格式如下所示:
public Image getImage(String url)
public Image getImage(String url,String name)
¨ 第一种形式:直接给出指向文件的URL;
¨ 第二种形式:通过合并指定的url和后面的name形成新的URL。
一些提示:
因为考虑到读者不一定都了解如何使用URL表示本地文件,所以在些给出一个实例,以便大家理解:
file:/c:/javastudy/test.jpg
格式是:file:/盘符:/路径/文件名。需要注重是,我们使用的是“/”来隔开各个部分,而不是使用Windows下的“”符。
我们经常需要调用当前目录下的文件,即使是这样,我们也需要写出这个目录的URL,否则将无法找到这个程序。
这,太痛苦了!不过,Java也提供了一个十分体贴的方法,让你能够很轻松地获得当前目录的URL:
getCodeBase()
这样,我们假如要调用当前目录下的1.jpg文件的话,就可以使用语句:
getImage(getCodeBase(),”1.jpg”);
getImage方法将返回一个Image对象。所以,我们通常先定义一个Image对象,用来存放装载进来的图像,例如:
Image image1=getImage(getCodeBase(),”1.jpg”);
这样,就将1.jpg装载到image1中了。
2.生成ImageIcon
将图像装载进来以后,还不能够直接被程序所使用,我们还要先调用ImageIcon方法将其生成一个ImageIcon:
ImageIcon(Image)
这个方法将返回一个ImageIcon对象,有了ImageIcon对象后,就可以被使用了。下面就是一个实例,我们将包含1.jpg的图象的image1对象转成ImageIcon对象icon1:
ImageIcon icon1=new ImageIcon(image1);
3.显示图像
现在,我们就可以显示这个图像了,我们将ImageIcon对象作为参数,创建标签、按钮等部件,就可以显示出这个图像了。下面我们就分别介绍一下:
1) 标签:
public JLabel(ImageIcon icon);
public JLabel(String text,ImageIcon icon);
第一个构造器,是让标签中只显示图像,而第二个构造器就可以同时显示文本标签和图像。可谓图像并茂。
2) 按钮:
public JButton(ImageIcon icon);
public JButton(String text,ImageIcon icon);
很明显,与标签构造器十分类似。
注重:
任何事物都是不断发展的,java.AWT包中提供的部件尚不能很好地包含图像,而更先进的java.Swing包中提供的部件就可以很好地包含图像了。
实例说明
下面,我们来构建一个显示图像的程序。为了大家便于完成这个实例操作,我们选用了一个大家都有的图像文件:
C:windowssystemoobeimagescnncterr.jpg文件。
为了方便操作,大家先将其拷贝到C:javastudy目录下。
源程序:useImage.java
import java.applet.*;
import java.awt.*;
import javax.swing.*;
public class useImage extends JApplet
{
Image image1;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new BorderLayout());
image1=getImage(getCodeBase(),"cnncterr.jpg");
ImageIcon icon1=new ImageIcon(image1);
JLabel imagelabel=new JLabel(icon1);
panel1.add(imagelabel);
}
}
将这个程序编译后,运行的结果如下图所示:
图11-1 程序useImage.java的输出
接下来,我们再来看一个有趣的程序:
源程序:useImage2.java
import java.applet.*;
import java.awt.*;
import javax.swing.*;
public class useImage2 extends JApplet
{
Image image1,image2;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new BorderLayout());
image1=getImage(getCodeBase(),"ontbvsa.gif");
ImageIcon icon1=new ImageIcon(image1);
image2=getImage(getCodeBase(),"offtbvsa.gif");
ImageIcon icon2=new ImageIcon(image2);
JButton imagebutton=new JButton(icon2);
imagebutton.setPressedIcon(icon1);
panel1.add(imagebutton,BorderLayout.CENTER);
}
}
这个程序的输出是:
图11-2 程序最初的显示
图11-3 当按下这个按钮时
这里,使用了一个新的方法,实现了一个非凡的效果!
imagebutton.setPressedIcon(icon1);
这就是当你按下这个按钮时,就显示icon1所指向的图像。
自测练习
1)___________包中定义的部件能够直接使用图像。
a.java.awt.* b.java.swing.* c.javax.swing.*
2) 一个按钮________同时拥用文本标签和图像。
a.不能 b.能
3) 按钮中可以直接使用____________对象。
a.ImageIcon b.Image c.Icon
4) 取得当前目录的URL使用_____________方法。
a.getURLbase b.getURL c.getCodeBase
5) 一个标签________同时拥用文本标签和图像。
a.能 b.不能
6) 编写一个程序,在默认情况下,只显示两个按钮:MasterCard和VisaCard,
图11-4 练习题图(1)
当按下MasterCard按钮时,则显示MasterCard的图像:
图11-5 练习题图(2)
而按下VisaCard按钮时,显示M VisaCard的图像。如下图所示:
图11-6 练习题图(3)
注:这两幅图分别是c:windowssystemoobdgmc.jpg和bgvisa.jpg。
练习答案
1)c 在java.awt包定义的部件对图像的支持不好;java.swing包是不存在的,应该是javax.swing。
2)b 当然可以。
3)a Image对象应先转成ImageIcon对象。
4)c 没有什么好解释的,提供的方法名就是getCodeBase()。
5)a 当然可以。
6)以下是一个实现实例:
源程序:lianxi11_1.java
import java.applet.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class lianxi11_1 extends JApplet
{
Image image1,image2;
ImageIcon icon1,icon2;
JButton mc,visa;
JLabel imagelabel;
public void init()
{
Frame frame1=new Frame("lianxi11_1");
frame1.setLayout(new BorderLayout());
image1=getImage(getCodeBase(),"bgmc.jpg");
icon1=new ImageIcon(image1);
image2=getImage(getCodeBase(),"bgvisa.jpg");
icon2=new ImageIcon(image2);
imagelabel=new JLabel();
frame1.add(imagelabel,BorderLayout.CENTER);
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(1,2));
mc=new JButton("MasterCard");
visa=new JButton("VisaCard");
panel1.add(mc);
panel1.add(visa);
mc.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
imagelabel.setIcon(icon1);
}
});
visa.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
imagelabel.setIcon(icon2);
}
});
frame1.add(panel1,BorderLayout.SOUTH);
frame1.pack();
frame1.show();
}
}
11.2 声音
传授新知
有时,我们需要在程序中释放声音,我可以在import java.applet.*包的支持下,让Java程序能够播放WAV、AU和SND格式的声音文件。
1.装载声音文件
与引用图像文件一样,我们也要将声音文件装载进来,才能够供Java程序使用。同样的,我们还是使用URL来定位一个声音文件。
在Java语言中装载声音文件,是使用getAudioClip方法,其语法格式是:
public AudioClip getAudioClip(String url)
public AudioClip getAudioClip(String url,String name)
同样的,我们可以调用getCodeBase()方法来获取当前目录的URL,这样就可以很方便地调用当前目录下的声音文件。例如:
AudioClip clip1=getAudioClip(getCodeBase(),”carbrake.wav)
注:carbreak.wav是Office97中带的,你可以在c:windowsmediaoffice97目录中找到,在此假设已拷贝到了c:javastudy目录中。
这样,我们就获得了一个AudioClip(声音片段)clip1,这个声音片段中存放的就是声音文件carbreak.wav。
2.操作声音片段
使用声音比使用图像要简单得多,我们现在就可以直接对一个AudioClip(声音片段)进行操作了,不再需要转换(图像就得从Image转成ImageIcon)。
1) 播放声音片段:
声音片段名.play()
一句话,就是直接调用声音片段对象的play()方法就可以将其播放出来。
2) 停止播放:
声音片段名.stop()
很简单吧,play就是播放,stop就是停止,好象在用放音机一样。
3) 循环播放:
声音片段名.loop()
有时,我们可能会需要一直播放一段声音,在Java语言中提供了一个很简单的方法来实现,那就是声音片段的loop方法。
实例说明
首先将c:windowsmediaoffice97carbrake.wav拷贝到c:javastudy目录下,然后输入以下源程序。
源程序:useAudio.java
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class useAudio extends JApplet
{
AudioClip carbrake;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(3,1));
carbrake=getAudioClip(getCodeBase(),"carbrake.wav");
JButton buttonPlay=new JButton("Play");
JButton buttonStop=new JButton("Stop");
JButton buttonLoop=new JButton("Loop");
panel1.add(buttonPlay);
panel1.add(buttonStop);
panel1.add(buttonLoop);
buttonPlay.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
carbrake.stop();
carbrake.play();
}
});
buttonStop.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
carbrake.stop();
}
});
buttonLoop.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
carbrake.stop();
carbrake.loop();
}
});
}
}
这个程序经编译后用appletviewer可以看到如下界面:
图11-7 useAudio.java的程序界面
当你按下play按钮时,你就会听到一声汽车的刹车声。而当你按下Loop按钮时,你就会听到边续不断的汽车刹车声。当你厌倦了的时候,就按下stop按钮,声音就消失了。
自测练习
1) 在Java语言中,使用_______类来装载声音文件。
a.Sound b.SoundClip c.AudioClip d.Clip
2) ___________包提供了对声音的支持。
a.java.awt.* b.javax.swing.* c.java.swing.* d.javax.awt.*
3) 在c:windowsmedia目录下有一个The Microsoft Sound.wav,它是Windows启动时的欢迎乐,在c:windowsmediaoffice97目录下有一个chimes.wav,它是一段十分和谐的音乐。下面请您编写一个程序,构建两个按钮,第一个是Microsoft Sound,按下时就播放第一个音乐;第二个按钮则是chimes,按下时就播放第二个音乐。程序界面如下图所示:
图11-8 练习题图
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)c 在Java中,使用AudioClip来装载声音文件。
2)a
3)以下是一个程序实例:
源程序:lianxi11_2.java
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi11_2 extends JApplet
{
AudioClip clip1,clip2;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(2,1));
clip1=getAudioClip(getCodeBase(),"The Microsoft Sound.wav");
clip2=getAudioClip(getCodeBase(),"chimes.wav");
JButton button1=new JButton("Microsoft Sound");
JButton button2=new JButton("Play chime");
panel1.add(button1);
panel1.add(button2);
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
clip2.stop();
clip1.play();
}
});
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
clip1.stop();
clip2.play();
}
});
}
}
11.3 改变字体
传授新知
不知不觉中,我们已经学习了很多的关于Java的知识了,从字符界面到图形界面,从呆滞的文字到多彩的图像、声音……
不过,不知道大家注重到没有,我们一直没有改变程序中显示出来的文字的字体!现在,我们就来补一下这方面的知识。
字体是一个十分神奇的东西,例如,我们使用了黑体字体现出了各个章节,使用楷体字体现出了一些注释、提示、说明等等。它使得我们的文本更生动、更直观。
字体由三种属性决定:
1) 字体名(family name)
字体名可以分成两大类:一种是中文字体,如宋体、楷体、黑体等;另一种是英文字体,如Arial、Times New Roman等等;
小知识:
对于英文字体中有两个术语:“等宽字体”与“变宽字体”,等宽字体是指每一英文字母的宽度一样大;而变宽字体则不然, m与l所占的宽度就不同。
2) 大小(size)
与字体名一样,大小也有两种衡量方式:一种是五号、六号,号数越小字越大;另一种是磅值(这是一种印刷界的通用单位),如11磅、12磅,它们的值越大,字越大。不过在Java中只支持后者,也就是磅值(point)。
3) 风格(style)
如斜体、粗体、下划线等。在Java中有四种字体风格,由Font类的值来定义。
¨ Font.PLAIN(普通)
¨ Font.BOLD(加粗)
¨ Font.ITALIC(斜体)
¨ Font.BOLD+ Font.ITALIC(粗斜体)
也就是说,在Java语言中并不支持下划线这种风格。
好了,我们已经知道了字体的具体内容,下面我们来看一下如何在程序中设置、改变字体?很简单,我们先使用以下构造器构造一个字体对象:
public Font(String familyName,int style,int size)
然后,调用对象的setFont方法来设置字体:
public void setFont(Font font)
正如上面所讲的一样,我们能够很轻松地设置风格与大小,但可以选择哪些字体名呢?我无法回答这个问题,谁也无法回答这个问题!因为这个问题的答案把握在你的系统中!也就是能够使用哪些字体,完全取决于你的系统中安装了什么字体。
实例说明
下面我们还做一次修改字体的实验:
源程序:lianxi11_2.java
import javax.swing.*;
import java.applet.*;
import java.awt.*;
public class useFont extends JApplet
{
public void init()
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(2,1));
JLabel fonttest=new JLabel("This is a Font test");
Font font=new Font("Arial",Font.BOLD,30);
fonttest.setFont(font);
panel1.add(fonttest);
JButton button1=new JButton("Test");
Font font1=new Font("Courier New",Font.BOLD,20);
button1.setFont(font1);
panel1.add(button1);
}
}
我们编译完后,用appletviewer观察程序的输出,你会发现,字体变了!
图11-9 useFont.java的输出
自测练习
1)“粗体”是字体的_________。
a.风格 b.字体集 c.大小
2)在Java语言中,字体大小使用________单位。
a.dot b.pixels c.point
3)在等宽字体中,字母m与字母l所占的字符宽度________。
a.相等 b.不相等
4) 只要两台机器上安装的操作系统一样,则能够使用的字体集就相同。______
a.对 b.不对
5) 在Java中,不支持____________。
a.粗体 b.下划线 c.斜体 d.粗斜体
6) 编写一个程序,其界面如下所示:
图11-10 练习题图
在这个程序中,我们打印出8个字体逐渐增长的字符串。其字体集为Arial,风格为普通。请编程实现:
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)a 粗体、斜体、粗斜体都是字体的风格。
2)c 采用印刷业的术语“磅”,即point。
3)a 所谓等宽就是所有字母所占的宽度相等。
4)b 不对,安装了什么字体是十分个性化的,除了操作系统,还有应用软件、手动安装使得字体不相同。
5)b 在java 中不支持下划线。
3)以下是一个程序实例:
源程序:lianxi11_3.java
import javax.swing.*;
import java.applet.*;
import java.awt.*;
public class lianxi11_3 extends JApplet
{
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(8,1));
for (int size=10;size<25;size+=2)
{
JLabel label=new JLabel("Arial,size is "+size);
Font font=new Font("Arial",Font.PLAIN,size);
label.setFont(font);
panel1.add(label);
}
}
}
11.4 使用颜色
传授新知
在我们前面的程序中,已经对颜色有了一些接触,在这一小节中,我们就系统地来学习一下如何在Java程序中使用颜色。
在Java中,就想处理字体一样,将与颜色相关的东西做在一个类中,这个类就是Color类。你可以通过它来定义各种各样的颜色。
1. 使用预定义颜色:
在Java语言中,为了方便大家在程序中使用常用颜色,就预先定义了13种颜色供大家使用。所有的预定义颜色如下表所示:
颜色值 颜色 颜色值 颜色
Color.black 黑色 Color.darkGray 深灰
Color.gray 灰色 Color.lightGray 浅灰
Color.white 白色 Color.red 红色
Color.green 绿色 Color.blue 蓝色
Color.yellow 黄色 Color.cyan 青色
Color.magenta 深红 Color.pink 粉红色
Color.orange 橙色
表11-1 预定义颜色一览表
2. 使用自定义颜色:
然而,我们生活在一个色彩斑斓的世界中,仅用这13种颜色来体现我们的心情,恐怕是太少了一些。为了让您能够充分发挥美术天才,在您的程序中更加色彩缤纷,我们自己动手定义一些喜欢的颜色。
要自己定义颜色,首先要学习一个常识。我们在小时候用颜料做画时就知道,有三种最基本的颜色(红、蓝、黄),只要各取一些就可以调出各种不同的颜色。
而在电脑的世界中,也是类似,但是我们要使用光学三原色,而不是颜料三原色。那就是RGB(Red、Green、Blue,红、绿、蓝)。我们将不同量的红、绿、蓝混合在一起就可以得到我们想要的颜色,当然这里需要经验和尝试。
使用下面的方法就可以完成“调色”工作:
Color(int red,int green,int blue)
其中red、green、blue代表我们取的量,值从(0-255)之间。例如:
Color black=new Color(0,0,0) 没有光嘛,当然是黑色;
Color white=new Color(255,255,255) 全来了,就是白色;
Color gray=new Color(128,128,128) 各一半,就是灰色。
实例说明
好了,我们通过一个实践,一方面了解一下颜色的使用,另一方面也熟悉一下Java中预定义的各种颜色的真实效果。
源程序:useColor.java
import javax.swing.*;
import java.applet.*;
import java.awt.*;
public class useColor extends JApplet
{
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new GridLayout(4,4));
JButton button1=new JButton("black");
button1.setForeground(Color.white);
button1.setBackground(Color.black);
panel1.add(button1);
JButton button2=new JButton("darkGray");
button2.setBackground(Color.darkGray);
panel1.add(button2);
JButton button3=new JButton("gray");
button3.setBackground(Color.gray);
panel1.add(button3);
JButton button4=new JButton("lightGray");
button4.setBackground(Color.lightGray);
panel1.add(button4);
JButton button5=new JButton("white");
button5.setBackground(Color.white);
panel1.add(button5);
JButton button6=new JButton("red");
button6.setBackground(Color.red);
panel1.add(button6);
JButton button7=new JButton("green");
button7.setBackground(Color.green);
panel1.add(button7);
JButton button8=new JButton("blue");
button8.setBackground(Color.blue);
panel1.add(button8);
JButton button9=new JButton("yellow");
button9.setBackground(Color.yellow);
panel1.add(button9);
JButton button10=new JButton("cyan");
button10.setBackground(Color.cyan);
panel1.add(button10);
JButton button11=new JButton("magenta");
button11.setBackground(Color.magenta);
panel1.add(button11);
JButton button12=new JButton("pink");
button12.setBackground(Color.pink);
panel1.add(button12);
JButton button13=new JButton("orange");
button13.setBackground(Color.orange);
panel1.add(button13);
}
}
在这个程序中,使用了最愚笨的方法完成了这个工作,相信无须点评,大家也能够一目了解了理会这个程序的用意。
下图就是这个程序的输出,大家从这个图中也就能够知道每个预定义颜色的样子:
图11-11 useColor.java的输出
自测练习
1) 在Java语言中,自定义颜色可以有_______。
a.无数种颜色 b.32K色 c.16M色
2) 以下___________是绿色。
a.new Color(0,255,0) b.new Color(255,255,255) c.new Color(0,0,0)
3) Java语言采用的是__________三原色。
a.颜料 b.光学
4) Java语言的三原色是___________。
a.红、黄、蓝 b.红、绿、蓝 c.红、黄、绿
5) 一个按钮的颜色定义如下:
button.setBackground(Color.black)
那么,我们________看到按钮上的标签文字。
a.能 b.不能
请说明原因:
____________________________________________________________________
练习答案
1)c 16M色,这很简单,三原色都可以取0-255,共256(28)个量,则它们的组合就是256*256*256,即224,也就是16M,因此可表示16M色。
2)a (0,255,0)说明0红光、255绿光、0蓝光,不是绿色是什么色?
3)b
4)b 光学三原色,红、绿、蓝。
5)b 不能,这是因为默认情况下,前景色是黑色。现在我们又将背景也设置为黑色。就象在黑布上用黑钢笔写字一样,是看不到的。