摘要
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 不能,這是因為默認情況下,前景色是黑色。現在我們又將背景也設置為黑色。就象在黑布上用黑鋼筆寫字一樣,是看不到的。