本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!
本文曾發(fā)表于天極網(wǎng):http://dev.yesky.com/185/2690685.shtml
Java SE 6之GUI:讓界面更加絢麗(下)
Java是一種非常強(qiáng)大的編程語(yǔ)言,但Java的GUI能力一直是它的軟肋。雖然Java提供2種圖形解決方案,AWT和Swing。但這2種圖形庫(kù)的功能十分有限,使用它們并不能帶來(lái)更多的用戶體驗(yàn)。而且AWT和Swing的更新速度很慢。一直到Java SE 5也沒(méi)什么明顯的變化。幸好Java SE 6終于為它們?cè)黾哟蟾鼜?qiáng)大的功能。有了這些功能,使用AWT和Swing設(shè)計(jì)的用戶界面可以更貼近用戶。為了使讀者能夠更早地體驗(yàn)Java SE 6 GUI的美麗,本文就Java SE 6 GUI提供的主要功能進(jìn)行討論。
一、顯示啟動(dòng)界面
現(xiàn)在很多商業(yè)和非商業(yè)軟件在啟動(dòng)時(shí)都必須初始化,有時(shí)初始化的時(shí)間會(huì)很長(zhǎng),如photoshop、flash等,為了讓用戶有耐心繼續(xù)等待,不要誤以為死器了,這些軟件在初始化之前總是顯示一個(gè)圖形界面來(lái)告訴用戶軟件正在做什么。如圖1是Flash8在啟動(dòng)時(shí)的初始化界面。
圖1 Flash8的啟動(dòng)界面
當(dāng)我們?cè)谠O(shè)計(jì)軟件時(shí)可能也需要這樣一個(gè)界面。當(dāng)然,這在Java SE的早期版本中也可以做到,但比較費(fèi)勁,基本的實(shí)現(xiàn)是將一個(gè)圖形放到窗體上,然后先顯示這個(gè),這需要編寫(xiě)一定的代碼,而Java SE 6提供了一個(gè)更簡(jiǎn)單的方法,可以不添加一行代碼,而且在界面要改變時(shí)還不需要重新編譯源程序。讓我們先看一個(gè)簡(jiǎn)單的例子。
import javax.swing.*;
import java.awt.*;
public class TestSplash
{
public static void main(String args[])
{
try
{
// 為了讓啟動(dòng)界面多顯示3秒,
// 如果是正常的程序,這里應(yīng)該時(shí)初始化代碼
Thread.sleep(3000);
JFrame frame = new JFrame("Java SE 6 啟動(dòng)界面演示");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("我的標(biāo)簽", JLabel.CENTER);
frame.add(label, BorderLayout.CENTER);
frame.setSize(300, 95);
frame.setVisible(true);
}
catch (InterruptedException e)
{
}
}
}
上面的程序是一個(gè)非常簡(jiǎn)單的界面演示程序,它的界面如圖2所示。
圖2
如果使用java
TestSplash直接運(yùn)行上面的程序,將立刻顯示如圖2的界面。Java
SE 6在java命令上提供了一個(gè)選項(xiàng),可以在顯示程序主界面之前先顯示一幅圖。
java –splash:splash.gif TestSplash
如果運(yùn)行以上的命令,在出現(xiàn)圖2所示的界面之前會(huì)先顯示splash.gif,然后再過(guò)幾秒鐘splash.gif自動(dòng)關(guān)閉,然后會(huì)顯示主界面。在上面程序中的Thread.sleep(3000); 是為了使splash.gif顯示的時(shí)間長(zhǎng)一些,可以將這句改為直正的初始化代碼。splash.gif文件如圖3所示。
圖3 splash.gif
在發(fā)布時(shí)一般將程序所用到的.class文件打包成一個(gè)或幾個(gè).jar文件,如果是這樣,可以將splash.gif一同打包在.jar文件中。然后在manifest.mf文件中使用SplashScreen-Image指定啟動(dòng)界面圖象。
在打包之前,先建一個(gè)文本文件manifest.mf,內(nèi)容如下
Manifest-Version: 1.0
Main-Class: TestSplash
SplashScreen-Image: splash.gif
然后通過(guò)以下命令進(jìn)行打包
jar -mcvf manifest.mf Splash.jar TestSplash.class
splash.gif
然后通過(guò)如下命令運(yùn)行程序
java -jar Splash.jar
現(xiàn)在我們已經(jīng)可以顯示一個(gè)啟動(dòng)界面了,但這只是一幅靜態(tài)的圖,而在大多數(shù)時(shí)還需要在這幅圖上顯示一些信息,如正在初始化什么。在Java SE 6也提供了可以操作這幅圖的功能。下面的代碼演示了如何操作啟動(dòng)界面。
import javax.swing.*;
import java.awt.*;
public class TestSplash
{
public static void main(String args[])
{
try
{
String[] info = new String[]
{ "正在初始化API
", "正在初始化網(wǎng)絡(luò)
", "正在初始化數(shù)據(jù)庫(kù)
" };
SplashScreen splash = SplashScreen.getSplashScreen();
Graphics g = splash.createGraphics();
if (splash != null)
{
for (int i = 0; i < 3; i++)
{
g.setColor(Color.BLACK);
g.drawString(info[i], 350, 170 + i * 15);
splash.update();
Thread.sleep((i + 1)*1000);
}
}
JFrame frame = new JFrame("Java SE 6 啟動(dòng)界面演示");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("我的標(biāo)簽", JLabel.CENTER);
frame.add(label, BorderLayout.CENTER);
frame.setSize(300, 95);
frame.setVisible(true);
}
catch (Exception e)
{
}
}
}
上面的代碼SplashSreen獲得啟動(dòng)界面,然后再通過(guò)createGraphics得到一個(gè)圖形句柄。本例將在啟動(dòng)界面顯示按一定時(shí)間間隔顯示三個(gè)字符串,這三個(gè)字符串保存在info數(shù)組中。啟動(dòng)界面如圖4所示。
圖4 在啟動(dòng)界面上顯示三個(gè)字符串
另外需要提一點(diǎn),在SplashScreen類(lèi)中有一個(gè)close方法用于關(guān)閉啟動(dòng)界面,但這個(gè)方法一般不需要調(diào)用,因?yàn)樵谥鞔翱陲@示時(shí)這個(gè)方法自動(dòng)被調(diào)用。當(dāng)然,要想在初始化過(guò)程中關(guān)閉這啟動(dòng)界面,如發(fā)生初始化錯(cuò)誤后,就不能再往下初始化了,因此,就要關(guān)閉這個(gè)界面,然后或退出程序,或直接進(jìn)入主界面。
二、系統(tǒng)托盤(pán)
現(xiàn)在有很多程序除了提供了一個(gè)完整的主界面外,在它最小化或者啟動(dòng)后在右下角的系統(tǒng)托盤(pán)區(qū)總是有一個(gè)小圖標(biāo),如金山詞霸、QQ和MSN等。圖5顯示了一臺(tái)計(jì)算機(jī)的系統(tǒng)托盤(pán)里的圖標(biāo)。
圖5 系統(tǒng)托盤(pán)
如果使用C++、Delphi(Pascal)等語(yǔ)言實(shí)現(xiàn)這個(gè)功能非常簡(jiǎn)單,只要調(diào)用一下系統(tǒng)API即可,但在以前版本(Java SE 5以前)的Java SE中Sun并未提供訪問(wèn)系統(tǒng)托盤(pán)的類(lèi),在那時(shí)使用Java訪問(wèn)系統(tǒng)托盤(pán)的唯一方法就是使用JNI直接調(diào)用系統(tǒng)API,但這種方法實(shí)現(xiàn)比較復(fù)雜,而且如果這樣做,就破壞了Java的跨平臺(tái)特性(除非你為每一個(gè)操作系統(tǒng)平臺(tái)都做一個(gè)這樣的類(lèi))。Java的這個(gè)缺陷緩和終于在Java SE 6中得到彌補(bǔ)。在java.awt包中提供了一個(gè)SystemTray類(lèi)可以直接訪問(wèn)系統(tǒng)托盤(pán)。下面的代碼演示了一個(gè)簡(jiǎn)單的實(shí)現(xiàn)。
import javax.swing.*;
import java.awt.*;
public class MyTray
{
public static void main(String args[])
{
// 判斷當(dāng)前操作系統(tǒng)是否支持系統(tǒng)托盤(pán)
// 最好加上這個(gè)判斷,否則這個(gè)程序可能在其它操作系統(tǒng)上無(wú)法正常工作
if (SystemTray.isSupported())
{
// 通過(guò)靜態(tài)方法getSystemTray()得到系統(tǒng)托盤(pán)
SystemTray tray = SystemTray.getSystemTray();
// 裝載托盤(pán)圖象
Image image = Toolkit.getDefaultToolkit().getImage(
"tray.gif");
// 為這個(gè)托盤(pán)加一個(gè)彈出菜單
PopupMenu popup = new PopupMenu();
MenuItem item = new MenuItem("我的菜單");
popup.add(item);
// 為這個(gè)托盤(pán)加一個(gè)提示信息
TrayIcon trayIcon = new TrayIcon(image, "提示信息", popup);
try
{
tray.add(trayIcon);
}
catch (AWTException e)
{
System.err.println("無(wú)法向這個(gè)托盤(pán)添加新項(xiàng): " + e);
}
}
else
{
System.err.println("無(wú)法使用系統(tǒng)托盤(pán)!");
}
}
}
在運(yùn)行上面的程序之前,tray.gif一定要放到當(dāng)前目錄,如果放到其它的目錄,要在程序中指明。圖6是程序運(yùn)行結(jié)果。最左側(cè)的五彩光盤(pán)圖標(biāo)就是本程序加入了。
圖6 運(yùn)行結(jié)果
如果多次調(diào)用tray.add(trayIcon),可以在一個(gè)程序中向系統(tǒng)托盤(pán)添加多個(gè)圖標(biāo)。但要注意,圖象可以使用一個(gè)Image對(duì)象,但彈出菜單要為每一個(gè)圖標(biāo)建一個(gè),如果不建,就設(shè)為null。如:
TrayIcon trayIcon1 = new TrayIcon(image,
"提示信息1", null);
TrayIcon trayIcon2 = new TrayIcon(image,
"提示信息2", null);
TrayIcon trayIcon3 = new TrayIcon(image,
"提示信息3", null);
tray.add(trayIcon1);
tray.add(trayIcon2);
tray.add(trayIcon3);
圖7為顯示界面圖
圖7
Java SE 6還為我們提供了3種提示信息,它們是警告、錯(cuò)誤和信息。如使用如下語(yǔ)句添加提示信息。
添加警告提示
trayIcon.displayMessage("警告", "這是一個(gè)警告提示!", TrayIcon.MessageType.WARNING);
圖8 警告提示
添加錯(cuò)誤提示
trayIcon.displayMessage("錯(cuò)誤", "這是一個(gè)錯(cuò)誤提示!", TrayIcon.MessageType.ERROR);
圖9 錯(cuò)誤提示
添加信息提示
trayIcon.displayMessage("信息", "這是一個(gè)信息提示!", TrayIcon.MessageType.INFO);
圖10 信息提示
交互對(duì)話框
在一般的程序語(yǔ)言或開(kāi)發(fā)工具中都有一些標(biāo)準(zhǔn)的對(duì)話框以方便和用戶交互,如Delphi中有InputBox對(duì)話框用來(lái)采集用戶的輸入信息。在Java SE 6中也提供了類(lèi)似的標(biāo)準(zhǔn)對(duì)話框來(lái)滿足這些需求。
在Java SE 6中提供了一種輸入對(duì)話框,下面是一個(gè)使用這個(gè)對(duì)話框的簡(jiǎn)單例子。
JOptionPane pane = new JOptionPane("文本",
JOptionPane.INFORMATION_MESSAGE);
pane.setWantsInput(true);
JDialog dialog =
pane.createDialog(parent, "請(qǐng)輸入文本");
dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setVisible(true);
String msg = pane.getInputValue();
上面的代碼使用JoptionPane對(duì)象的createDialog方法來(lái)建立一個(gè)輸入對(duì)話框。上面的代碼有幾點(diǎn)需要注意一下。
1.
如果將pane.setWantsInput(true)改為pane.setWantsInput(false),那么輸入對(duì)話框?qū)⑾А?/span>
2.
這個(gè)對(duì)話框使用的是APPLICATION_MODAL模式,Java
SE 6還提供了一個(gè)DOCUMENT_MODAL模式,這兩種模式最大的區(qū)別是第一種模式是對(duì)整個(gè)應(yīng)用程序的,也就是說(shuō),使用這種模式彈出對(duì)話框后,整個(gè)程序都不訪問(wèn),而使用第二種模式,只有彈出對(duì)話框的窗體不可訪問(wèn),其它的窗體并不受影響。圖11為以上代碼的程序界面。
圖11
圖象轉(zhuǎn)換
Java在圖象處理上是比較強(qiáng)大的,但是以前的Java SE版本對(duì)于GIF圖只能讀,不能寫(xiě)。這并不是因?yàn)榧夹g(shù)原因,而是因?yàn)?/span>GIF專(zhuān)利的原因。但最近這個(gè)專(zhuān)利到期了,因此,在Java SE 6中提供了讀寫(xiě)GIF的功能。下面的代碼演示了如何通過(guò)Java來(lái)將其它格式的圖象轉(zhuǎn)換為gif格式。
import javax.imageio.*;
import java.io.*;
import java.awt.image.*;
import java.util.*;
public class ToGIF
{
public static void main(String args[]) throws IOException
{
// 可以將abc.bmp換成其它格式的圖象
File inputFile = new File(“abc.bmp”);
BufferedImage input = ImageIO.read(inputFile);
File outputFile = new File("abc.gif");
ImageIO.write(input, "GIF", outputFile);
}
}
如果你想知道在Java SE 6支持什么圖象格式,可以使用如下語(yǔ)句進(jìn)行查看。
System.out.println(Arrays.toString(ImageIO.getWriterFormatNames()));
顯示結(jié)果
[BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG,
JPEG, WBMP, GIF, gif]
新浪微博:http://t.sina.com.cn/androidguy 昵稱(chēng):李寧_Lining