Do you drink java?



                像寫情書一樣coding

           

          2005年9月11日

          發(fā)發(fā)牢騷

          IE7訪問(wèn)我的部落格頁(yè)面布局異常!

          Firefox2.0添加新隨筆JS腳本異常!!

          |/__


          換了風(fēng)格

          posted @ 2006-11-23 16:49 leon 閱讀(410) | 評(píng)論 (0)編輯 收藏

          [Swing]在 JFileChooser 中進(jìn)行文件驗(yàn)證的小技巧

          我們?cè)谧鯣UI編程的時(shí)候經(jīng)常需要用到JFileChooser組件構(gòu)造一個(gè)文件選取對(duì)話框來(lái)為用戶提供打開文件、保存文件等操作。

          通常的做法是調(diào)用JFileChooser.showXXX()方法顯示文件選取對(duì)話框并且選擇一個(gè)文件后,點(diǎn)擊Approve 按鈕(默認(rèn)情況下標(biāo)有 "Open" 或 "Save")當(dāng)對(duì)話框關(guān)閉后使用JFileChooser.getSelectedFile()方法得到選取的文件(或使用JFileChooser.getSelectedFiles()取得選取的文件數(shù)組),然后再對(duì)被選取的文件有效性進(jìn)行驗(yàn)證(例如,文件的文件名是否合法、選取的路徑下是否已有同名文件存在等等),如果驗(yàn)證不通過(guò),需要再次打開文件選擇對(duì)話框進(jìn)行選取。

          顯然,驗(yàn)證沒(méi)有通過(guò)的情況下,文件選取對(duì)話框被反復(fù)的打開和關(guān)閉,影響用戶體驗(yàn)。

          我現(xiàn)在介紹一個(gè)方法,在點(diǎn)擊了文件選取對(duì)話框上的Approve 按鈕后,文件選取對(duì)話框關(guān)閉前對(duì)選取的文件進(jìn)行驗(yàn)證,如果驗(yàn)證沒(méi)有通過(guò),那么對(duì)話框不關(guān)閉,直接進(jìn)行下一次選擇。

          查看JFileChooser的API,可以發(fā)現(xiàn)這樣一個(gè)方法 public void approveSelection() ,這個(gè)方法會(huì)在用戶單擊 Approve 按鈕時(shí)由 UI 調(diào)用此方法。導(dǎo)致使用等于 APPROVE_SELECTION 的命令字符串激發(fā)一個(gè)操作事件。

          那么,我們現(xiàn)在可以選擇繼承JFileChooser再覆寫這個(gè)方法,將對(duì)選中文件的有效性驗(yàn)證寫入這個(gè)方法中,只有當(dāng)驗(yàn)證通過(guò)時(shí)才調(diào)用超類的approveSelection() 完成文件選取,否則直接返回,繼續(xù)選擇新的文件。

          下面是我寫的一個(gè)demo以供參考:

          import java.io.File;
          import javax.swing.JOptionPane;

          /**
          ?* 在 JFileChooser 中進(jìn)行文件驗(yàn)證的小技巧
          ?* @author Chen Wei
          ?* @email chenwei.mobi@gmail.com
          ?*/
          public class JFileChooserDemo extends javax.swing.JFileChooser{
          ???
          ??? public void approveSelection(){
          ??????? File file = getSelectedFile();
          ???????
          ??????? // 驗(yàn)證文件名是否合法
          ??????? if (!validateFileName(file.getName())) {
          ??????????? JOptionPane.showMessageDialog(getParent(), "文件名不能包含下列任何字符之一:\n \\ / : * ? \" < > |");
          ??????????? return;
          ??????? }else{
          ??????????? super.approveSelection();
          ??????? }
          ??? }
          ???
          ??? /**
          ???? * 驗(yàn)證輸入字符串參數(shù)是否為有效文件名。
          ???? * @param name 待驗(yàn)證的文件名字符串。
          ???? * @return 通過(guò)驗(yàn)證,文件名無(wú)效返回 false,有效返回 true。
          ???? */
          ??? public static boolean validateFileName(String name) {
          ??????? if (name.indexOf('\\') != -1 || name.indexOf('/') != -1 ||
          ??????????? name.indexOf(':') != -1 || name.indexOf('*') != -1 ||
          ??????????? name.indexOf('?') != -1 || name.indexOf('"') != -1 ||
          ??????????? name.indexOf('<') != -1 || name.indexOf('>') != -1 ||
          ??????????? name.indexOf('|') != -1) {

          ??????????? return false;
          ??????? } else {
          ??????????? return true;
          ??????? }
          ??? }
          ???
          ??? public static void main(String[] args){
          ??????? JFileChooserDemo chooser = new JFileChooserDemo();
          ??????? chooser.showOpenDialog(null);
          ??? }
          }


          程序運(yùn)行截圖:
          JFileChooserDemo.jpg

          posted @ 2006-11-23 14:15 leon 閱讀(5405) | 評(píng)論 (7)編輯 收藏

          [news]chenwei.mobi

          本博搬家到CSDN,網(wǎng)址 http://blog.csdn.net/chenweionline ,可以通過(guò) www.chenwei.mobi 訪問(wèn)!

          posted @ 2006-10-30 17:16 leon 閱讀(545) | 評(píng)論 (0)編輯 收藏

          [tips]使用Java將中文字符轉(zhuǎn)換成Unicode編碼

          這兩天操作XML使用到了Jdom,在創(chuàng)建XML文件并輸出到硬盤的時(shí)候遇到一個(gè)中文編碼的問(wèn)題:Jdom默認(rèn)輸出的XML編碼是UTF-8,但是文檔中如果出現(xiàn)中文字符那么該中文字符就會(huì)變成亂碼,造成XML文件無(wú)法被正確解析。

          UTF-8應(yīng)該是可以用來(lái)表示中文的吧?我不知道這是不是Jdom的一個(gè)BUG(Jdom 1.0,beta了10次的產(chǎn)物哦!)。我google了一下,大家解決這個(gè)問(wèn)題的辦法無(wú)非是把Jdom的輸出字符集改為GBK或者GB2312,但是這樣就會(huì)有一些副作用,如果在沒(méi)有特定字符集(GBK或者GB2312)的操作系統(tǒng)上不是依然不能正確解析嗎?一個(gè)比較好的解決辦法是先把中文轉(zhuǎn)換成Unicode編碼在直接輸出,程序解析XML后的時(shí)候再把Unicode編碼轉(zhuǎn)回中文就沒(méi)有問(wèn)題了。

          于是我查看了JDK的文檔,截至Java 5好像都沒(méi)有做類似轉(zhuǎn)換的類可以直接使用,但是我發(fā)現(xiàn)一個(gè)類 java.util.Properties,它的源代碼里有兩個(gè)私有(private)方法 loadConvert (char[] in, int off, int len, char[] convtBuf) 和 saveConvert(String theString, boolean escapeSpace) 其實(shí)就是做特殊字符和Unicode編碼字符間轉(zhuǎn)換的,我把它們提取出來(lái),單獨(dú)包裝到一個(gè)類里就可以使用了。

          下面是我包裝的類 CharacterSetToolkit

          /*
          ?* CharacterSetToolkit.java
          ?*
          ?* Created on 2006年10月27日, 下午2:06
          ?*
          ?* To change this template, choose Tools | Template Manager
          ?* and open the template in the editor.
          ?*/

          package mobi.chenwei.lang;

          /**
          ?* 進(jìn)行字符操作的工具類
          ?* @author Chen Wei
          ?* @email chenwei.mobi@gmail.com
          ?*/
          public class CharacterSetToolkit {
          ???
          ??? /** Creates a new instance of CharacterSetToolkit */
          ??? public CharacterSetToolkit() {
          ??? }
          ???
          ??? private static final char[] hexDigit = {
          ??????? '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
          ??? };
          ???
          ??? private static char toHex(int nibble) {
          ??????? return hexDigit[(nibble & 0xF)];
          ??? }
          ???
          ??? /**
          ???? * 將字符串編碼成 Unicode 。
          ???? * @param theString 待轉(zhuǎn)換成Unicode編碼的字符串。
          ???? * @param escapeSpace 是否忽略空格。
          ???? * @return 返回轉(zhuǎn)換后Unicode編碼的字符串。
          ???? */
          ??? public static String toUnicode(String theString, boolean escapeSpace) {
          ??????? int len = theString.length();
          ??????? int bufLen = len * 2;
          ??????? if (bufLen < 0) {
          ??????????? bufLen = Integer.MAX_VALUE;
          ??????? }
          ??????? StringBuffer outBuffer = new StringBuffer(bufLen);

          ??????? for(int x=0; x<len; x++) {
          ??????????? char aChar = theString.charAt(x);
          ??????????? // Handle common case first, selecting largest block that
          ??????????? // avoids the specials below
          ??????????? if ((aChar > 61) && (aChar < 127)) {
          ??????????????? if (aChar == '\\') {
          ??????????????????? outBuffer.append('\\'); outBuffer.append('\\');
          ??????????????????? continue;
          ??????????????? }
          ??????????????? outBuffer.append(aChar);
          ??????????????? continue;
          ??????????? }
          ??????????? switch(aChar) {
          ??????????????? case ' ':
          ??????????????????? if (x == 0 || escapeSpace)
          ??????????????????????? outBuffer.append('\\');
          ??????????????????? outBuffer.append(' ');
          ??????????????????? break;
          ??????????????? case '\t':outBuffer.append('\\'); outBuffer.append('t');
          ????????????????????????? break;
          ??????????????? case '\n':outBuffer.append('\\'); outBuffer.append('n');
          ????????????????????????? break;
          ??????????????? case '\r':outBuffer.append('\\'); outBuffer.append('r');
          ????????????????????????? break;
          ??????????????? case '\f':outBuffer.append('\\'); outBuffer.append('f');
          ????????????????????????? break;
          ??????????????? case '=': // Fall through
          ??????????????? case ':': // Fall through
          ??????????????? case '#': // Fall through
          ??????????????? case '!':
          ??????????????????? outBuffer.append('\\'); outBuffer.append(aChar);
          ??????????????????? break;
          ??????????????? default:
          ??????????????????? if ((aChar < 0x0020) || (aChar > 0x007e)) {
          ??????????????????????? outBuffer.append('\\');
          ??????????????????????? outBuffer.append('u');
          ??????????????????????? outBuffer.append(toHex((aChar >> 12) & 0xF));
          ??????????????????????? outBuffer.append(toHex((aChar >>? 8) & 0xF));
          ??????????????????????? outBuffer.append(toHex((aChar >>? 4) & 0xF));
          ??????????????????????? outBuffer.append(toHex( aChar??????? & 0xF));
          ??????????????????? } else {
          ??????????????????????? outBuffer.append(aChar);
          ??????????????????? }
          ??????????? }
          ??????? }
          ??????? return outBuffer.toString();
          ??? }
          ???
          ??? /**
          ???? * 從 Unicode 碼轉(zhuǎn)換成編碼前的特殊字符串。
          ???? * @param in Unicode編碼的字符數(shù)組。
          ???? * @param off 轉(zhuǎn)換的起始偏移量。
          ???? * @param len 轉(zhuǎn)換的字符長(zhǎng)度。
          ???? * @param convtBuf 轉(zhuǎn)換的緩存字符數(shù)組。
          ???? * @return 完成轉(zhuǎn)換,返回編碼前的特殊字符串。
          ???? */
          ??? public String fromUnicode(char[] in, int off, int len, char[] convtBuf) {
          ??????? if (convtBuf.length < len) {
          ??????????? int newLen = len * 2;
          ??????????? if (newLen < 0) {
          ??????????????? newLen = Integer.MAX_VALUE;
          ??????????? }
          ??????????? convtBuf = new char[newLen];
          ??????? }
          ??????? char aChar;
          ??????? char[] out = convtBuf;
          ??????? int outLen = 0;
          ??????? int end = off + len;

          ??????? while (off < end) {
          ??????????? aChar = in[off++];
          ??????????? if (aChar == '\\') {
          ??????????????? aChar = in[off++];
          ??????????????? if (aChar == 'u') {
          ??????????????????? // Read the xxxx
          ??????????????????? int value = 0;
          ??????????????????? for (int i = 0; i < 4; i++) {
          ??????????????????????? aChar = in[off++];
          ??????????????????????? switch (aChar) {
          ??????????????????????? case '0':
          ??????????????????????? case '1':
          ??????????????????????? case '2':
          ??????????????????????? case '3':
          ??????????????????????? case '4':
          ??????????????????????? case '5':
          ??????????????????????? case '6':
          ??????????????????????? case '7':
          ??????????????????????? case '8':
          ??????????????????????? case '9':
          ??????????????????????????? value = (value << 4) + aChar - '0';
          ??????????????????????????? break;
          ??????????????????????? case 'a':
          ??????????????????????? case 'b':
          ??????????????????????? case 'c':
          ??????????????????????? case 'd':
          ??????????????????????? case 'e':
          ??????????????????????? case 'f':
          ??????????????????????????? value = (value << 4) + 10 + aChar - 'a';
          ??????????????????????????? break;
          ??????????????????????? case 'A':
          ??????????????????????? case 'B':
          ??????????????????????? case 'C':
          ??????????????????????? case 'D':
          ??????????????????????? case 'E':
          ??????????????????????? case 'F':
          ??????????????????????????? value = (value << 4) + 10 + aChar - 'A';
          ??????????????????????????? break;
          ??????????????????????? default:
          ??????????????????????????? throw new IllegalArgumentException(
          ??????????????????????????????????? "Malformed \\uxxxx encoding.");
          ??????????????????????? }
          ??????????????????? }
          ??????????????????? out[outLen++] = (char) value;
          ??????????????? } else {
          ??????????????????? if (aChar == 't') {
          ??????????????????????? aChar = '\t';
          ??????????????????? } else if (aChar == 'r') {
          ??????????????????????? aChar = '\r';
          ??????????????????? } else if (aChar == 'n') {
          ??????????????????????? aChar = '\n';
          ??????????????????? } else if (aChar == 'f') {
          ??????????????????????? aChar = '\f';
          ??????????????????? }
          ??????????????????? out[outLen++] = aChar;
          ??????????????? }
          ??????????? } else {
          ??????????????? out[outLen++] = (char) aChar;
          ??????????? }
          ??????? }
          ??????? return new String(out, 0, outLen);
          ??? }
          }

          posted @ 2006-10-28 20:53 leon 閱讀(10692) | 評(píng)論 (3)編輯 收藏

          [ad]city8升級(jí)預(yù)告

          9月26日(下周二),city8(www.city8.com)將進(jìn)行一次升級(jí)。

          更新內(nèi)容:

          1、上海的中環(huán)、外環(huán)以內(nèi)的數(shù)據(jù)添加,這樣一來(lái)整個(gè)上海的數(shù)據(jù)就全了,大家想去哪,就可以看到哪了。

          ?2、三維實(shí)景窗口變大,看高樓不那么累了:)

          3、操作按鈕重新設(shè)計(jì),這樣大家可以方便實(shí)現(xiàn)在街道中行走、全屏瀏覽等很酷的體驗(yàn)。

          4、實(shí)景地圖分享:可以方便在地圖添加文字表述,如“我的家”,并通過(guò)msn,qq,blog,論壇等方式與他人分享

          界面先睹為快:

          首頁(yè):
          homepage

          搜索結(jié)果頁(yè)面:
          main search

          posted @ 2006-09-23 14:25 leon 閱讀(477) | 評(píng)論 (2)編輯 收藏

          [tips]Java 中十進(jìn)制十六進(jìn)制相互轉(zhuǎn)換

          // 十進(jìn)制轉(zhuǎn)化為十六進(jìn)制,結(jié)果為C8。
          Integer.toHexString(200);

          // 十六進(jìn)制轉(zhuǎn)化為十進(jìn)制,結(jié)果140。
          Integer.parseInt("8C",16);

          posted @ 2006-09-19 12:02 leon 閱讀(18207) | 評(píng)論 (2)編輯 收藏

          [Image]使用 Java 2D 對(duì)圖像進(jìn)行縮放

          ???? /**
          ?????*?縮放?-?參數(shù)指定目標(biāo)圖縮放比例。
          ?????*?
          @param ?srcImage?源圖像對(duì)象。
          ?????*?
          @param ?xscale?圖像?x?軸(寬度)上的的縮放比例。
          ?????*?
          @param ?yscale?圖像?y?軸(高度)上的的縮放比例。
          ?????*?
          @param ?hints?重新繪圖使用的?RenderingHints?對(duì)象。
          ?????*?
          @return ?縮放后的圖像對(duì)象。
          ?????
          */

          ????
          public ? static ?BufferedImage?scaleJ2D(BufferedImage?srcImage,? double ?xscale,? double ?yscale,?RenderingHints?hints)? {
          ????????
          int ?width? = ?( int )?(( double )?srcImage.getWidth()? * ?xscale);
          ????????
          int ?height? = ?( int )?(( double )?srcImage.getHeight()? * ?yscale);
          ????????
          ????????AffineTransform?affineTransform?
          = ? new ?AffineTransform();
          ????????affineTransform.scale(xscale,?yscale);
          ????????
          if (hints? == ? null ) {
          ????????????hints?
          = ? new ?RenderingHints(RenderingHints.KEY_RENDERING,?RenderingHints.VALUE_RENDER_DEFAULT);
          ????????}

          ????????AffineTransformOp?affineTransformOp?
          = ? new ?AffineTransformOp(?affineTransform,?hints);
          ????????
          ????????BufferedImage?dstImage?
          = ? new ?BufferedImage(width,?height,?srcImage.getType());
          ????????
          ????????
          return ?affineTransformOp.filter(srcImage,?dstImage);
          ????}

          posted @ 2006-08-27 18:41 leon 閱讀(1223) | 評(píng)論 (1)編輯 收藏

          [Image]使用 Java 2D 將彩色圖像轉(zhuǎn)換成灰度圖

          ???? /**
          ?????*?將彩色圖像轉(zhuǎn)換為灰度圖。
          ?????*?
          @param ?srcImage?源彩色圖像。
          ?????*?
          @param ?hints?重新繪圖使用的?RenderingHints?對(duì)象。
          ?????*?
          @return ?目標(biāo)灰度圖。
          ?????
          */

          ????
          public ? static ?BufferedImage?transformGrayJ2D(BufferedImage?srcImage,RenderingHints?hints)? {
          ????????BufferedImage?dstImage?
          = ? new ?BufferedImage(srcImage.getWidth(),?srcImage.getHeight(),?srcImage.getType());
          ????????
          ????????
          if ?(hints? == ? null )? {
          ????????????Graphics2D?g2?
          = ?dstImage.createGraphics();
          ????????????hints?
          = ?g2.getRenderingHints();
          ????????????g2.dispose();
          ????????????g2?
          = ? null ;
          ????????}

          ????????
          ????????ColorSpace?grayCS?
          = ?ColorSpace.getInstance(ColorSpace.CS_GRAY);
          ????????ColorConvertOp?colorConvertOp?
          = ? new ?ColorConvertOp(grayCS,?hints);
          ????????colorConvertOp.filter(srcImage,?dstImage);
          ????????
          ????????
          return ?dstImage;
          ????}

          posted @ 2006-08-27 14:33 leon 閱讀(1623) | 評(píng)論 (0)編輯 收藏

          [Image]使用 Java 2D 取得圖像上指定位置像素的 rgb 顏色分量

          ???? /**
          ?????*?取得圖像上指定位置像素的?rgb?顏色分量。
          ?????*?
          @param ?image?源圖像。
          ?????*?
          @param ?x?圖像上指定像素位置的?x?坐標(biāo)。
          ?????*?
          @param ?y?圖像上指定像素位置的?y?坐標(biāo)。
          ?????*?
          @return ?返回包含?rgb?顏色分量值的數(shù)組。元素?index?由小到大分別對(duì)應(yīng)?r,g,b。
          ?????
          */

          ????
          public ? static ? int []?getRGB(BufferedImage?image, int ?x, int ?y) {
          ????????
          int []?rgb? = ? null ;
          ????????
          ????????
          if (image? != ? null ? && ?x? < ?image.getWidth()? && ?y? < ?image.getHeight()) {
          ????????????rgb?
          = ? new ? int [ 3 ];
          ????????????
          int ?pixel? = ?image.getRGB(x,y);
          ????????????rgb[
          0 ]? = ?(pixel? & ? 0xff0000 )? >> ? 16 ;
          ????????????rgb[
          1 ]? = ?(pixel? & ? 0xff00 )? >> ? 8 ;
          ????????????rgb[
          2 ]? = ?(pixel? & ? 0xff );
          ????????}

          ????????
          ????????
          return ?rgb;
          ????}


          使用這個(gè)方法前需要先將圖像文件從磁盤上讀到一個(gè) java.awt.image.BufferedImage 對(duì)象中,我們可以用 J2SE 包含的 ImageIO 庫(kù)。

          try ? {
          ????BufferedImage?bi?
          = ?ImageIO.read( new ?File( " ?test.jpg? " ));
          }
          ? catch ?(IOException?ex)? {
          ????ex.printStackTrace();
          }

          posted @ 2006-08-16 10:55 leon 閱讀(2964) | 評(píng)論 (0)編輯 收藏

          胃痙攣

          胃痙攣,疼痛,瞬間失去意識(shí)。

          只剩觸覺(jué),全身抽搐,十幾到幾十秒鐘后意識(shí)逐漸清晰,發(fā)現(xiàn)躺在地上。

          后遺癥是身體多處劃傷和脖子扭了。

          人生經(jīng)驗(yàn):一大早不要喝冰可樂(lè)。

          posted @ 2006-07-03 12:06 leon 閱讀(21350) | 評(píng)論 (69)編輯 收藏

          [Download] Java 2 圖形設(shè)計(jì)卷Ⅰ:AWT

          Java2AWT_s.jpg
          Java 2 圖形設(shè)計(jì)卷Ⅰ:AWT
          Graphic Java 1.2 Mastering the JFC Volume Ⅰ:AWT
          [美]David M.Geary 著 馬欣民等譯
          機(jī)械工業(yè)出版社

          http://www.aygfsteel.com/Files/leon/Java2圖形設(shè)計(jì)卷1AWT.rar

          posted @ 2006-06-21 11:07 leon 閱讀(2089) | 評(píng)論 (9)編輯 收藏

          [zt] Swing是MVC設(shè)計(jì)的典范

          不管你的項(xiàng)目是否用到了Swing技術(shù),我都要說(shuō),Swing是一個(gè)設(shè)計(jì)優(yōu)秀的Java包,它充滿了大師的智慧。如果你學(xué)了Java卻連一個(gè)Button還不會(huì)寫,就象你學(xué)習(xí)Visual Basic卻不會(huì)用Button,那可絕對(duì)是不能被原諒的。Swing技術(shù)的應(yīng)用已經(jīng)在國(guó)外大行其道,由于java的免費(fèi)、易學(xué)以及大家對(duì)于java技術(shù)的充分信賴,好多公司早早的就把應(yīng)用程序的一切,從后臺(tái)服務(wù)到前臺(tái)人機(jī)交互界面,統(tǒng)統(tǒng)移到了java開發(fā)上。Swing出現(xiàn)了快10年了,憑借其先進(jìn)的設(shè)計(jì)思想,一直未曾落后于哪種語(yǔ)言的界面開發(fā)技術(shù),使用和理解Swing的設(shè)計(jì)思想,對(duì)軟件開發(fā)者大有裨益。

          Swing的設(shè)計(jì)是MVC的典范。雖然MVC的概念有點(diǎn)泛濫,可是真正能夠理解并熟練掌握、在設(shè)計(jì)和開發(fā)里面自然流露的并不多見。記得用VC++開發(fā)程序時(shí)候,MFC向?qū)б彩巧蒁ocument和View兩個(gè)類,當(dāng)時(shí)一直奇怪為什么這么繞圈子。再看Swing的設(shè)計(jì),則到處充滿了MVC的痕跡。仔細(xì)研究Swing中事件監(jiān)聽、Model-View分離、Renderer/Editor機(jī)制、可插拔的LookAndFeel等機(jī)制,簡(jiǎn)直就是一門藝術(shù),充滿了美感。而如果你非常痛恨這些設(shè)計(jì)并覺(jué)得他們怪異,很可能你是剛從VB或者Delphi轉(zhuǎn)過(guò)來(lái),這些快速開發(fā)工具幫助了你也“害”了你。

          Swing設(shè)計(jì)的不錯(cuò),不過(guò)可能過(guò)度學(xué)術(shù)化的設(shè)計(jì)也使得Swing跑起來(lái)并不靈巧,學(xué)習(xí)難度也大。這客觀上確實(shí)使得Swing一直沒(méi)有被廣泛使用,而且廣受詬病。記得以前“Swing有什么成功的應(yīng)用嗎?”之類的帖子一直是熱門話題。IBM等則趁機(jī)抓住小辮子弄了SWT吸引了不少人,使得Java GUI技術(shù)面臨分裂的危險(xiǎn)。

          不過(guò)隨著JAVA的不斷升級(jí)和優(yōu)化,Swing的速度一直在提高,美觀性也在改善,基于Swing的成功應(yīng)用也越來(lái)越多了。關(guān)于Swing是否消亡或被SWT代替或是否能作桌面應(yīng)用的爭(zhēng)論逐漸少了。不過(guò)喜歡并精通Swing技術(shù)的開發(fā)者,尤其在國(guó)內(nèi),依舊非常少。

          好在情況在轉(zhuǎn)好。Sun正意識(shí)到Eclipse和SWT所帶來(lái)的威脅,下了大力氣發(fā)展NetBeans,其最新版本對(duì)Swing GUI可視化設(shè)計(jì)的支持已經(jīng)超過(guò)了所有對(duì)手,其Rich Client框架也走向成熟,這對(duì)Swing的發(fā)展和應(yīng)用是一個(gè)很大的推動(dòng)。隨著WEB熱潮的減退,人們又更多的開始理性的思考B/S和C/S架構(gòu)的選擇,某些領(lǐng)域Swing技術(shù)已經(jīng)成為首選的解決方案。隨著JGoodies、JIDE、TWaver等優(yōu)秀Swing產(chǎn)品的不斷涌現(xiàn),Swing會(huì)以更快速度在桌面應(yīng)用中普及。




          原文地址http://www.matrix.org.cn/resource/article/44/44417_Swing+MVC.html

          posted @ 2006-06-13 10:28 leon 閱讀(468) | 評(píng)論 (0)編輯 收藏

          [tips] Java中的四舍五入

          Java.lang.Math的round()方法返回的是整型,如果要保留小數(shù)位的話可以先乘以(小數(shù)位數(shù) *? 10),使用Java.lang.Math的round()方法計(jì)算之后再除以(小數(shù)位數(shù) *? 10)。

          ???? /**
          ?????*?浮點(diǎn)數(shù)的四舍五入。
          ?????*?
          @param ?f?float?代表源浮點(diǎn)數(shù)
          ?????*?
          @param ?digits?int?保留的小數(shù)點(diǎn)后位數(shù)
          ?????*?
          @return ?float
          ?????
          */

          ????
          public ? static ? float ?round( float ?f,? int ?digits)? {
          ????????
          float ?offset? = ?1f;
          ????????
          if ?(digits? == ? 0 )? {
          ????????????offset?
          = ?1f;
          ????????}
          ? else ? if ?(digits? > ? 0 )? {
          ????????????offset?
          = ?digits? * ?10f;
          ????????}
          ? else ? if ?(digits? < ? 0 )? {
          ????????????
          return ?f;
          ????????}


          ????????f?
          = ?java.lang.Math.round(f? * ?offset)? / ?offset;
          ????????
          return ?f;
          ????}

          posted @ 2006-06-07 11:50 leon 閱讀(509) | 評(píng)論 (1)編輯 收藏

          縱橫四海

          ?我喜歡的一張海報(bào),一部電影。

          100分鐘的光影,一個(gè)縱橫四海的夢(mèng)。

          英文片名卻叫做《Once A Thief》,曾經(jīng)是個(gè)賊。Once,只一個(gè)單詞,埋葬了所有過(guò)往。


          OnecAThief.jpg

          posted @ 2006-06-03 20:45 leon 閱讀(319) | 評(píng)論 (0)編輯 收藏

          [tips] 獲取當(dāng)前系統(tǒng)的所有可用字體

          ?//?返回一個(gè)數(shù)組,它包含此?GraphicsEnvironment?中所有可用字體的像素級(jí)實(shí)例。
          ?
          Font[]?fonts =?GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();

          //?返回一個(gè)包含此?GraphicsEnvironment?中所有字體系列名稱的數(shù)組,它針對(duì)默認(rèn)語(yǔ)言環(huán)境進(jìn)行了本地化,由?Locale.getDefault()?返回。
          ?
          String fontNames?=??GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

          posted @ 2006-06-03 14:51 leon 閱讀(734) | 評(píng)論 (0)編輯 收藏

          [Image] 讀取數(shù)碼照片中的EXIF信息

          相信大家都有使用數(shù)碼相機(jī)拍照的經(jīng)歷,一張數(shù)碼照片可以包含的內(nèi)容遠(yuǎn)遠(yuǎn)超過(guò)了我們當(dāng)前觀察到的景物,他可能包括攝影時(shí)的光圈、快門、ISO、日期時(shí)間等各種與當(dāng)時(shí)攝影條件相關(guān)的訊息,相機(jī)品牌型號(hào),色彩編碼,拍攝時(shí)錄制的聲音以及全球定位系統(tǒng)(GPS)等信息。這些信息都是存放在一個(gè)叫做Exif的文件里,然后把Exif文件放置在我們熟知的 JPEG/TIFF 文件的頭部,也就是說(shuō) EXIF 信息是鑲嵌在 JPEG/TIFF 圖像文件格式內(nèi)的一組拍攝參數(shù)。

          我在網(wǎng)上找到一個(gè)開源的開發(fā)工具包Metadata-Extractor,使用它可以像ACDSee等圖像軟件一樣讀取數(shù)碼照片的Exif信息。

          我寫了一個(gè)小Demo程序演示通過(guò)使用metadata-extractor-2.2.2讀取數(shù)碼照片的Exif信息并從Exif中讀取圖像縮略圖。
          import?java.io.*;
          import?java.nio.*;
          import?java.nio.channels.*;
          import?java.util.*;

          import?com.drew.imaging.jpeg.*;
          import?com.drew.metadata.*;
          import?com.drew.metadata.exif.*;


          ?
          public?class?ExifExtractor?{
          ??
          public?ExifExtractor()?{
          ??}


          ??
          public?static?void?main(String[]?args)?{
          ????
          try?{
          ??????Metadata?metadata?
          =?JpegMetadataReader.readMetadata(new?File("o_P4140147.JPG.jpg"));

          ??????Iterator?directories?
          =?metadata.getDirectoryIterator();
          ??????
          while?(directories.hasNext())?{
          ????????Directory?directory?
          =?(Directory)?directories.next();

          ????????Iterator?tags?
          =?directory.getTagIterator();
          ????????
          while?(tags.hasNext())?{
          ??????????Tag?tag?
          =?(Tag)?tags.next();

          ??????????
          //?modify?Exif
          //??????????if?(tag.getTagName().equalsIgnoreCase("User?Comment"))?{
          //??????????????????????Directory?exifDirectory?=?metadata.getDirectory(ExifDirectory.class);
          //??????????????????????exifDirectory.setString(tag.getTagType(),?"LeonChen");
          //??????????}

          ??????????
          //?read?thumbnail
          ??????????if?(tag.getTagName().equalsIgnoreCase("Thumbnail?Data"))?{
          ????????????Directory?exifDirectory?
          =?metadata.getDirectory(ExifDirectory.class);

          ????????????
          byte[]?dataBuffer?=?exifDirectory.getByteArray(tag.getTagType());
          ????????????FileChannel?channel?
          =?new?RandomAccessFile(new?File("thumbnail.jpg"),
          ????????????????
          "rw").getChannel();
          ????????????MappedByteBuffer?fileBuffer?
          =?channel.map(FileChannel.MapMode.
          ????????????????READ_WRITE,?
          0,?dataBuffer.length);
          ????????????fileBuffer.put(dataBuffer);
          ????????????fileBuffer.force();
          ????????????channel.close();
          ??????????}


          ??????????
          //?print?exif
          ??????????System.out.println(tag);
          ????????}

          ??????}

          ????}

          ????
          catch?(FileNotFoundException?ex)?{
          ??????ex.printStackTrace();
          ????}

          ????
          catch?(IOException?ex)?{
          ??????ex.printStackTrace();
          ????}

          ????
          catch?(MetadataException?ex)?{
          ??????ex.printStackTrace();
          ????}

          ????
          catch?(JpegProcessingException?ex)?{
          ??????ex.printStackTrace();
          ????}

          ??}

          }


          我在上面的測(cè)試程序里注釋了一段代碼,他們可以在內(nèi)存中修改Exif中某一節(jié)點(diǎn)的信息,但是我不知道怎樣才能將修改后的Exif信息保存到文件,如果你知道方法,請(qǐng)給我留言。

          測(cè)試圖片下載地址:
          http://www.aygfsteel.com/images/blogjava_net/leon/2174/o_P4140147.JPG

          EXIF參考:
          http://www.exif.org

          posted @ 2005-11-29 17:04 leon 閱讀(2595) | 評(píng)論 (5)編輯 收藏

          [Swing] 布局管理器 - OverlayLayout

          OverlayLayout是用于排列重疊組件的布局管理器。它的用途是以一些對(duì)齊的點(diǎn)為基準(zhǔn)將一些組件層疊的放置在布局容器中。

          組件的橫軸和縱軸的對(duì)齊點(diǎn)介于0.0和1.0之間。橫軸(X軸)上0.0代表組件的左側(cè)面,1.0代表組件的右側(cè)面;縱軸(Y軸)上0.0和1.0分別代表組件的頂部和底部。

          構(gòu)造函數(shù)
          public OverlayLayout(Container target)

          因?yàn)闃?gòu)造函數(shù)不會(huì)為target對(duì)象安裝結(jié)果布局管理器,所以我們還必須調(diào)用setLayout()來(lái)完成此功能。
          JPanel p1 = new JPanel();
          OverlayLayout overlay 
          = new OverlayLayout(p1);
          p1.setLayout(overlay); 

          在OverlayLayout布局管理器中,每個(gè)組件都有一對(duì)橫縱坐標(biāo)值,每個(gè)組件的位置只和它本身的橫縱坐標(biāo)值有關(guān),換句話說(shuō)就是組件以他自己的位置作為基準(zhǔn),橫軸上0.0和1.0分別代表組件的左側(cè)面和右側(cè)面;縱軸上0.0和1.0分別代表組件的頂部和底部,和容器位置無(wú)關(guān)。如果一個(gè)組件的alignmentX屬性設(shè)置為0.5,原本左側(cè)面的位置對(duì)應(yīng)0.0,現(xiàn)在變成了0.5,那么,現(xiàn)在組件的位置就要向左移動(dòng)width/2的距離,使左側(cè)面的位置對(duì)應(yīng)現(xiàn)在的0.0。縱軸亦是如此,明白了嗎?

          為了容易理解,我們來(lái)看《Java Swing》中關(guān)于OverlayLayout的一段樣例程序,它可以編譯運(yùn)行。如圖,你可以在輸入框中調(diào)節(jié)容器中3個(gè)按鈕的X,Y軸的值來(lái)看他們?cè)谌萜髦械奈恢檬窃鯓痈淖兊模嘣噹状危憔涂梢酝耆斫釵verlayLayout。

          OverlayTest.jpg
          // OverlayTest.java
          // A test of the OverlayLayout manager allowing experimentation.
          //

          import java.awt.*;
          import java.awt.event.*;
          import javax.swing.*;

          public class OverlayTest extends JFrame {

              
          public OverlayTest() {
                  
          super("OverlayLayout Test");
                  setSize(
          500300);
                  setDefaultCloseOperation(EXIT_ON_CLOSE);

                  
          final Container c = getContentPane();
                  c.setLayout(
          new GridBagLayout());

                  
          final JPanel p1 = new GridPanel();
                  
          final OverlayLayout overlay = new OverlayLayout(p1);
                  p1.setLayout(overlay);

                  
          final JButton jb1 = new JButton("B1");
                  
          final JButton jb2 = new JButton("B2");
                  
          final JButton jb3 = new JButton("B3");

                  Dimension b1 
          = new Dimension(6050);
                  Dimension b2 
          = new Dimension(8040);
                  Dimension b3 
          = new Dimension(10060);

                  jb1.setMinimumSize(b1);
                  jb1.setMaximumSize(b1);
                  jb1.setPreferredSize(b1);
                  jb2.setMinimumSize(b2);
                  jb2.setMaximumSize(b2);
                  jb2.setPreferredSize(b2);
                  jb3.setMinimumSize(b3);
                  jb3.setMaximumSize(b3);
                  jb3.setPreferredSize(b3);

                  SimpleReporter reporter 
          = new SimpleReporter();
                  jb1.addActionListener(reporter);
                  jb2.addActionListener(reporter);
                  jb3.addActionListener(reporter);

                  p1.add(jb1);
                  p1.add(jb2);
                  p1.add(jb3);

                  JPanel p2 
          = new JPanel();
                  p2.setLayout(
          new GridLayout(2,6));
                  p2.add(
          new JLabel("B1 X", JLabel.CENTER));
                  p2.add(
          new JLabel("B1 Y", JLabel.CENTER));
                  p2.add(
          new JLabel("B2 X", JLabel.CENTER));
                  p2.add(
          new JLabel("B2 Y", JLabel.CENTER));
                  p2.add(
          new JLabel("B3 X", JLabel.CENTER));
                  p2.add(
          new JLabel("B3 Y", JLabel.CENTER));
                  p2.add(
          new JLabel(""));

                  
          final JTextField x1 = new JTextField("0.0"4); // Button1 x alignment
                  final JTextField y1 = new JTextField("0.0"4); // Button1 y alignment
                  final JTextField x2 = new JTextField("0.0"4); 
                  
          final JTextField y2 = new JTextField("0.0"4); 
                  
          final JTextField x3 = new JTextField("0.0"4); 
                  
          final JTextField y3 = new JTextField("0.0"4); 

                  p2.add(x1);
                  p2.add(y1);
                  p2.add(x2);
                  p2.add(y2);
                  p2.add(x3);
                  p2.add(y3);


                  GridBagConstraints constraints 
          = new GridBagConstraints();
                  c.add(p1, constraints);

                  constraints.gridx 
          = 1;
                  JButton updateButton 
          = new JButton("Update");
                  updateButton.addActionListener(
          new ActionListener() {
                      
          public void actionPerformed(ActionEvent ae) {
                          jb1.setAlignmentX(
                              Float.valueOf(x1.getText().trim()).floatValue());
                          jb1.setAlignmentY(
                              Float.valueOf(y1.getText().trim()).floatValue());
                          jb2.setAlignmentX(
                              Float.valueOf(x2.getText().trim()).floatValue());
                          jb2.setAlignmentY(
                              Float.valueOf(y2.getText().trim()).floatValue());
                          jb3.setAlignmentX(
                              Float.valueOf(x3.getText().trim()).floatValue());
                          jb3.setAlignmentY(
                              Float.valueOf(y3.getText().trim()).floatValue());

                          p1.revalidate();
                      }

                  }
          );
                  c.add(updateButton, constraints);

                  constraints.gridx 
          = 0;
                  constraints.gridy 
          = 1;
                  constraints.gridwidth 
          = 2;
                  c.add(p2, constraints);
              }


              
          public static void main(String args[]) {
                  OverlayTest ot 
          = new OverlayTest();
                  ot.setVisible(
          true);
              }


              
          public class SimpleReporter implements ActionListener {
                  
          public void actionPerformed(ActionEvent ae) {
                      System.out.println(ae.getActionCommand());
                  }

              }


              
          public class GridPanel extends JPanel {
                  
          public void paint(Graphics g) {
                      
          super.paint(g);
                      
          int w = getSize().width;
                      
          int h = getSize().height;

                      g.setColor(Color.red);
                      g.drawRect(
          0,0,w-1,h-1);
                      g.drawLine(w
          /2,0,w/2,h);
                      g.drawLine(
          0,h/2,w,h/2);
                  }

              }

          }



          最后提醒,使用OverlayLayout布局管理器關(guān)鍵要記住X,Y軸對(duì)應(yīng)組件位置,和容器沒(méi)有關(guān)系。只要明白這一點(diǎn),使用還是很簡(jiǎn)單方便的,我用OverlayLayout布局管理器clone了一個(gè)PhotoShop的工具面板。
          ToolWidget.jpg

          posted @ 2005-11-02 23:08 leon 閱讀(3871) | 評(píng)論 (0)編輯 收藏

          [Image] 將屏幕截圖保存成圖像文件

          import ?java.io. * ;
          import ?java.awt. * ;
          import ?java.awt.image. * ;
          import ?javax.imageio. * ;

          public ? class ?CropScreen? {
          ??
          public ? static ? void ?main(String[]?args)? {
          ????
          try ? {
          ??????Toolkit?toolkit?
          = ?Toolkit.getDefaultToolkit();
          ??????Dimension?screenSize?
          = ?toolkit.getScreenSize();
          ??????Rectangle?screenRect?
          = ? new ?Rectangle(screenSize);

          ??????Robot?robot?
          = ? new ?Robot();
          ??????BufferedImage?image?
          = ?robot.createScreenCapture(screenRect);
          ??????ImageIO.write(image,?
          " jpg " ,? new ?File( " screen.jpg " ));
          ????}

          ????
          catch ?(Exception?ex)? {
          ??????ex.printStackTrace();
          ????}

          ??}

          }

          posted @ 2005-10-26 11:39 leon 閱讀(1268) | 評(píng)論 (0)編輯 收藏

          [Image] 使用JAI將實(shí)現(xiàn)RenderedImage接口的圖像對(duì)象序列化

          我們都知道,圖像對(duì)象可以編碼成指定圖像格式文件保存在硬盤上,需要時(shí)再對(duì)其進(jìn)行解碼讀入內(nèi)存。但是除了這樣還有別的辦法可以將圖像對(duì)象保存在硬盤上嗎?熟悉Java I/O 的人也許可以想到采用對(duì)象序列化(Object serialization)試一試,很好,但是如果你研究了 BufferedImage?類的結(jié)構(gòu)后就會(huì)大失所望(至少當(dāng)時(shí)我是這樣)。
          BufferedImage.jpg

          BufferedImage?提供一般圖像管理。BufferedImage 對(duì)象包括另外兩個(gè)對(duì)象:Raster 和 ColorModel。Raster 對(duì)象包含另外兩個(gè)對(duì)象:DataBuffer 和 SampleModel。不幸的是,他們都沒(méi)有實(shí)現(xiàn)序列化所必需的 Serializable 接口,所以無(wú)法直接對(duì)他們進(jìn)行對(duì)象序列化。

          我在學(xué)習(xí) JAI 的時(shí)候發(fā)現(xiàn)了 javax.media.jai.remote 包里有一個(gè)類 SerializableRenderedImage,這個(gè)類實(shí)現(xiàn)了RenderedImage, Serializable 接口,可以將 RanderedImage 對(duì)象作為構(gòu)造函數(shù)的參數(shù)實(shí)例化一個(gè)可以序列化的圖像對(duì)象。

          javax.media.jai.remote.SerializableRenderedImage

          public final class SerializableRenderedImage
          extends Object
          implements RenderedImage, Serializable

          SerializableRenderedImage(RenderedImage?source)
          ??????????Constructs a SerializableRenderedImage wrapper for a RenderedImage source.
          SerializableRenderedImage(RenderedImage?source, boolean?useDeepCopy)
          ??????????Constructs a SerializableRenderedImage wrapper for a RenderedImage source.
          SerializableRenderedImage(RenderedImage?source, boolean?useDeepCopy, OperationRegistry?registry, String?formatName, TileCodecParameterList?encodingParam, TileCodecParameterList?decodingParam)
          ??????????Constructs a SerializableRenderedImage wrapper for a RenderedImage source.

          查看JDK的文檔可以知道無(wú)論 Java 2D 中的 BufferedImage 還是 JAI 中的 PlanarImage 都實(shí)現(xiàn)自 RenderedImage 接口,也就是說(shuō)所有實(shí)現(xiàn)自 RenderedImage 接口的對(duì)象均可作為參數(shù)包裝出一個(gè) SerializableRenderedImage 類型對(duì)象,將其序列化。

          下面是一個(gè)簡(jiǎn)單的例子說(shuō)明了這個(gè)類的使用方法:

          import?java.io.*;
          import?javax.media.jai.remote.*;

          import?java.awt.image.*;

          public?class?SomeSerializableClass
          ????
          implements?Serializable?{
          ??
          protected?transient?RenderedImage?image;

          ??
          //?Fields?omitted.

          ??
          public?SomeSerializableClass(RenderedImage?image)?{
          ????
          this.image?=?image;
          ??}


          ??
          //?Methods?omitted.

          ??
          //?Serialization?method.
          ??private?void?writeObject(ObjectOutputStream?out)?throws?IOException?{
          ????out.defaultWriteObject();
          ????out.writeObject(
          new?SerializableRenderedImage(image,?true));
          ??}


          ??
          //?Deserialization?method.
          ??private?void?readObject(ObjectInputStream?in)?throws?IOException,
          ??????ClassNotFoundException?
          {
          ????in.defaultReadObject();
          ????image?
          =?(RenderedImage)?in.readObject();
          ??}

          }

          posted @ 2005-10-18 17:36 leon 閱讀(2842) | 評(píng)論 (1)編輯 收藏

          [Image] AWT使用ImageProducer/ImagConsumer模式加載和顯示圖像的原理

          以前寫過(guò)2篇關(guān)于AWT中圖像加載顯示方法的文章,最近又多了一些對(duì)于 ImageProducer / ImagConsumer 模式的一些理解,嘗試著用文字總結(jié)了一下,接著還想再寫一篇介紹 AWT 中圖像過(guò)濾的原理和方法。你可能認(rèn)為現(xiàn)在學(xué)習(xí) AWT 中的成像方法對(duì)于開發(fā)中已經(jīng)沒(méi)有太大的意義,因?yàn)橐呀?jīng)有了 Java 2D 和 JAI ,但是我在實(shí)際工作中感到還是無(wú)法完全離開 AWT,特別是在一些基本的應(yīng)用上。而且我覺(jué)得理解 AWT 的 Producer / Consumer (push) model 對(duì)于理解 Java 2D 的 Immediate mode model 和 JAI 的 Pipeline (pull) model 的都是有好處的。

          因?yàn)樗接邢蓿@方面學(xué)習(xí)資料相對(duì)也不豐富,我也不知道我的理解或想法是否完全正確或者表述清楚,感興趣的朋友可以當(dāng)作學(xué)習(xí)參考,希望能夠和我聯(lián)系進(jìn)行進(jìn)一步的討論。



          AWT 使用 ImageProducer / ImagConsumer 模式,支持加載和顯示 GIF 圖像文件格式和 JPEG 圖像文件格式。因?yàn)閳D像的加載和顯示是異步方式進(jìn)行的,所以有大量加載和顯示的技術(shù)。

          在 AWT 中,提供了一個(gè) java.awt.Image 類。java.awt.Image 類代表一個(gè)圖像對(duì)象被作為參數(shù)傳遞給其他用來(lái)顯示和處理圖像的其他 AWT 對(duì)象使用。例如,通過(guò)調(diào)用 Graphics.drawImage(java.awt.Image, int, int, ImageObserver) 方法,可以在組件中畫出圖像。

          java.awt.Image 是一個(gè)定義方法的抽象類,它定義的方法提供的對(duì)圖像信息的訪問(wèn)。而創(chuàng)建和處理圖像的基本結(jié)構(gòu)則在 java.awt.image 包中。注意,這里不要和 java.awt.Image 發(fā)生混淆。

          AWT? 加載和顯示圖像使用的是 ImageProducer / ImagConsumer 模式,我們必須了解3個(gè)術(shù)語(yǔ),ImageProducer(圖像生產(chǎn)者),ImageConsumer(圖像消費(fèi)者)和ImageObserver(圖像觀察者)。

          ImageProducer 負(fù)責(zé)生產(chǎn)圖像的位,ImagConsumer 接受圖像的位,ImageObserver 監(jiān)視 ImageProducer 的圖像生產(chǎn)過(guò)程。ImageProducer 生產(chǎn)傳遞給 ImagConsumer 與圖像相關(guān)的位。因?yàn)閳D像生產(chǎn)過(guò)程是異步進(jìn)行的,并不是一次性生產(chǎn)所有圖像位,所以當(dāng) ImageProducer 加載圖像時(shí),ImageObserver 用來(lái)監(jiān)視它的進(jìn)展情況。因?yàn)?java.awt.Component 實(shí)現(xiàn)了 ImageObserver 接口,所以 AWT 中的每個(gè)組件都可以是ImageObserver,當(dāng)一個(gè)給定的 ImageProducer 進(jìn)行異步操作時(shí),這個(gè) ImageObserver 可以選擇是否被更新。java.awt.image 包為 ImageProducer,ImagConsumer 和 ImageObserver 都定義了接口。

          ImageProducer
          和圖像相關(guān)的位并不存儲(chǔ)在 java.awt.Image 中,每個(gè)圖像都維護(hù)一個(gè)和一個(gè) ImageProducer?的關(guān)聯(lián)。這個(gè) ImageProducer?的責(zé)任是生產(chǎn)圖像的位并將它們傳送給 ImagConsumer,用于過(guò)濾該圖像。

          java.awt.image軟件包中,F(xiàn)ilteredImageSource(被過(guò)濾的圖像源)和 MemoryImageSource(內(nèi)存的圖像源)實(shí)現(xiàn)了 ImageProducer? 接口,是 ImageProducer?。


          ImagConsumer
          java.awt.image軟件包中,ImageFilter(圖像過(guò)濾器)和 PixelGrabber(像素抓取器)實(shí)現(xiàn)了 ImagConsumer 接口,是 ImagConsumer。


          ImageProducer?和 ImagConsumer 的詳細(xì)介紹請(qǐng)閱讀 使用 ImageProducer? / ImagConsumer 進(jìn)行圖像過(guò)濾


          ImageObserver
          ImageObserver接口中,定義了一個(gè)常數(shù)集合和一個(gè)方法:

          public boolean imageUpdate(image img, int flags, int x, int y, int width, int height);

          ImageObserver的常數(shù)
          標(biāo)志 含義
          ABORT 圖像加載被中斷
          ALLBITS 所有的位都已加載給圖像
          ERROR 在加載過(guò)程中發(fā)生錯(cuò)誤
          FRAMEBITS 多幀圖像的一個(gè)幀被傳送,一般用于GIF
          HEIGHT 圖像的高度已經(jīng)可用
          PROPERTIES 圖像的屬性已經(jīng)可用
          SOMEBITS 圖像的縮放變體的多個(gè)位已經(jīng)可用
          WIDTH 圖像的寬度已經(jīng)可用

          參數(shù) flags 的作用是通知圖像觀察者圖像生產(chǎn)的進(jìn)展情況。這些常數(shù)代表傳遞給 ImageObserver.imageUpdate() 的 flags 參數(shù)中的位。

          當(dāng) Component 作為 ImageObserver 時(shí),一旦圖像有新的部分被加載,就會(huì)調(diào)用 Component.imageUpdate() 方法,imageUpdate() 再調(diào)用 repaint() 重新繪制圖像。repaint() 將先調(diào)用 update() 方法清除組件背景,再由 update() 方法調(diào)用 paint() 方法繪制圖像。我們可以通過(guò)重載 imageUpdate() 方法控制組件何時(shí)被更新,重載 update() 方法控制是否每次重繪都要清除背景圖像(每次重繪都清除背景圖像會(huì)造成畫面閃爍)。


          為了更好的理解,下面我們來(lái)看幾個(gè)樣例程序:

          例1,圖像位在需要之前不被生產(chǎn)

          import?java.net.URL;
          import?java.applet.Applet;
          import?java.awt.Graphics;
          import?java.awt.Image;

          public?class?ImageTestAppletSimple?extends?Applet{
          ????
          private?Image?im;
          ????
          ????
          public?void?init(){
          ????????URL?codebase?
          =?getCodeBase();
          ????????System.out.println(codebase);
          ????????
          ????????im?
          =?getImage(codebase,"flower.jpg");
          ????????
          ????????System.out.print(
          "Image?width?=?"?+?im.getWidth(this));
          ????????System.out.println(
          " hight?=?"?+?im.getHeight(this));
          ????}

          ????
          ????
          public?void?paint(Graphics?g){
          ????????g.drawImage(im,
          0,0,this);
          ????}

          }

          輸出結(jié)果:
          image width = -1 height = -1

          圖像的高度和寬度只有在圖像被完全加載后才是有效的,輸出結(jié)果說(shuō)明 java.awt.image 相關(guān)的圖像位在需要之前不被生產(chǎn)。


          例2,圖像異步生產(chǎn)

          import?java.net.URL;
          import?java.applet.Applet;
          import?java.awt.Graphics;
          import?java.awt.Image;

          public?class?ImageTestAppletSimple2?extends?Applet{
          ????
          private?Image?im;
          ????
          ????
          public?void?init(){
          ????????im?
          =?getImage(getCodeBase(),"flower.jpg");
          ????}

          ????
          ????
          public?void?paint(Graphics?g){
          ????????System.out.println(
          "drawing?image...");
          ????????System.out.println(g.drawImage(im,
          0,0,this));
          ????}

          }

          輸出結(jié)果:
          drawing?image...
          false
          drawing?image...
          false
          drawing?image...
          false
          drawing?image...
          true

          輸出結(jié)果說(shuō)明組件作為 ImageObserver ,監(jiān)視 ImageProducer 異步生產(chǎn)圖像,一旦有新的圖像位被生產(chǎn)時(shí)就重繪圖像,圖像完全加載后 drawImage() 方法返回 true。


          例3,重載 ImageObserver 的 imageUpdate() 方法,在圖像完全加載前不調(diào)用 repaint()

          import?java.applet.Applet;
          import?java.awt.Graphics;
          import?java.awt.Image;

          public?class?ImageTestAppletWithUpdate?extends?Applet{
          ????
          private?Image?im;
          ????
          ????
          public?void?init(){
          ????????im?
          =?getImage(getCodeBase(),"flower.jpg");
          ????????
          ????????System.out.print(
          "Image?width?=?"?+?im.getWidth(this));
          ????????System.out.println(
          "hight?=?"?+?im.getHeight(this));
          ????}

          ????
          ????
          public?void?paint(Graphics?g){
          ????????g.drawImage(im,
          0,0,this);
          ????}

          ????
          ????
          public?boolean?imageUpdate(Image?image,int?flags,int?x,int?y,int?w,int?h){
          ????????System.out.println(
          "imageUpdate():x="?+?x?+?",y="?+?y?+?",w="?+?w?+?",h="?+?h);
          ????????
          ????????
          if((flags?&?ALLBITS)?==?0)
          ????????????
          return?true;
          ????????
          else
          ????????
          {
          ????????????repaint();
          ????????????
          return?false;
          ????????}

          ????}

          }



          例4,重載? Component.update() 方法,被調(diào)用時(shí)不清除背景圖像,直接調(diào)用 paint() 方法繪制圖像,消除閃爍

          import?java.applet.Applet;
          import?java.awt.Graphics;
          import?java.awt.Image;

          public?class?ImageTestAppletWithSmoothDynamicUpdate?extends?Applet{
          ????
          private?Image?im;
          ????
          ????
          public?void?init(){
          ????????im?
          =?getImage(getCodeBase(),"hl.jpg");
          ????????
          ????????System.out.print(
          "Image?width?=?"?+?im.getWidth(this));
          ????????System.out.println(
          "hight?=?"?+?im.getHeight(this));
          ????}

          ????
          ????
          public?void?paint(Graphics?g){
          ????????g.drawImage(im,
          0,0,this);
          ????}

          ????
          ????
          public?boolean?imageUpdate(Image?image,int?flags,int?x,int?y,int?w,int?h){
          ????????System.out.println(
          "imageUpdate():x="?+?x?+?",y="?+?y?+?",w="?+?w?+?",h="?+?h);
          ????????
          ????????repaint();
          ????????
          ????????
          if((flags?&?ALLBITS)?==?0)
          ????????????
          return?true;
          ????????
          else
          ????????????
          return?false;
          ????}

          ????
          ????
          public?void?update(Graphics?g){
          ????????paint(g);
          ????}

          }

          ?

          posted @ 2005-10-11 10:35 leon 閱讀(2633) | 評(píng)論 (3)編輯 收藏

          [Download] Java 2D API 程序員指南

          Programmer's Guide to the JavaTM 2D API 中文版

          http://www.aygfsteel.com/Files/leon/Java2DAPI程序員指南.rar

          posted @ 2005-09-13 17:09 leon 閱讀(2322) | 評(píng)論 (5)編輯 收藏

          導(dǎo)航

          統(tǒng)計(jì)

          公告

          DSC_0106.jpg
          本博客已經(jīng)搬家到CSDN
          http://blog.csdn.net/chenweionline




          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          About Technology

          My Favorite Website

          搜索

          積分與排名

          最新評(píng)論

          • 1.?re: 胃痙攣
          • 兄弟們你們都做胃鏡了嗎開的啥藥?有什么養(yǎng)胃秘方啊?請(qǐng)賜教啊!
          • --我也進(jìn)來(lái)了
          • 2.?re: 胃痙攣
          • @痛啊
            我感覺(jué)比生孩子還疼,生孩子還能有意識(shí)呢!這種疼還叫不出來(lái)連說(shuō)話的力氣都沒(méi)了
          • --我也進(jìn)來(lái)了
          • 3.?re: 胃痙攣
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --我也進(jìn)來(lái)了
          • 4.?re: 胃痙攣
          • 我都周期性的發(fā)作,算來(lái)有4年了 。每年最少一次,一次最少2天。吃了好多藥就差沒(méi)去做胃鏡了。 剛剛發(fā)作就隨便煮了點(diǎn)姜湯喝下就好了些,不知道還會(huì)不會(huì)發(fā)作了。
          • --許家洛
          • 5.?re: 胃痙攣
          • 我昨晚也疼的要死。。上次疼的直接120送醫(yī)院了,一上120我竟然就不疼了,醫(yī)院里掉了瓶鹽水就放回家了。這次正好國(guó)外旅游中,幾乎疼了一整晚,整個(gè)在床上翻滾狀態(tài)了。今天不疼了,就是整個(gè)人難受。。。求助阿
          • --胃疼
          • 6.?re: [Swing]在 JFileChooser 中進(jìn)行文件驗(yàn)證的小技巧
          • 輸入*還是會(huì)有問(wèn)題
          • --ngh
          • 7.?re: 胃痙攣[未登錄](méi)
          • 昨晚一夜的身不如死的感覺(jué),胃痙攣兄不要來(lái)了吧 ,求你了
          • --李飛
          • 8.?re: 胃痙攣
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --daidai
          • 9.?re: 胃痙攣
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --痛啊
          • 10.?re: 胃痙攣
          • 媽啊 痛的快死了~!第一次感覺(jué)過(guò)這樣的痛啊~!和女的生孩子有的一比了吧~!哭哭哭~!
          • --痛啊

          閱讀排行榜

          主站蜘蛛池模板: 全南县| 古丈县| 榆中县| 甘谷县| 南澳县| 呼玛县| 晋宁县| 于田县| 澎湖县| 蒲城县| 天水市| 米泉市| 绵阳市| 桂林市| 大悟县| 龙海市| 锦州市| 噶尔县| 洞口县| 兴化市| 镇宁| 汝南县| 富裕县| 长白| 乐平市| 游戏| 明水县| 大悟县| 桐梓县| 鄂温| 洮南市| 玉林市| 泰来县| 福州市| 威远县| 仪陇县| 泸溪县| 滨州市| 丰台区| 芷江| 巴青县|