<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    sunfruit[請(qǐng)?jiān)L問(wèn)http://www.fruitres.cn]

    --我相信JAVA能走得更遠(yuǎn) QQ:316228067

    2006年7月19日 #

    Linux Enterprise 5 安裝Oracle出現(xiàn)ins_rdbms.mk錯(cuò)誤的解決辦法

        --sunfruit

        在Linux Enterprise 5安裝Oracle的時(shí)候有時(shí)候會(huì)報(bào)錯(cuò)例如“makefile '/oracle/product/10.2.0/db_1/rdbms/lib/ins_rdbms.mk' 的目標(biāo) 'all_no_orcl' 時(shí)出錯(cuò)”

        經(jīng)過(guò)多次測(cè)試是缺少相關(guān)的系統(tǒng)包文件,至少我的環(huán)境中確實(shí)是這樣,只要是安裝了下面的包文件,這個(gè)錯(cuò)誤可以避免(版本號(hào)在不同環(huán)境中略有不同)

        compat-libstdc++-33-3.2.3-61
        compat-libstdc++-296-2.96-138
        gcc-4.1.1-52.el5
        gcc-c++-4.1.1-52.el5
        glibc-2.5-12
        glibc-common-2.5-12
        glibc-devel-2.5-12
        glibc-headers-2.5-12
        libgcc-4.1.1-52.el5
        make-3.81-1.1
        binutils-2.17.50.0.6-2.el5
        openmotif-2.3.0-0.3.el5

        以上的安裝包由于在安裝Linux的選擇的包以及具體的環(huán)境不同可能,可能有些不需要,不過(guò)如果出現(xiàn)了ins_rdbms.mk的錯(cuò)誤,可以按照這個(gè)方法嘗試一下

        注:以上的安裝在Linux Enterprise 5的安裝盤中都包含,不需要額外在網(wǎng)上下載

    posted @ 2008-09-12 09:18 sunfruit 閱讀(5422) | 評(píng)論 (1)編輯 收藏

    Linux Enterprise 5安裝Oracle10g,Oracle10g字符集設(shè)置問(wèn)題

        -sunfruit

        如果在安裝Oracle10g的時(shí)候沒(méi)有選擇字符集,則按照下面的3部進(jìn)行字符集的修改就可以完全正常的使用Oracle10g(注:關(guān)于下面的1、2、3均是轉(zhuǎn)貼,后面添加了個(gè)人在使用的時(shí)候一些心得)
       

    1、檢查服務(wù)器上Oracle數(shù)據(jù)庫(kù)的字符集   
        sqlplus /nolog
      SQL>  connect / as sysdba
      連接成功.   
       
      SQL>  desc  props$   
        列名                                                    可空值否      類型   
        -------------------------------  --------  ----   
        NAME                                                        NOT  NULL  VARCHAR2(30)   
        VALUE$                                                                      VARCHAR2(2000)   
        COMMENT$                                                                  VARCHAR2(2000)   
       
      SQL>  col  value$  format  a40   
      SQL>  select  name,value$  from  props$;   
       
      NAME                                                      VALUE$   
      ------------------------------  -------------------------   
      DICT.BASE                                            2   
      NLS_LANGUAGE                                      AMERICAN   
      NLS_TERRITORY                                    AMERICA   
      NLS_CURRENCY                                      $   
      NLS_ISO_CURRENCY                              AMERICA   
      NLS_NUMERIC_CHARACTERS                  .,   
      NLS_DATE_FORMAT                                DD-MON-YY   
      NLS_DATE_LANGUAGE                            AMERICAN   
      NLS_CHARACTERSET                              ZHS16GBK   
      NLS_SORT                                              BINARY   
      NLS_CALENDAR                                      GREGORIAN   
      NLS_RDBMS_VERSION                            7.3.4.0.0   
      GLOBAL_DB_NAME                                  ORACLE.WORLD   
      EXPORT_VIEWS_VERSION                      3   
       
       
       
      NLS_CHARACTERSET和NLS_CHAR_CTERSET這個(gè)參數(shù)應(yīng)該是ZHS16GBK,如不是,改為它。   
       
      SQL*Plus中修改方法:   
      SQL>  update  props$  set  value$='ZHS16GBK'  where  name='NLS_CHARACTERSET'; 


    2、確認(rèn)字符集是否修改的不徹底。
      SELECT DISTINCT (NLS_CHARSET_NAME(CHARSETID)) CHARACTERSET,
      DECODE(TYPE#, 1,
      DECODE(CHARSETFORM, 1, 'VARCHAR2', 2, 'NVARCHAR2', 'UNKOWN'),
      9,
      DECODE(CHARSETFORM, 1, 'VARCHAR', 2, 'NCHAR VARYING', 'UNKOWN'),
      96,
      DECODE(CHARSETFORM, 1, 'CHAR', 2, 'NCHAR', 'UNKOWN'),
      112,
      DECODE(CHARSETFORM, 1, 'CLOB', 2, 'NCLOB', 'UNKOWN')) TYPES_USED_IN
      FROM SYS.COL$
      WHERE CHARSETFORM IN (1, 2)
      AND TYPE# IN (1, 9, 96, 112);

    3、如果上面的查詢的確顯示有多個(gè)字符集的設(shè)定,則進(jìn)行如下處理:
      SHUTDOWN IMMEDIATE;
      STARTUP MOUNT;
      ALTER SYSTEM ENABLE RESTRICTED SESSION;
      ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
      ALTER SYSTEM SET AQ_TM_PROCESSES=0;
      ALTER DATABASE OPEN;

      COL VALUE NEW_VALUE CHARSET
      SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
      COL VALUE NEW_VALUE NCHARSET
      SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_NCHAR_CHARACTERSET';

      --INTERNAL_USE是沒(méi)有寫在文檔中的參數(shù),用以強(qiáng)制完成字符集一致化
      ALTER DATABASE CHARACTER SET INTERNAL_USE &CHARSET;
      ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE &NCHARSET;

      SHUTDOWN IMMEDIATE;
      STARTUP;
      -- 再次啟動(dòng)數(shù)據(jù)庫(kù)一遍
      SHUTDOWN IMMEDIATE;
      STARTUP;

    **************注意****************
    本人在使用上面的方法設(shè)置以后Oracle10g可以正常使用,在導(dǎo)入dmp,sql文件的時(shí)候則需要在Linux中做如下設(shè)置
    sql文件,dmp文件在導(dǎo)入oracle的時(shí)候需要設(shè)置字符集

    export LANG=zh_CN.GBK    //這個(gè)是linux的字符集設(shè)置
    export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK   //這個(gè)是oracle的字符集設(shè)置

    posted @ 2008-09-12 09:09 sunfruit 閱讀(2318) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]Applet上疊加層的解決方案(非div)

        --sunfruit

        在applet上疊加層有2種方式
        第一:使用iframe的方式
        第二:使用window.createPopup();方式

        <div></div>的方式我是沒(méi)有試成功,無(wú)論如何設(shè)置,div都在applet的下面,要是哪位實(shí)驗(yàn)成功了,經(jīng)驗(yàn)也共享一下

        由于window.createPopup()主要用于創(chuàng)建右鍵菜單,由于其的一些特性,例如在其他地方點(diǎn)擊,該window.createPopup()對(duì)象消失,所以疊加層方式使用window.createPopup()并不合適,使用iframe制作疊加層的效果更好更好

        效果圖如下
        
        
        演示:http://www.fruitres.cn/applet.jsp,可以從該演示頁(yè)直接下載js代碼,或者到代碼下載頁(yè)下載
        代碼下載:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1084563770&number=0 
        更多下載:http://www.fruitres.cn/

    posted @ 2007-12-29 15:36 sunfruit 閱讀(956) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用JAVA開(kāi)發(fā)不規(guī)則滾動(dòng)條

        --sunfruit

        在GIS網(wǎng)站上一般都會(huì)看到下面的滾動(dòng)條,俗稱骨頭棒或是排骨架,當(dāng)然這個(gè)是WEB方式
         

        如果是應(yīng)用程序或是Applet該如何制作呢,其實(shí)也不復(fù)雜,只是需要靈活運(yùn)用Swing的特性,下面是一個(gè)Application的demo
       

        看似復(fù)雜,其實(shí)如果理解了也沒(méi)有什么神秘

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1342916853&number=0
        JAVA WEB START演示地址:http://www.fruitres.cn/useruploadfile/3/1342916853_jnlp.jnlp
        更多下載:http://www.fruitres.cn/

    posted @ 2007-12-29 12:56 sunfruit 閱讀(484) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用ArcIMS引擎繪制地圖基礎(chǔ)代碼

        --sunfruit 

        代碼演示了基于ArcIMS開(kāi)發(fā)包進(jìn)行地圖開(kāi)發(fā)的基礎(chǔ)方法

        代碼不是單獨(dú)的可執(zhí)行類,所以只看private void initMap()方法和public BufferedImage render()方法即可。MapBoundModel不用深究可以理解為等同Envelope類即可

        在確定以下三個(gè)值
        private String host = "172.17.8.99";
        private int port = 5300;
        private String servicename = "sde";
        設(shè)置正確并且調(diào)用refresh();方法也沒(méi)有異常拋出,但是getStream();返回null值得時(shí)候,則需要調(diào)整AXL文件添加<OUTPUT method="stream"/>重新發(fā)布,具體AXL內(nèi)容請(qǐng)注冊(cè)后下載加密附件查看

        查看代碼直接下載demo文件即可

        地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1257242391&number=0
        更多下載:http://www.fruitres.cn

    posted @ 2007-11-30 23:28 sunfruit 閱讀(439) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用GeoTools引擎繪制地圖基礎(chǔ)代碼

        --sunfruit

        Geotools是一個(gè)開(kāi)源的Java GIS工具包,可利用它來(lái)開(kāi)發(fā)符合標(biāo)準(zhǔn)的地理信息系統(tǒng)。Geotools提供了OGC(Open Geospatial Consortium)規(guī)范的一個(gè)實(shí)現(xiàn)來(lái)作為他們的開(kāi)發(fā)

        代碼演示了基于GeoTools開(kāi)源包進(jìn)行地圖開(kāi)發(fā)的基礎(chǔ)方法

        代碼不是單獨(dú)的可執(zhí)行類,所以只看private void init()方法和public BufferedImage render()方法即可。MapBoundModel不用深究可以理解為等同Envelope類即可

    直接下載demo文件即可

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=627152979&number=0
        更多下載:http://www.fruitres.cn

    posted @ 2007-11-30 23:27 sunfruit 閱讀(2676) | 評(píng)論 (2)編輯 收藏

    [轉(zhuǎn)發(fā)]微軟緊隨Google加入OGC

        --sunfruit
     

        3sNews最新消息,微軟現(xiàn)在也已經(jīng)成為OGC主要成員之一,OGC組織也對(duì)微軟的加入感到高興,他們最需要做的事情當(dāng)然是把Virtual Earth 和 SQL Server 2008納入OpenGIS兼容標(biāo)準(zhǔn).微軟是隨Google之后加入OGC協(xié)會(huì)的。而2大巨頭的加入也標(biāo)志著空間信息產(chǎn)業(yè)已進(jìn)入發(fā)展的快車道,逐漸成為IT主流。

        Google Earth的KML文件格式是開(kāi)放地理協(xié)會(huì)的最佳應(yīng)用之一,這一協(xié)會(huì)包含345個(gè)成員,涵蓋公司、政府機(jī)構(gòu)和大學(xué)等角色,他們的目標(biāo)是建立一個(gè)OpenGIS標(biāo)準(zhǔn).2007年春季,Google遞交了Keyhole Markup Language (KML 2.1)--Google Earth的最新格式,通過(guò)了OGC的驗(yàn)證,很快,它在世界范圍內(nèi)引起了廣泛的興趣,OGC也將他們加入了 -- 地理標(biāo)示語(yǔ)言(GML)中.

        原貼:http://www.3snews.net/index.php/action_viewnews_itemid_16707.html

    posted @ 2007-11-27 09:30 sunfruit 閱讀(339) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]A*算法最短路徑JAVA代碼

        --sunfruit

        基于A*算法最短路徑的JAVA代碼

        包含一篇很好A*算法的教程

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=682648067&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-11-22 15:16 sunfruit 閱讀(802) | 評(píng)論 (0)編輯 收藏

    GML3.1中文版

        --sunfruit

        Geographic information – Geography Markup
        Language (GML)-version 3.1 中文版


        可以到OGC下載GML英文版 www.opengeospatial.org

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1460914139&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-11-15 11:45 sunfruit 閱讀(723) | 評(píng)論 (7)編輯 收藏

    [原創(chuàng)]使用MapInfo引擎的自定義圖層演示程序

        --sunfruit

        這是一個(gè)自定義圖層的演示程序,演示向自定義圖層添加POI、修改自定義圖層中的POI、隱藏/顯示自定義圖層,關(guān)于圖層和POI的定義參考原來(lái)發(fā)布的例子
        通過(guò)這個(gè)demo可以了解數(shù)據(jù)部署方式,需要的lib文件,至于其它的就是Swing+Graphics的基本應(yīng)用,所以不提供源代碼
        Swing+Graphics的用法請(qǐng)參考原來(lái)發(fā)布的作品
        《基本繪圖演示源代碼,繪制矩形》
        《JAVA開(kāi)發(fā)的俄羅斯方塊源代碼》

        JDK 1.5.0

        功能:放大、縮小、平移
              地圖底圖圖層控制
              自定義圖層控制

        參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供
        
        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=2087703113&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-10-22 22:09 sunfruit 閱讀(443) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用MapInfo引擎的自定義圖層控制

        --sunfruit

        使用MapInfo地圖引擎的自定義圖層的代碼

        主要思路是自己建立系統(tǒng)圖層,該圖層和MapInfo引擎圖層無(wú)關(guān)(關(guān)于MapInfo引擎圖層控制請(qǐng)參考原來(lái)發(fā)布的例子),例如建立自己的ATM機(jī)圖層,要求可以控制顯示、隱藏ATM機(jī)圖層。那么需要建立一個(gè)圖層類和一個(gè)ATM機(jī)類,當(dāng)然最好是接口的設(shè)計(jì),這樣在2D繪制的時(shí)候可以很容易的進(jìn)行擴(kuò)展添加其他的圖層

        注:不包含地圖數(shù)據(jù)和Lib包

        參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1367471068&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-10-22 22:07 sunfruit 閱讀(361) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]基于MapInfo地圖引擎圖層管理演示程序

        --sunfruit

        上次發(fā)布了一個(gè)使用MapInfo地圖引擎進(jìn)行圖層控制源代碼,這次照例寫了一個(gè)java程序來(lái)演示圖層控制
        通過(guò)這個(gè)demo可以了解數(shù)據(jù)部署方式,需要的lib文件,至于其它的就是Swing+Graphics的基本應(yīng)用,所以不提供源代碼
        Swing+Graphics的用法請(qǐng)參考原來(lái)發(fā)布的作品
        《基本繪圖演示源代碼,繪制矩形》
        《JAVA開(kāi)發(fā)的俄羅斯方塊源代碼》

        JDK 1.5.0

        功能:放大、縮小、平移
                   地圖底圖圖層控制

        參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=842314737&number=0
        更多下載:http://www.fruitres.cn

    posted @ 2007-10-19 17:27 sunfruit 閱讀(395) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用MapInfo地圖引擎進(jìn)行圖層控制源代碼

        --sunfruit
        
        使用MapInfo地圖引擎控制地圖圖層的代碼

        該代碼只是對(duì)地圖引擎底圖數(shù)據(jù)圖層的控制,對(duì)于自定義圖層和添加新的圖層,以后會(huì)出相關(guān)的代碼

        注:不包含地圖數(shù)據(jù)和Lib包
        
        參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供

        直接下載demo文件即可

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=196483354&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-10-19 13:31 sunfruit 閱讀(417) | 評(píng)論 (0)編輯 收藏

    Oracle10g Spatial(空間數(shù)據(jù)庫(kù)參考) (10.2)

        --sunfruit

        Oracle® Spatial
        User’s Guide and Reference
        10g Release 2 (10.2)

        非常好的Oracle10g Spatial(10.2)的指南和參考文檔
        英文的
        
        目錄有3部分20多個(gè)章節(jié),這里只節(jié)選了第二章節(jié)的目錄
        2 Spatial Data Types and Metadata
        2.1 Simple Example: Inserting, Indexing, and Querying Spatial Data..... 2-1
        2.2 SDO_GEOMETRY Object Type ...... 2-5
        2.2.1 SDO_GTYPE.......... 2-5
        2.2.2 SDO_SRID.......... 2-7
        2.2.3 SDO_POINT .......... 2-7
        2.2.4 SDO_ELEM_INFO......... 2-7
        2.2.5 SDO_ORDINATES ........ 2-10
        2.2.6 Usage Considerations ......... 2-11
        2.3 SDO_GEOMETRY Methods......... 2-11
        2.4 SDO_GEOMETRY Constructors........ 2-13
        2.5 Geometry Examples........ 2-14
        2.5.1 Rectangle......... 2-14
        2.5.2 Polygon with a Hole......... 2-15
        2.5.3 Compound Line String ....... 2-17
        2.5.4 Compound Polygon ......... 2-19
        2.5.5 Point........... 2-20
        2.5.6 Oriented Point .......... 2-21
        2.5.7 Type 0 (Zero) Element......... 2-23
        2.5.8 Several Geometry Types........ 2-25
        2.6 Geometry Metadata Views ........ 2-29
        2.6.1 TABLE_NAME......... 2-30
        2.6.2 COLUMN_NAME......... 2-30
        2.6.3 DIMINFO........ 2-30
        2.6.4 SRID........... 2-31
        2.7 Spatial Index-Related Structures ....... 2-31
        2.7.1 Spatial Index Views ....... 2-31
        2.7.1.1 xxx_SDO_INDEX_INFO Views....... 2-31
        2.7.1.2 xxx_SDO_INDEX_METADATA Views..... 2-32
        2.7.2 Spatial Index Table Definition ....... 2-34
        2.7.3 R-Tree Index Sequence Object ....... 2-35
        2.8 Unit of Measurement Support ........ 2-35

        直接下載demo文件即可

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1500381985&number=0
        更多下載:http://www.fruitres.cn

    posted @ 2007-10-19 12:55 sunfruit 閱讀(492) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]JAVA基于MapInfo地圖引擎簡(jiǎn)易的地圖瀏覽程序

        --sunfruit

        前一段時(shí)間寫了一個(gè)基于MapInfo地圖引擎生成地圖圖片的例子,這次寫了一個(gè)java程序來(lái)使用MapInfo地圖引擎瀏覽地圖,可以看到加載地圖數(shù)據(jù)以后,進(jìn)行放大、縮小、平移的操作,拋去網(wǎng)絡(luò)因素,速度方面還是可以接受的
        通過(guò)這個(gè)demo可以了解數(shù)據(jù)部署方式,需要的lib文件,至于其它的就是Swing+Graphics的基本應(yīng)用,所以不提供源代碼
        Swing+Graphics的用法請(qǐng)參考原來(lái)發(fā)布的作品
        《基本繪圖演示源代碼,繪制矩形》
        《JAVA開(kāi)發(fā)的俄羅斯方塊源代碼》

        JDK 1.5.0

        功能:放大、縮小、平移

         參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供

         下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=254133506&number=0
         更多下載:http://www.fruitres.cn/

    posted @ 2007-10-17 16:19 sunfruit 閱讀(1038) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]使用MapInfo地圖引擎生成地圖圖片的代碼

        -sunfruit

        使用MapInfo地圖引擎生成地圖圖片的代碼,不包含地圖數(shù)據(jù)和Lib包

        直接下載demo文件即可
        
        參考MapXtremeJava48_DG_CHS.pdf,在MapInfo網(wǎng)站下載,或是安裝開(kāi)發(fā)包以后在文檔目錄中提供

        JDK1.5

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=447120696&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-10-17 15:18 sunfruit 閱讀(516) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]JAVA開(kāi)發(fā)的俄羅斯方塊源代碼

        --sunfruit

        JAVA開(kāi)發(fā)的俄羅斯方塊源代碼,比較簡(jiǎn)陋,只支持最基本的功能,不過(guò)框架清晰,感興趣的可以參考
       
        直接下載demo文件即可

        JDK1.5

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1925709310&number=0
        更多下載:http://www.fruitres.cn/

    posted @ 2007-09-29 11:11 sunfruit 閱讀(1201) | 評(píng)論 (1)編輯 收藏

    [資料]WINDOWS平臺(tái)的java串口開(kāi)發(fā)包javacomm20-win32

        --sunfruit
        windows平臺(tái)串口java開(kāi)發(fā)包javacomm20-win32

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=994930817&number=0
        更多下載:http://www.fruitres.cn

    posted @ 2007-09-12 11:10 sunfruit 閱讀(1031) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]WIN XP中選擇多個(gè)磁盤進(jìn)行碎片整理的方法

        --sunfruit
        WINXP中選擇多個(gè)磁盤進(jìn)行碎片整理雖然bux一個(gè)批命令文件,可以順序執(zhí)行多個(gè)磁盤的碎片整理工作,這樣雖然不能在WIN XP中選擇多個(gè)磁盤進(jìn)行碎片整理,利用這個(gè)方法也可以一次執(zhí)行多個(gè)磁盤的碎片整理,比較實(shí)用

        下載地址:http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1942443612&number=0
        更多資料:http://www.fruitres.cn/

    posted @ 2007-09-11 23:05 sunfruit 閱讀(406) | 評(píng)論 (0)編輯 收藏

    [SQL]Oracle正常SQL(2004年第1版)

        --sunfruit

        該文檔非常好的Oracle維護(hù)學(xué)習(xí)文檔
         
         文檔目錄如下

         監(jiān)控SQL
         常用戶用SQL
         查詢表結(jié)構(gòu)
         表空間使用狀況
         查詢某個(gè)模式下面數(shù)據(jù)不為空的表
         客戶端主機(jī)信息
         安裝Oracle以后,經(jīng)常使用的修改表空間的SQL代碼
         查看回滾段名稱及大小
         PL/SQL入門教程
         在from后面使用變量
         Oracle常用數(shù)據(jù)字典
         在Oracle中實(shí)現(xiàn)數(shù)據(jù)庫(kù)的復(fù)制
         SQL*PLUS環(huán)境輸入'&字符'的方法
         簡(jiǎn)說(shuō)創(chuàng)建用戶
         簡(jiǎn)說(shuō)Oracle啟動(dòng)及關(guān)閉數(shù)據(jù)庫(kù)實(shí)例
         簡(jiǎn)說(shuō)Oracle數(shù)據(jù)庫(kù)導(dǎo)出(exp)/導(dǎo)入(imp)
         實(shí)例:Oracle導(dǎo)出Excel文件
         實(shí)例:Oracle導(dǎo)出HTM文件
         查看數(shù)據(jù)庫(kù)保留字
         數(shù)據(jù)字典及某些字段意義

          下載地址  http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=244294537&number=0
          更多資料  http://www.fruitres.cn/

    posted @ 2007-09-06 09:40 sunfruit 閱讀(258) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]基本繪圖演示源代碼,繪制矩形

        --sunfruit
        
        源代碼四個(gè)文件,在這個(gè)DEMO中可以看到
        如何使用2D組件,如何把JPanel做為畫(huà)板使用,如何使用Canvas替代JPanel,如何設(shè)置2D組件的線寬

        這個(gè)只是針對(duì)像入門的新手,高手就不需要看了,免得扔雞蛋
        

         下載地址 http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=1016162856&number=0
         更多工具和文檔請(qǐng)到 http://www.fruitres.cn/

    posted @ 2007-09-03 12:46 sunfruit 閱讀(456) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]Oracle表結(jié)構(gòu)導(dǎo)出為HTML工具1.0.4

        --sunfruit
    將Oracle表結(jié)構(gòu)導(dǎo)出成Html頁(yè)面的工具

    1.0.4
    增加了導(dǎo)出觸發(fā)器、存儲(chǔ)過(guò)程、函數(shù)的功能,并且修改了不能導(dǎo)出KEYS全部類型的BUG

    1.0.3
    增加了導(dǎo)出Sequences、View的功能,并且導(dǎo)出界面默認(rèn)導(dǎo)出到安裝文件夾中的export目錄中

    1.0.2
    增加了導(dǎo)出KEYS、INDEX的功能

    1.0.1
    增加了導(dǎo)出完畢以后直接點(diǎn)擊打開(kāi)文件夾、打開(kāi)文件的查看方式,并且支持Linux/Win 平臺(tái)

    1.0.0
    導(dǎo)出為html文件,導(dǎo)出完畢后直接查看index.html文件即可。導(dǎo)出的內(nèi)容包括各個(gè)表的名稱索引和注釋以及表中各個(gè)字段的明細(xì)和注釋

    下載地址 http://www.fruitres.cn/servlet/buyproductservlet?tag=single&tag1=info&PRODUCT_ID=942025602&number=0 下載版本1.0.4
    更多工具和文檔請(qǐng)到 http://www.fruitres.cn/

    posted @ 2007-07-19 11:41 sunfruit 閱讀(1262) | 評(píng)論 (1)編輯 收藏

    [原創(chuàng)]通過(guò)JAVA改變圖片的像素Alpha值實(shí)現(xiàn)圖片透明

        --sunfruit

        設(shè)置圖片的每個(gè)象素Alpha,使得圖片透明,核心代碼如下

        private void setAlpha(ByteArrayOutputStream os) {
        /**
         * 增加測(cè)試項(xiàng)
         * 讀取圖片,繪制成半透明
         */
        try {

          ImageIcon imageIcon = new ImageIcon(os.toByteArray());
          BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(),imageIcon.getIconHeight()
              , BufferedImage.TYPE_4BYTE_ABGR);
          Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
          g2D.drawImage(imageIcon.getImage(), 0, 0,
                               imageIcon.getImageObserver());
          //循環(huán)每一個(gè)像素點(diǎn),改變像素點(diǎn)的Alpha值
          int alpha = 100;
          for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
            for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
              int rgb = bufferedImage.getRGB(j2, j1);
              rgb = ( (alpha + 1) << 24) | (rgb & 0x00ffffff);
              bufferedImage.setRGB(j2, j1, rgb);
            }
          }
          g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
         
          //生成圖片為PNG

          ImageIO.write(bufferedImage, "png",  new File(圖片路徑));
        }
        catch (Exception e) {
          e.printStackTrace();
        }

      }

    posted @ 2007-05-20 00:20 sunfruit 閱讀(12105) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]通過(guò)HttpURLConnection如何使用代理服務(wù)器連接公網(wǎng)

        --sunfruit

        在openConnection之前加上
        Properties   prop   =   System.getProperties();
        System.getProperties().put("proxySet","true");
        // 設(shè)置http訪問(wèn)要使用的代理服務(wù)器的地址
        prop.setProperty("http.proxyHost","xxxxxxx");
        // 設(shè)置http訪問(wèn)要使用的代理服務(wù)器的端口
        prop.setProperty("http.proxyPort","xxxxx");
       
        然后并不像有的貼子說(shuō)的那樣添加
        prop.setProperty("http.proxyUser","xxxxxxxx");
        prop.setProperty("http.proxyPassword","xxxxx");
        添加這樣的內(nèi)容是不行的,而是將"username:password"進(jìn)行base64編碼,具體代碼如下
        String authentication = "username:password";
        String encodedLogin = new BASE64Encoder().encode(authentication.getBytes());
        httpurlconnection.setRequestProperty("Proxy-Authorization", " Basic " + encodedLogin);
       
        注意BASE64Encoder().encode(authentication.getBytes());這里不能使用BASE64Encoder().encodeBuffer(authentication.getBytes())否則報(bào)錯(cuò)
        具體原因參考sun公布的JDK BUG , Bug ID:  4615330  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4615330

    posted @ 2007-03-22 10:41 sunfruit 閱讀(1780) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]關(guān)于JAVAMAIL發(fā)送郵件正文是html格式并且顯示圖片還帶有附件的郵件的幾點(diǎn)說(shuō)明

    ??? --sunfruit
    ??? 前一段時(shí)間發(fā)了一個(gè)“[原創(chuàng)]JAVAMAIL發(fā)送郵件正文是html格式并且顯示圖片還帶有附件的郵件”的文章,后來(lái)經(jīng)過(guò)深入的使用該功能發(fā)現(xiàn)幾個(gè)要點(diǎn)說(shuō)明如下:
    ????第一:正文必須第一個(gè)添加到Multipart對(duì)象中
    ??? 第二:IMGX? X是序號(hào),該序號(hào)必須從1開(kāi)始,并且只能為數(shù)字
    ??? 以上兩點(diǎn)缺少一點(diǎn)都不會(huì)成功
    ??? 另:ByteArrayDataSource? 這個(gè)類在舊的javamail開(kāi)發(fā)包中沒(méi)有,需要新的javamail開(kāi)發(fā)包

    posted @ 2006-11-09 11:06 sunfruit 閱讀(1486) | 評(píng)論 (1)編輯 收藏

    [資料]WEB開(kāi)發(fā)利器--JAVASCRIPT API文檔 HTML API 文檔

    ??? --sunfruit
    ??? 有三個(gè)壓縮包需要下載,下載以后放在同一個(gè)目錄中解壓即可
    ???? 下載包1
    ???? 下載包2
    ???? 下載包3

    posted @ 2006-10-31 16:37 sunfruit 閱讀(15748) | 評(píng)論 (29)編輯 收藏

    [原創(chuàng)]JAVAMAIL發(fā)送郵件正文是html格式并且顯示圖片還帶有附件的郵件

    ??? --sunfruit
    ???沒(méi)有什么說(shuō)的,源代碼如下
    public void sendMail(int id) {
    ??????? //數(shù)據(jù)初始化
    ??????? Transport transport; //發(fā)郵件時(shí)使用
    ??????? String part = GetResource.getXMLValue("mail_port"); //端口
    ??????? String mailhost = GetResource.getXMLValue("mail_server"); //服務(wù)器
    ??????? String user = GetResource.getXMLValue("mail_user"); //用戶名
    ??????? String password = GetResource.getXMLValue("mail_password"); //密碼
    ??????? String from = GetResource.getXMLValue("mail_from"); //發(fā)件mail
    ??????? String strname = GetResource.getXMLValue("mail_strname"); //在地址欄上顯示的名字

    ??????? String to = GetResource.getXMLValue("mail_to"); //收件人
    ??????? String cc = ""; //抄送人
    ??????? String bcc = ""; //密送人
    ??????? String title = GetResource.getXMLValue("mail_title"); //標(biāo)題
    ??????? byte[] bytes = null;
    ??????? try {
    ??????????? bytes = FileIO.readFile(GetResource.getXMLValue("mail_contentpath")); //正文
    ??????? } catch (IOException ex) {
    ??????????? log.error("",ex);
    ??????? }
    ??????? String fromat = GetResource.getXMLValue("mail_fromat");

    ??????? //獲得下載需要的key
    ??????? byte[] bkeydes=null;
    ??????? try {
    ??????????? bkeydes=FileIO.readFile(GetResource.getXMLValue("附件地址"));
    ??????? } catch (IOException ex) {
    ??????????? log.error("",ex);
    ??????? }

    ??????? try {
    ??????????? Properties props = System.getProperties(); //獲得系統(tǒng)屬性
    ??????????? props.put("mail.smtp.host", mailhost); //設(shè)置SMTP主機(jī)
    ??????????? props.put("mail.smtp.auth", "true"); //設(shè)置身份驗(yàn)證為真,若須身份驗(yàn)證則必須設(shè)為真

    ??????????? //獲得郵件會(huì)話對(duì)象
    ??????????? Session session = null;

    ??????????? //需要驗(yàn)證
    ??????????? session = Session.getDefaultInstance(props,
    ???????????????????????????????????????????????? new SmtpAuthenticator(user,
    ??????????????????? password));

    ??????????? //創(chuàng)建MIME郵件對(duì)象
    ??????????? MimeMessage mimeMsg = new MimeMessage(session);
    ??????????? //設(shè)置發(fā)信人
    ??????????? if (strname != null && !strname.equals("")) {
    ??????????????? mimeMsg.setFrom(new InternetAddress(from, strname));
    ??????????? } else {
    ??????????????? mimeMsg.setFrom(new InternetAddress(from));
    ??????????? }
    ??????????? //設(shè)置收信人
    ??????????? if (!to.equals("")) {
    ??????????????? mimeMsg.setRecipients(Message.RecipientType.TO,
    ????????????????????????????????????? InternetAddress.parse(to));
    ??????????? }
    ??????????? //設(shè)置抄送人
    ??????????? if (!cc.equals("")) {
    ??????????????? mimeMsg.setRecipients(Message.RecipientType.CC,
    ????????????????????????????????????? InternetAddress.parse(cc));
    ??????????? }
    ??????????? //設(shè)置暗送人
    ??????????? if (!bcc.equals("")) {
    ??????????????? mimeMsg.setRecipients(Message.RecipientType.BCC,
    ????????????????????????????????????? InternetAddress.parse(bcc));
    ??????????? }
    ??????????? //設(shè)置郵件主題
    ??????????? sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
    //??????????? mimeMsg.setSubject("=?GB2312?B?" + enc.encode(title.getBytes()) +
    //?????????????????????????????? "?=");
    ??????????? mimeMsg.setSubject(title, "GBK");
    ??????????? //設(shè)置郵件內(nèi)容
    ??????????? //mimeMsg.setText(content, "gb2312");
    ??????????? //發(fā)送日期
    ??????????? mimeMsg.setSentDate(new Date());
    ??????????? /*******************附件 begin××××××××××××××××××××××××*/
    ??????????? BodyPart mbp = null; //正文
    ??????????? //MimeBodyPart mbp1 = null; //附件

    ??????????? mbp = new MimeBodyPart();
    ??????????? //設(shè)置郵件正文格式(html/text)
    ??????????? if (fromat.equals("0") || fromat.equals("")) {
    ??????????????? //普通格式
    ??????????????? mbp.setText(new String(bytes,"GBK"));
    ??????????? } else {
    ??????????????? //網(wǎng)頁(yè)格式
    ??????????????? mbp.setDataHandler(new DataHandler(new String(bytes,"GBK"),
    ??????????????????????? "text/html;charset=gb2312"));
    ??????????? }
    ??????????? //!!!!注意必須為new MimeMultipart("related"); 這樣的實(shí)例化才能發(fā)送html正文顯示圖片的郵件 "related"
    ??????????? //new MimeMultipart(); 這樣實(shí)例化則不能發(fā)送html正文顯示圖片的郵件 只可以發(fā)送其他的郵件
    ??????????? Multipart mp = new MimeMultipart("related");
    ??????????? if (mbp != null)
    ??????????????? mp.addBodyPart(mbp); //正文

    ??????????? //附件key.des
    ??????????? BodyPart messageBodyPart = new MimeBodyPart();
    ??????????? ByteArrayDataSource fileds = new ByteArrayDataSource(bkeydes,"application/octet-stream");
    ??????????? messageBodyPart.setDataHandler(new DataHandler(fileds));
    ??????????? //解決附件中文問(wèn)題
    ??????????? //mbp1.setFileName(fileds.getName(),"gb2312");
    ??????????? messageBodyPart.setFileName(MimeUtility.encodeWord("key.des", "GB2312", null));
    ??????????? mp.addBodyPart(messageBodyPart);

    ??????????? //附件 圖標(biāo)
    ??????????? messageBodyPart = new MimeBodyPart();
    ??????????? bytes=FileIO.readFile(GetResource.getXMLValue("img_logo"));
    ??????????? fileds = new ByteArrayDataSource(bytes,"application/octet-stream");
    ??????????? messageBodyPart.setDataHandler(new DataHandler(fileds));
    ??????????? //解決附件中文問(wèn)題
    //??????????? messageBodyPart.setFileName("fruitrsource_touming.jpg");
    //??????????? messageBodyPart.setHeader("Content-ID", "fruitrsource_touming");
    ??????????? messageBodyPart.setFileName("1.jpg");
    ??????????? //!!!!注意這里是"<IMG1>" 帶有尖括號(hào) 而在正文的html里面則是src="cid:IMG1"
    ??????????? messageBodyPart.setHeader("Content-ID", "<IMG1>");
    ??????????? mp.addBodyPart(messageBodyPart);

    ??????????? // 添加 Multipart到Message中
    ??????????? mimeMsg.setContent(mp);
    ??????????? mimeMsg.saveChanges();
    ??????????? transport = session.getTransport("smtp");
    ??????????? transport.connect(mailhost, Integer.parseInt(part), user, password);
    ??????????? //發(fā)送郵件
    ??????????? //transport.send(mimeMsg, mimeMsg.getAllRecipients());
    ??????????? //transport.send(mimeMsg);
    ??????????? transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
    ??????????? //System.out.println("mail send!");
    ??????????? transport.close();

    ??????? }

    ??????? catch (Exception e) {
    ??????????? e.printStackTrace();

    ??????? }
    ??? }

    class SmtpAuthenticator extends Authenticator {
    ??????? //SMTP身份驗(yàn)證
    ??????? public SmtpAuthenticator(String username, String password) {
    ??????????? this.username = username;
    ??????????? this.password = password;
    ??????? }

    ??????? public PasswordAuthentication getPasswordAuthentication() {
    ??????????? return new PasswordAuthentication(this.username, this.password);
    ??????? }

    ??????? String username = null;
    ??????? String password = null;
    ??? }

    posted @ 2006-10-24 23:04 sunfruit 閱讀(10901) | 評(píng)論 (5)編輯 收藏

    [原創(chuàng)]利用圖片的像素RGB值還原圖像的JAVA應(yīng)用

        --sunfruit
        JAVA編寫的使用像素RGB值還原圖像的方法,代碼如下
        public class ImageData {

        private int[][] idata=null;

        public ImageData() {
            readImageData();
            writeImageData();
        }

        private int[][] readImageData()
        {
            try {
                //imagedata的鍵值就是一個(gè)存儲(chǔ)了圖像像素RGB值得文本文件
                RandomAccessFile randomAccessFile = new RandomAccessFile(new File(GetResource.getXMLValue("imagedata")),"r");
                long filesize=randomAccessFile.length();
                long filepointer=0;
                DynArrayInt dynArrayInt=null;
                ArrayList arrayList=new ArrayList();
                int n1=0;
                while(filesize>filepointer)
                {
                    filepointer=randomAccessFile.getFilePointer();

                    String str1=randomAccessFile.readLine();
                    if(str1!=null)
                    {
                        String[] str2=str1.split(" ");
                        String[] str3=str2[1].split(",");
                        dynArrayInt=new DynArrayInt();
                        for(int i=0;i<str3.length;i++)
                        {
                            if(!str3[i].equals(""))
                            {
                                int pix = Integer.parseInt(str3[i], 16);
                                dynArrayInt.addInt(pix);
                            }
                        }
                        if(n1==0)
                            n1=dynArrayInt.getSize();
                        arrayList.add(dynArrayInt);
                    }
                }

                idata=new int[arrayList.size()][dynArrayInt.getSize()];
                for(int i=0;i<idata.length;i++)
                {
                     DynArrayInt dynArrayInt1=(DynArrayInt)arrayList.get(i);
                    for(int j=0;j<idata[i].length;j++)
                    {
                        idata[i][j]=dynArrayInt1.getInt(j);
                    }
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return idata;
        }

        private void writeImageData()
        {
            BufferedImage bufferedImage=new BufferedImage(idata[0].length,idata.length,BufferedImage.TYPE_INT_RGB);
            for(int i=0;i<idata.length;i++)
            {

                for(int j=0;j<idata[i].length;j++)
                {
                    bufferedImage.setRGB(j,i,idata[i][j]);
                }
            }
            Random random=new Random(System.currentTimeMillis());
            String ext="jpg";
            String filepath = System.getProperty("java.io.tmpdir") + random.nextInt(99999) + "." + ext;
            try {
                ImageIO.write(bufferedImage, ext,  new File(filepath));
                System.out.println("文件已經(jīng)生成,路經(jīng)為" + filepath);
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }

        }

        public static void main(String[] args) {
            ImageData imagedata = new ImageData();
        }
    }

    其中的“GetResource”,“DynArrayInt”為自定義類,GetResource得功能就是解析獲取properties文件的內(nèi)容,DynArrayInt是一個(gè)整形動(dòng)態(tài)數(shù)組,可以在以前的文章里獲得“DynArrayInt”的源代碼,所謂的圖像的像素值就是如下數(shù)據(jù)
    px1 44525b,44555d,475a61,47585d,44555a,46575c,44575d,43565c,42575e,43585f,445960,435962,435964,425861,425861,41585e,3f555e,3e545f,3d5261,3c5162,3d4f59,3d4f59,3f515b,40525c,40525c,40525c,40525c,3f515b,3f515b,3f4f5a,3f4f5c,40505d,3f515f,3f515f,3d5060,3c4f5f,3b505f,3a4e58,3e525e,3e525e,3d5060,415466,3f5264,405363,405460,41555f,42575d,42575e,43585f,445862,445862,445864,445864,445866,445866,415760,435962,445a63,455b66,455b66,445a67,455b68,485d6c,4c626f,4d636e,4e646f,4d636c,4b616a,51686e,536a70,566d73,5c7378,6f7c7a,7c8987,86908f,8d9796,8e9696,949a9a,969c9c,9ca2a2,a1a3a1,a8aaa8,aeb1ac,b2b5b0,b9bcb7,c5c8c2,cccfc9,ced1c9,d6d9d1,d5d8d3,d7dad5,dadbd5,dcddd7,dcdbd4,ddddd3,e0ddd4,e0ddd4,deddd6,deddd6,deddd6,dfded7,dfded7,e0dfd8,e0dfd8,e0dfd8,e0dfd8,e3dfd9,e3dfd9,e3dfd9,e3dfd9,e4e0da,e4e0da,e4e0da,e5e1db,e5e1db,e2e1da,e2e1da,e3e2db,e3e2db,e4e3dc,e4e3dc,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e6e5de,e6e5de,e6e5de,e6e5de,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e4e1d8,e5e2d9,e5e2d9,e4e1d8,e2dfd6,e3e0d7,e2dfd6,e1ded5,e1ded5,e2dfd6,e2dfd6,e2dfd6,e2dfd6,e1ded5,e1ded5,e1ded5,e1ded5,e1ded5,dedad4,dedad4,dcdbd4,dcdbd4,dbdcd4,dbdcd4,d9dcd4,d9dcd4,dedad4,dedad4,ddd9d3,ddd9d3,dbd7d1,dbd7d1,dcd8d2,dcd8d2,dbd7d1,d5d8d0,d5d8d0,d7d8d0,d7d8d0,d7d6cf,d9d5cf,d9d5cf,d9d5cf,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d5d4cd,d5d4cd,d5d7cc,d5d7cc,d5d7cc,d5d7cc,d4d6cb,d4d6cb,d5d7cc,d5d7cc,d5d7cc,d2d7d0,d2d7d0,d3d6d0,d3d6d0,d4d5cf,d4d5cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d4d3ce,d4d3ce,d4d3ce,d4d3ce,d4d3ce,d0d3cb,d2d3cb,d3d2cb,d6d0cb,d6d0cb,d4d3cc,d3d4cc,d2d5cd,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d3d2ce,d0d3cb,d0d3cb,d2d3cb,d2d3cb,d3d2cb,d3d2cb,d5d1cb,d5d1cb,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d1d0c9,d1d0c9,d2d1ca,d2d1ca,d3d2cb,d3d2cb,d3d2cb,d3d2cb
    px0 44525b,44575e,465b62,485a5a,455757,46585a,44575b,42555b,41565d,435761,445862,445a63,435966,435964,42595f,42595e,40575c,3f5560,3d5263,3c5066,3a4c58,3b4d59,3d4f5b,3e505a,40525c,40525c,40535a,3f5259,3f5259,3f5057,3f5057,405158,3f5259,3f5259,3d515b,3c505a,3b515c,3a4e5a,3e5260,3e5260,3d5060,415468,3f5266,3f5262,405462,405460,42575d,42575e,43585f,435761,41555f,425662,445864,465a68,465a68,415760,425861,445a63,445a65,445a65,465c69,475d6a,475c6b,44596a,485d6e,4c6373,4d6474,4a616f,4b6472,4b6472,496270,4c6573,5f6c6e,677476,6f7c7e,798587,818a8d,899295,8f969a,91989c,949895,9a9e9b,9ea39d,a1a6a0,a9aea8,aeb3ac,babfb8,c0c5bc,ccd1c8,cfd2cd,d2d5d0,d5d6d0,d7d8d2,dcdbd4,ddddd3,e0ddd4,e0ddd4,deddd6,deddd6,deddd6,dfded7,dfded7,e0dfd8,e0dfd8,e0dfd8,e0dfd8,e3dfd9,e3dfd9,e3dfd9,e3dfd9,e4e0da,e4e0da,e4e0da,e5e1db,e5e1db,e2e1da,e2e1da,e3e2db,e3e2db,e4e3dc,e4e3dc,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e6e5de,e6e5de,e6e5de,e6e5de,e5e4dd,e5e4dd,e5e4dd,e5e4dd,e4e1d8,e4e1d8,e4e1d8,e3e0d7,e2dfd6,e2dfd6,e2dfd6,e1ded5,e1ded5,e2dfd6,e2dfd6,e2dfd6,e2dfd6,e1ded5,e1ded5,e1ded5,e1ded5,e1ded5,ddd9d3,ddd9d3,dbdad3,dbdad3,dadbd3,dadbd3,d8dbd3,d8dbd3,dedad4,dedad4,ddd9d3,ddd9d3,dad6d0,dbd7d1,dcd8d2,dcd8d2,dbd7d1,d5d8d0,d5d8d0,d5d8d0,d7d8d0,d6d7cf,d7d6cf,d7d6cf,d9d5cf,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d6d5ce,d5d4cd,d5d4cd,d6d8cd,d6d8cd,d6d8cd,d6d8cd,d4d6cb,d4d6cb,d5d7cc,d5d7cc,d5d7cc,d3d8d1,d3d8d1,d4d7d1,d4d7d1,d4d5cf,d4d5cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d5d4cf,d4d3ce,d4d3ce,d4d3ce,d4d3ce,d4d3ce,d0d3cb,d2d3cb,d3d2cb,d6d0cb,d7d1cc,d4d3cc,d4d5cd,d2d5cd,d4d2d1,d4d2d1,d4d2d1,d4d2d1,d4d2d1,d3d1d0,d3d1d0,d3d1d0,d3d1d0,d0d3cb,d0d3cb,d2d3cb,d2d3cb,d3d2cb,d3d2cb,d5d1cb,d5d1cb,d3d2cd,d3d2cd,d3d2cd,d3d2cd,d3d2cd,d2d1cc,d2d1cc,d2d1cc,d2d1cc,d1d0c9,d1d0c9,d2d1ca,d2d1ca,d4d3cc,d4d3cc,d4d3cc,d4d3cc
    以上數(shù)據(jù)表示圖像有兩行像素,每一行有260個(gè)像素組成,每個(gè)像素的RGB值就是44525b

    posted @ 2006-10-23 21:28 sunfruit 閱讀(1928) | 評(píng)論 (2)編輯 收藏

    [原創(chuàng)]圖論應(yīng)用--最短路徑

        --sunfruit

    求上圖1點(diǎn)到其他各點(diǎn)的最短路徑,依據(jù)圖論知識(shí)建立矩陣模型,進(jìn)一步得到代碼如下

    public class ShortPathA {

      private static int[][]
          a = {
          {0, 50, 10, 100000, 45, 100000}, {100000, 0, 15, 100000, 10, 100000}, {20, 100000, 0, 15, 100000, 100000}, {
          100000, 20, 100000, 0, 35, 100000}, {100000, 100000, 1000000, 30, 0, 100000}, {100000, 100000, 100000, 3, 100000, 0}
      };

      private static boolean[] mark = new boolean[a.length];
      public ShortPathA() {
        int Vo = 0; //源點(diǎn)
        //源點(diǎn)到其他各點(diǎn)的距離
        int[] b = new int[a.length];
        DynArrayInt S = new DynArrayInt();
        for (int i = 0; i < a.length; i++) {
          mark[i] = false;
          //b[i] = a[Vo][i];
        }
        int best = -1;
        mark[0] = true;
        b[0] = 0; //{0為源點(diǎn)}
        while (best != 0) {
          best = 0;
          int best_j = 0;
          for (int i = 0; i < b.length; i++)
          {
            if (mark[i]) //{對(duì)每一個(gè)已計(jì)算出最短路徑的點(diǎn)}
            {
              for (int j = 0; j < b.length; j++) {
                if ( (!mark[j]) && (a[i][j] > 0)) {
                  if ( (best == 0) || (b[i] + a[i][j] < best)) {
                    best = b[i] + a[i][j];
                    best_j = j;
                  }
                }
              }
            }
          }
          if (best > 0) {
            b[best_j] = best;
            mark[best_j] = true;
          }

        }
        System.out.println(java.util.Arrays.toString(b));
      }

      public static void main(String[] args) {
        ShortPathA shortpath = new ShortPathA();
      }

    }

    posted @ 2006-10-23 21:17 sunfruit 閱讀(1696) | 評(píng)論 (0)編輯 收藏

    用URLConnection或是HttpURLConnection類以POST或是GET方式提交保持Session的解決辦法

        --sunfruit
        當(dāng)通過(guò)URLConnection第一次和服務(wù)器發(fā)起POST或是GET請(qǐng)求以后,通過(guò)getHeaderField方法獲得SessionID,具體方法為:
        String session_value=getHeaderField("Set-Cookie");
        第二次發(fā)起POST或是GET請(qǐng)求的時(shí)候需要把剛才獲得的SessionID放置在請(qǐng)求的頭部然后再提交,這樣就能服務(wù)器就會(huì)認(rèn)為是同一個(gè)Session請(qǐng)求了,具體方法為:
        setRequestProperty("Cookie", session_value);

        如果取得Set-Cookie的值比較長(zhǎng),取值到分號(hào)前即可 如 JSESSIONID=575F7196EDB52825D288F4061C66BC29;
        
        這樣就實(shí)現(xiàn)了保存session向服務(wù)器提交請(qǐng)求

    posted @ 2006-09-01 14:21 sunfruit 閱讀(3272) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]圖論應(yīng)用--一筆畫(huà)問(wèn)題

    ??? --sunfruit
    tu1_2.gif
    上圖求一筆畫(huà)的路徑,利用圖論的相關(guān)知識(shí)可以得到程序如下:

    public class OnePath {

    ??? private static int[][]
    ??????????? links = { {0,1,1,0,0,0,1,0}, {1,0,0,1,0,0,0,1}, {1,0,0,1,1,1,0,0},
    ??????????? {0,1,1,0,1,1,0,0}, {0,0,1,1,0,1,1,0}, {0,0,1,1,1,0,0,1}, {1,0,0,0,1,0,0,0}, {0,1,0,0,0,1,0,0}
    ??? };

    ??? public OnePath() {
    ??????? int sum = 0;
    ??????? //存放每個(gè)點(diǎn)的度
    ??????? int[] point = new int[links[0].length];
    ??????? for (int i = 0; i < links[0].length; i++) {
    ??????????? int[] templink = links[i];
    ??????????? for (int j = 0; j < links[0].length; j++) {
    ??????????????? point[i] += templink[j];
    ??????????? }
    ??????????? sum += point[i];
    ??????? }

    ??????? //計(jì)算度數(shù)是奇數(shù)點(diǎn)的個(gè)數(shù),如果大于2則不能一筆畫(huà)
    ??????? int odt = 0;
    ??????? int start = -1;
    ??????? for (int i = 0; i < point.length; i++) {
    ??????????? int mod = point[i] % 2;
    ??????????? if (mod > 0) {
    ??????????????? //if(start==-1)
    ??????????????????? start = i;
    ??????????????? odt++;
    ??????????? }
    ??????? }
    ??????? if(odt>2)
    ??????? {
    ????????? System.out.println("該圖不能一筆畫(huà)");
    ????????? return;
    ??????? }
    ??????? int r = 0;
    ??????? //從一個(gè)奇數(shù)點(diǎn)開(kāi)始計(jì)算
    ??????? int nowd=start;
    ??????? System.out.print(nowd+1);
    ??????? while (sum > 0) {
    ??????????? r=0;
    ??????????? //對(duì)于起點(diǎn)nowd 檢查當(dāng)前的點(diǎn)r 是否合適
    ??????????? //links[nowd][r]==0 判斷是否有可以走的沒(méi)有用過(guò)的線路
    ??????????? //(point[r]<=1 && sum!=2) 判斷是否是最后一次,如果不是最后一次,那么避開(kāi)度數(shù)是1的點(diǎn)
    ??????????? while (links[nowd][r]==0 || (point[r]<=1 && sum!=2)) {
    ??????????????? r++;
    ??????????? }
    ??????????? links[nowd][r]=0; //已經(jīng)用過(guò)的線路
    ??????????? links[r][nowd]=0; //已經(jīng)用過(guò)的線路 links[nowd][r] links[r][nowd]互為往返路線,用過(guò)1->2那么2->1也作廢了
    ??????????? sum=sum-2; //總度數(shù)減2 因?yàn)閺?->2 消耗了1的度和2的度
    ??????????? point[nowd]--; //起點(diǎn)和終點(diǎn)的度都減1 1->2 那么1的度和2的度都減1
    ??????????? point[r]--; //起點(diǎn)和終點(diǎn)的度都減1 1->2 那么1的度和2的度都減1
    ??????????? nowd =r; //設(shè)置新的起點(diǎn)
    ??????????? System.out.print("->"+(r+1));
    ??????? }
    ??? }

    ??? public static void main(String[] args) {
    ??????? new OnePath();
    ??? }

    }

    posted @ 2006-08-31 14:20 sunfruit 閱讀(945) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)]JavaScript面向?qū)ο蟮奶匦?/a>

    如果你使用JavaScript編程,你或許會(huì)懷疑它是否包含了面向?qū)ο螅∣O)的結(jié)構(gòu)。實(shí)際上,JavaScript的確支持面向?qū)ο蟮募軜?gòu)――在某種程度上。本文將通過(guò)一個(gè)可擴(kuò)展向量圖形(SVG)的實(shí)例來(lái)說(shuō)明JavaScript的OO結(jié)構(gòu)。

    我如何在類中定義方法和屬性?

    OO開(kāi)發(fā)的一個(gè)基本方面是類及其相應(yīng)的方法和/或?qū)傩缘氖褂谩avaScript通過(guò)function關(guān)鍵字支持類(及其屬性)的使用。下面的代碼定義了一個(gè)叫做Figure的JavaScript類:
    function Figure() {
    this.centerX=0;
    this.centerY=0;
    this.area=0;
    this.transform = transform; // methods are defined like this
    function transform(moveX,moveY,angle) {
    this.centerX += moveX;
    this.centerY += moveY;
    } }

    這個(gè)Figure類有三個(gè)屬性:centerX,centerY,和area。另外,它還有一個(gè)方法叫做transform()。前三行是這個(gè)類的構(gòu)造器。
    但是它看起來(lái)不像一個(gè)類
    你會(huì)想Figure()看起來(lái)不像一個(gè)類,而更像一個(gè)JavaScript的函數(shù)。那么為什么Figure()定義的是個(gè)類?

    嚴(yán)格的說(shuō),F(xiàn)igure()函數(shù)沒(méi)有定義一個(gè)類,但是它仿造了一個(gè)。它實(shí)際上創(chuàng)建了一個(gè)對(duì)象,在括號(hào)里的代碼使這個(gè)對(duì)象的構(gòu)造器。JavaScript的對(duì)象支持是很基礎(chǔ)的,它并不區(qū)分類和對(duì)象。
    這就引到了問(wèn)題為什么Figure()函數(shù)創(chuàng)建的是一個(gè)對(duì)象。對(duì)象是可以有屬性和方法的?;旧?,因?yàn)镕igure()函數(shù)同時(shí)包含了屬性和方法,它就是個(gè)對(duì)象。在JavaScript里,所有的函數(shù)即是對(duì)象又是可調(diào)用的代碼塊。這不像它聽(tīng)起來(lái)的那樣容易被誤解。要?jiǎng)?chuàng)建一個(gè)Figure()類/對(duì)象,你只用使用以下句法:
    MyFigure = new Figure();
    你也可以把Figure()函數(shù)當(dāng)作代碼塊調(diào)用,就像這樣:
    figValue = Figure();
    變量figValue沒(méi)有被定義是因?yàn)榇a塊Figure()沒(méi)有返回任何值。如果你把return(this.area)加到函數(shù)的最后一行,figValue就會(huì)有個(gè)值0。所以figValue是個(gè)類型數(shù)字,MyFigure是對(duì)象 Rectangle的實(shí)例。
    為什么所有的變量前面都一個(gè)“this”?

    這個(gè)關(guān)鍵字this表示這是對(duì)象的實(shí)例變量,可以使用MyFigure.centerX從對(duì)象外部訪問(wèn)。要讓變量成為私有變量,去掉前綴this就行了。this.transform = transform這一行讓方法成為公用方法。這個(gè)方法通過(guò)MyFigure.transform(100,100,0)調(diào)用。

    這些類有層次之分嗎?

    另一個(gè)好問(wèn)題的是JavaScript的類是否有層次之分?;卮鹗强隙ㄓ小N覀儊?lái)仔細(xì)看看是怎么做到分層的。我們可以定義一個(gè)Rectangle子類,并把Figure作為父類:

    function Rectangle(startX, startY, endX, endY) {
    this.width = endX - startX;
    this.height = endY - startY;
    this.centerX = (endX + startX)/2;
    this.centerY = (endY + startY)/2;
    this.computeArea = computeArea;
    function computeArea() {
    this.area = this.width*this.height;
    } }
    Rectangle.prototype = new Figure();

    Rectangle對(duì)象是用4個(gè)自變量創(chuàng)建的,前四行是構(gòu)造器。 Rectangle類包含了一個(gè)方法: computeArea()。最后一行Rectangle.prototype = new Figure();,把Rectangle類定義為從Figure類繼承來(lái)的子類。
    然我來(lái)解釋一下prototype(原型)。每個(gè)對(duì)象構(gòu)造器都有prototype屬性;這是用來(lái)給所有的對(duì)象增加新屬性和方法的。這就是為什么原型被用來(lái)實(shí)現(xiàn)繼承:child.prototype = new parent();。通過(guò)原型,父對(duì)象的所有屬性和方法都被添加到子對(duì)象上。
    要注意this.centerX,this.centerY,和area是Rectangle類中所使用的屬性,但是它們是 Figure父類的屬性。和Rectangle類相似,Circle類可以被定義成Figure類的原型。這種父子關(guān)系可以按你需要來(lái)定義深度;你可以創(chuàng)建另一個(gè)Rectangle的子類。
    我如何創(chuàng)建一個(gè)類的實(shí)例?

    在JavaScript里創(chuàng)建一個(gè)類的實(shí)例很容易:
    rect = new Rectangle(100,100,900,800);
    這就創(chuàng)建了Rectangle類型的一個(gè)對(duì)象。Rectangle的構(gòu)造器在屬性width, height, centerX, 和centerY中填入了值。rect.area屬性的值是零(0)。使用這個(gè)命令就能調(diào)用area方法:
    rect.computeArea();
    rect.area的值現(xiàn)在是560,000。要調(diào)用transform方法使用:
    rect.transform(100,200,0);

    父和子對(duì)象的屬性可以像這樣訪問(wèn)到:
    var ar = rect.area;
    var wi = rect.width;

    我能超越屬性和方法嗎?

    就像你在Java中的一樣,你可以超越屬性和方法。在子類中定義的屬性或者方法可以超越同名的父類的屬性和方法。
    和全局變量互動(dòng)
    JavaScript也支持全局變量的使用。在以下代碼段中測(cè)試一下g_area變量的范圍:
    <HTML>
    <SCRIPT>
    var g_area = 20;
    function Figure() {

    this.area=g_area;

    }
    function Rectangle(){ … }
    Rectangle.prototype = new Figure();
    function test(){
    g_area = 40;
    rect = new Rectangle();
    alert(rect.area);
    }
    </SCRIPT>
    <BODY onLoad = 'test()'/>
    </BODY>
    </HTML>
    rect.area的值是20(不是你預(yù)計(jì)的40),這是因?yàn)镽ectangle對(duì)象是Figure對(duì)象的原型,這種關(guān)系在test()被調(diào)用以前就被定義了。要使用g_area的新值,你需要用以下的方法:

    function test() {
    g_area = 40;
    Rectangle.prototype = new Figure();
    rect = new Rectangle();
    alert(rect.area);
    }

    對(duì)于所有的Rectangle的新實(shí)例,這將改變area屬性的值?;蛘?,你可以使用這種方法:function test() {
    g_area = 40;
    rect = new Rectangle();
    Rectangle.prototype.area = g_area;
    alert(rect.area);
    }

    這將改變Rectangle所有現(xiàn)存的以及新實(shí)例的area屬性的值。
    結(jié)論

    為了效仿OO開(kāi)發(fā),JavaScript提供了必需的繼承、封裝和超越屬性,盡管它不支持接口和方法的過(guò)載。如果你是剛接觸到OO開(kāi)發(fā),用它試試。OO概念允許開(kāi)發(fā)者將一組數(shù)據(jù)和相關(guān)操作集中入一個(gè)對(duì)象。這在管理瀏覽器事件和管理瀏覽器內(nèi)SVG圖時(shí)很有用。

    posted @ 2006-08-30 09:37 sunfruit 閱讀(405) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)發(fā)]SEO|搜索引擎優(yōu)化(如何讓你的網(wǎng)站排名靠前)

         摘要: --sunfruit如何讓你的網(wǎng)站排名靠前??????? 網(wǎng)站做好了,怎樣才能讓你的網(wǎng)站在各大搜索引擎中排名靠前呢?網(wǎng)上的帖子很多,通過(guò)搜索和總結(jié),整理出了一套自己行之有效的方法,寫出來(lái)供大家參考?????? 成功案例推薦:http://sooboo.com.cn/?????? 還在繼續(xù)整理中,而且我們的網(wǎng)站也在不斷優(yōu)化中.........1、?網(wǎng)站建好后首先到各大搜索引擎免費(fèi)登錄你的網(wǎng)站http...  閱讀全文

    posted @ 2006-08-11 10:37 sunfruit 閱讀(729) | 評(píng)論 (1)編輯 收藏

    [原創(chuàng)]通過(guò)AJAX監(jiān)控文件上傳進(jìn)度

    ??? --sunfruit

    ???很多時(shí)候需要上傳附件到服務(wù)器,一般采用在頁(yè)面放置<input type="file" name="upload" value=""> 的方式讓用戶選擇要上傳的文件進(jìn)行上傳,使用的是HTTP協(xié)議,這樣的方式很方便開(kāi)發(fā)也簡(jiǎn)單,不過(guò)如果上傳的附件比較大的時(shí)候,會(huì)出現(xiàn)IE響應(yīng)很慢的情況,如果用戶急性子,多點(diǎn)幾下上傳的按鈕,那么就會(huì)導(dǎo)致IE不響應(yīng)的情況,這個(gè)時(shí)候如果在文件上傳得過(guò)程中,給用戶一個(gè)動(dòng)態(tài)的提示甚至是一個(gè)上傳的進(jìn)度條,效果就會(huì)好多了,這樣就會(huì)用到Ajax技術(shù)了,讓Ajax以一個(gè)固定的間隔時(shí)間檢查上傳情況然后在頁(yè)面以文字或是圖片的方式體現(xiàn)出來(lái)就行了。
    ???在使用Ajax進(jìn)行附件上傳進(jìn)度查詢的時(shí)候也想過(guò),直接使用Ajax進(jìn)行附件上傳,在實(shí)現(xiàn)過(guò)程中發(fā)現(xiàn)問(wèn)題比較多,所以就使用了變通的方式:使用標(biāo)準(zhǔn)的附件上傳方式,結(jié)合Ajax進(jìn)行上傳的進(jìn)度檢查
    ???主要的代碼如下:
    ???Ajax的封裝
    ???/**
    ? * 創(chuàng)建 XMLHttpRequest 對(duì)象
    ? */
    ? function getXMLHttpRequest()
    ? {
    ??? var http_request;
    ??? if (window.XMLHttpRequest) {
    ????? //非IE瀏覽器框架創(chuàng)建 XMLHttpRequest 對(duì)象
    ????? http_request = new XMLHttpRequest();
    ????? if(http_request.overrideMimeType)
    ????? {
    ??????? http_request.overrideMimeType('text/xml');
    ????? }
    ??? }else if (window.ActiveXObject){
    ????? // 創(chuàng)建 XMLHttpRequest 對(duì)象
    ????? try {
    ??????? http_request = new ActiveXObject("Msxml2.XMLHTTP");
    ????? } catch (e1) {
    ??????? try {
    ????????? http_request = new ActiveXObject("Microsoft.XMLHTTP");
    ??????? } catch (e2) {
    ????????? // 不能創(chuàng)建 XMLHttpRequest 對(duì)象
    ??????? }
    ????? }
    ??? }
    ??? return http_request;
    ? }

    /**
    ?? * Get請(qǐng)求
    ?? */
    ? function sendGetDictate(http_request,url)
    ? {
    ??? req.open("GET", url, true);
    ??? http_request.send(null);
    ? }
    以上是Ajax的的基礎(chǔ)部分,下面說(shuō)文件上傳部分的檢查部分,文件上傳本身的流程不變,只是在提交上傳以后,需要執(zhí)行setTimeout(checkupload,500); 這樣的方法 checkupload 方法要自己編寫,例如
    function checkupload()
    ? {
    ??? req=getXMLHttpRequest();
    ??? req.onreadystatechange = setActiveContent;
    ??? sendGetDictate(req,"/manager/servlet/imageservlet?tag=ajaxuploadfilecheck&WARE_ID=609187669&nocache="+Math.random(),"name=111");
    ? }
    然后需要編寫setActiveContent方法,例如
    var count=0; //防止無(wú)限循環(huán),并且在頁(yè)面提交上傳得時(shí)候設(shè)置為0
    function setActiveContent()
    ? {
    ??? if (req.readyState == 4) {
    ????? if (req.status == 200) {
    ??????? var rettext=req.responseText; //這里是servlet返回的內(nèi)容,檢查上傳得狀態(tài),可以在javabean或是servlet里面設(shè)置全局的靜態(tài)變量來(lái)表明上傳狀態(tài)
    ??????? if(rettext=="-1")
    ??????? {
    ????????? //停止循環(huán)
    ????????? alert("服務(wù)器更新錯(cuò)誤");
    ??????? }
    ??????? else if(rettext=="0")
    ??????? {
    ????????? //繼續(xù)循環(huán)檢查
    ????????? if(count<6)
    ????????? {
    ??????????? setTimeout("checkupload()",500);
    ??????????? count++;
    ????????? }
    ????????? else
    ????????? {
    ??????????? alert("上傳失敗");
    ????????? }
    ??????? }
    ????????else if(rettext=="1")
    ??????? {
    ????????? alert("文件上傳成功");
    ??????? }
    ????? }
    ??? }
    ? }
    ?
    基本流程就是這樣了,至于文字表現(xiàn)上傳過(guò)程還是進(jìn)度條表現(xiàn),就看自己了

    posted @ 2006-08-10 11:11 sunfruit 閱讀(2454) | 評(píng)論 (5)編輯 收藏

    [轉(zhuǎn)發(fā)]AWT和Swing中的繪畫(huà)

    Painting in AWT and Swing
    Good Painting Code Is the Key to App Performance
    By Amy Fowler

    在圖形系統(tǒng)中, 窗口工具包(windowing toolkit)通常提供一個(gè)框架以便相對(duì)容易地創(chuàng)建一個(gè)圖形用戶接口(GUI),在正確的時(shí)間、正確的屏幕位置顯示一個(gè)正確的圖像位。

    AWT (abstract windowing toolkit,抽象窗口工具包) 和Swing都提供這種框架。但是實(shí)現(xiàn)這種框架的APIs對(duì)一些開(kāi)發(fā)人員來(lái)講不是很好理解 -- 這就導(dǎo)致一些程序的運(yùn)行達(dá)不到預(yù)期的效果。

    本文詳細(xì)地解釋AWT和Swing的繪畫(huà)機(jī)制,目的是幫助開(kāi)發(fā)人員寫出正確的和高率的GUI繪畫(huà)代碼。然而,這篇文章只包括一般的畫(huà)圖機(jī)制(即,在什么地方和什么時(shí)間去呈現(xiàn)),而不介紹Swing的圖形API怎樣去呈現(xiàn)圖形。想學(xué)習(xí)怎樣去顯示漂亮的圖形,請(qǐng)?jiān)L問(wèn)Java 2D 網(wǎng)站。

    繪畫(huà)系統(tǒng)的演變
    當(dāng)最初的、為JDK1.0使用的AWT API發(fā)布時(shí),只有重量級(jí)(heavyweight)部件("重量級(jí)" 的意思是說(shuō)該部件有它自己的、遮光(opaque)的、與生俱來(lái)的窗體)。這樣就使得AWT在很大程度上依賴于本地平臺(tái)的繪畫(huà)系統(tǒng)。這樣的安排需要開(kāi)發(fā)人員寫代碼的時(shí)候要考慮到很多細(xì)節(jié)問(wèn)題,象重畫(huà)檢測(cè)(damage detection)、剪切(clip)計(jì)算、以及Z軸次序等。隨著JDK 1.1中輕量級(jí)(lightweight)部件的引入("輕量級(jí)" 部件重用了與它最接近的重量級(jí)祖先的本地窗體),需要AWT能在共享的代碼里為輕量級(jí)部件實(shí)現(xiàn)繪畫(huà)處理。因此,重量級(jí)和輕量級(jí)部件在它們各自的繪畫(huà)處理方法有著微妙的差別。

    在JDK 1.1之后,當(dāng)發(fā)布了Swing工具的時(shí)候,引入了它自己的繪畫(huà)風(fēng)格。Swing的繪畫(huà)機(jī)制在很大程度上類似并且依賴于AWT,但是,也有它自己的觀點(diǎn),還帶來(lái)了新的API,使得應(yīng)用程序可以容易地定制繪畫(huà)工作。


    在AWT中繪畫(huà)
    去理解AWT繪畫(huà)API怎樣工作,有助于我們搞明白是什么觸發(fā)了窗口環(huán)境中的繪畫(huà)操作。AWT中有兩種繪畫(huà)操作:系統(tǒng)觸發(fā)的繪畫(huà),和程序觸發(fā)的繪畫(huà)

    系統(tǒng)觸發(fā)的繪畫(huà)操作
    在系統(tǒng)觸發(fā)的繪畫(huà)操作中,系統(tǒng)需要一個(gè)部件顯示它的內(nèi)容,通常是由于下列中的原因:


    部件第一次在屏幕上顯示


    部件的大小改變了


    部件顯示的內(nèi)容受損需要維護(hù)。(比如,先前擋住部件的其它物體移走了,于是部件被擋住的部分曝露出來(lái)。
    程序觸發(fā)的繪畫(huà)操作

    在程序觸發(fā)的繪畫(huà)操作,是部件自己決定要更新自身的內(nèi)容,因?yàn)椴考?nèi)部的狀態(tài)改變了。(比如,監(jiān)測(cè)到鼠標(biāo)按鈕已經(jīng)按下,那么它就需要去畫(huà)出按鈕"被按下"時(shí)的樣子>

    畫(huà)圖的方法
    不管是誰(shuí)觸發(fā)了畫(huà)圖請(qǐng)求,AWT都是利用"回調(diào)"機(jī)制來(lái)實(shí)現(xiàn)繪畫(huà),這個(gè)機(jī)制對(duì)于“重量級(jí)”和“輕量級(jí)”的部件都是相同的。這就意味著程序應(yīng)該在一個(gè)特定的可覆蓋的方法中放置那些表現(xiàn)部件自身的的代碼,并且在需要繪畫(huà)的時(shí)候,工具包就會(huì)調(diào)用這個(gè)方法。這個(gè)可覆蓋的方法在java.awt.Component中聲明:

    ??? public void paint(Graphics g)

    當(dāng)AWT調(diào)用這個(gè)方法時(shí),作為參數(shù)的、負(fù)責(zé)在這個(gè)特定的部件上繪畫(huà)的Graphics對(duì)象是在之前已經(jīng)配置了的,擁有恰當(dāng)?shù)臓顟B(tài)值。

    Graphics的顏色 值被設(shè)置為部件的前景。
    Graphics的字體 設(shè)置為部件的字體。
    Graphics的平移(translation) 也給設(shè)定,使用坐標(biāo)(0,0)定位部件的左上角。
    Graphics的裁剪框(clip rectangle)設(shè)置為部件需要畫(huà)圖的區(qū)域。
    程序必須使用這個(gè)Graphics(或者其派生類)對(duì)象來(lái)呈現(xiàn)繪畫(huà),并且可以根據(jù)自己的需要任意改變Graphics對(duì)象的屬性值。

    這里是一個(gè)回調(diào)繪畫(huà)的簡(jiǎn)單例子,在部件的范圍內(nèi)呈現(xiàn)一個(gè)實(shí)體園:

    ??? public void paint(Graphics g) {
    ??????? // 根據(jù)部件的范圍,動(dòng)態(tài)計(jì)算圓的尺寸信息。
    ??????? Dimension size = getSize();
    ??????? // 直徑
    ??????? int d = Math.min(size.width, size.height);
    ??????? int x = (size.width - d)/2;
    ??????? int y = (size.height - d)/2;

    ??????? // 畫(huà)圓(顏色已經(jīng)預(yù)先設(shè)置為部件的前景顏色)
    ??????? g.fillOval(x, y, d, d);
    ??????? g.setColor(Color.black);
    ??????? g.drawOval(x, y, d, d);
    ??? }

    初次接觸AWT的開(kāi)發(fā)人員可以看看PaintDemo example,那里介紹了一個(gè)在AWT程序中怎樣使用畫(huà)圖回調(diào)方法的例子。

    一般情況下,程序應(yīng)該避免把繪畫(huà)代碼放置在回調(diào)方法paint()的范圍之外。為什么呢?因?yàn)閜aint方法之外的繪畫(huà)代碼可能會(huì)在不適合畫(huà)圖的時(shí)候被調(diào)用 -- 例如,在部件變?yōu)榭梢?jiàn)之前或者已經(jīng)在使用一個(gè)有效的Graphics。同時(shí),不推薦在程序中直接調(diào)用paint()。

    為了使能夠由程序觸發(fā)繪畫(huà)操作,AWT提供了下面的java.awt.Component的方法,這樣程序就可以提出一個(gè)異步的繪畫(huà)請(qǐng)求:

    ??? public void repaint()
    ??? public void repaint(long tm)
    ??? public void repaint(int x, int y, int width, int height)
    ??? public void repaint(long tm, int x, int y,
    ?????????????????? int width, int height)

    下面的代碼顯示了一個(gè)簡(jiǎn)單的鼠標(biāo)監(jiān)聽(tīng)器的例子,當(dāng)鼠標(biāo)按下和抬起的時(shí)候,使用repaint()來(lái)觸發(fā)“假想按鈕”的更新操作。


    MouseListener l = new MouseAdapter() {
    ??????????? public void mousePressed(MouseEvent e) {
    ??????????????? MyButton b = (MyButton)e.getSource();
    ??????????????? b.setSelected(true);
    ??????????????? b.repaint();????????????
    ??????????? }

    ??????????? public void mouseReleased(MouseEvent e) {
    ??????????????? MyButton b = (MyButton)e.getSource();
    ??????????????? b.setSelected(false);
    ??????????????? b.repaint();????????????
    ??????????? }
    ??????? };

    如果部件要呈現(xiàn)復(fù)雜的圖形,就應(yīng)該使用帶參數(shù)的repaint()方法,通過(guò)參數(shù)來(lái)指定需要更新的區(qū)域。一個(gè)比較常見(jiàn)的錯(cuò)誤是總是調(diào)用無(wú)參數(shù)的repaint()來(lái)提出重畫(huà)請(qǐng)求,這個(gè)方法會(huì)重畫(huà)整個(gè)部件,經(jīng)常導(dǎo)致一些不必要的畫(huà)圖處理。

    paint() vs. update()
    為什么我們要區(qū)分繪畫(huà)操作是"系統(tǒng)觸發(fā)" 還是"程序觸發(fā)"呢?因?yàn)樵凇爸亓考?jí)”部件上,AWT對(duì)這兩種請(qǐng)求的在處理上稍有不同(“輕量級(jí)”的情況將在后面介紹),并且不幸的是與此相關(guān)的代碼非常復(fù)雜,難以更改。

    對(duì)于“重量級(jí)”部件,這兩種方式的繪畫(huà)產(chǎn)生于兩條不同的途徑,取決于是“系統(tǒng)觸發(fā)”還是“程序觸發(fā)”。

    系統(tǒng)觸發(fā)的繪畫(huà)
    下面介紹“系統(tǒng)觸發(fā)”的繪畫(huà)操作是怎么產(chǎn)生的:

    AWT確定是一部分還是整個(gè)部件需要繪畫(huà)。


    AWT促使事件分派線程調(diào)用部件的paint()方法。

    程序觸發(fā)的繪畫(huà)
    由程序觸發(fā)的繪畫(huà)的產(chǎn)生如下所示:

    程序確定是一部分還是全部部件需要重畫(huà)以對(duì)應(yīng)內(nèi)部狀態(tài)的改變。
    ?

    程序調(diào)用部件的repaint(),該方法向AWT登記了一個(gè)異步的請(qǐng)求 -- 當(dāng)前部件需要重畫(huà)。
    ?

    AWT促使事件分派線程去調(diào)用部件的update() 方法。
    注意: 在最初的重畫(huà)請(qǐng)求處理完成之前,如果在該部件上有多次對(duì)repaint()的調(diào)用,那么這些調(diào)用可以被合并成對(duì)update()的一次調(diào)用。決定什么時(shí)候應(yīng)該合并多次請(qǐng)求的運(yùn)算法則取決于具體的實(shí)現(xiàn)。如果多次請(qǐng)求被合并,最終被更新的區(qū)域?qū)⑹撬羞@些請(qǐng)求所要求更新的區(qū)域的聯(lián)合(union)。

    ?

    如果部件沒(méi)有覆蓋(override)update()方法,update()的默認(rèn)實(shí)現(xiàn)會(huì)清除部件背景(如果部件不是“輕量級(jí)”),然后只是簡(jiǎn)單地調(diào)用paint()方法。
    因?yàn)樽鳛槟J(rèn)的最終結(jié)果都是一樣的(paint()方法被調(diào)用),很多開(kāi)發(fā)人員完全不知道一個(gè)分離的update() 方法的意義。確實(shí),默認(rèn)的update()的實(shí)現(xiàn)最終會(huì)轉(zhuǎn)回到對(duì)paint()方法的調(diào)用,然而,如果需要,這個(gè)更新操作的 "鉤子(hook)"可以使程根據(jù)不同的情況來(lái)處理程序觸發(fā)的繪畫(huà)。程序必須這么設(shè)想,對(duì)paint()的調(diào)用意味著Graphics的裁剪區(qū)"損壞"了并且必須全部重畫(huà);然而對(duì)update()的調(diào)用沒(méi)有這種含義,它使程序做增量的繪畫(huà)。

    如果程序希望只把要增加的內(nèi)容敷蓋于已存在于該部件的像素位之上,那么就使用增量畫(huà)圖操作。UpdateDemo example 示范了一個(gè)利用update()的優(yōu)點(diǎn)做增量繪畫(huà)的程序。

    事實(shí)上,大多數(shù)GUI部件不需要增量繪畫(huà),所有大部分程序可以忽略u(píng)pdate()方法,并且簡(jiǎn)單地覆蓋(override)paint()來(lái)呈現(xiàn)部件的當(dāng)前狀態(tài)。這就意味著不管“系統(tǒng)觸發(fā)”還是“程序觸發(fā)”,在大多數(shù)部件上的表現(xiàn)從其本質(zhì)上講是是等價(jià)的。

    繪畫(huà)與輕量級(jí)部件
    從應(yīng)用開(kāi)發(fā)人員的觀點(diǎn)看,“輕量級(jí)”的繪畫(huà)API基本上和“重量級(jí)”一樣(即,你只需要覆蓋paint()方法,同樣,調(diào)用repaint()方法去觸發(fā)繪圖更新)。然而,因?yàn)锳WT的“輕量級(jí)”部件的框架全部使用普通Java代碼實(shí)現(xiàn),在輕量級(jí)部件上繪畫(huà)機(jī)制的實(shí)現(xiàn)方式有一些微妙的不同。

    ?

    “輕量級(jí)”部件是怎樣被繪制的
    “輕量級(jí)”部件需要一個(gè)處在容器體系上的“重量級(jí)”部件提供進(jìn)行繪畫(huà)的場(chǎng)所。當(dāng)這個(gè)“重量級(jí)”的“祖宗”被告知要繪制自身的窗體時(shí),它必須把這個(gè)繪畫(huà)的請(qǐng)求轉(zhuǎn)化為對(duì)其所有子孫的繪畫(huà)請(qǐng)求。這是由java.awt.Container的paint()方法處理的,該方法調(diào)用包容于其內(nèi)的所有可見(jiàn)的、并且與繪畫(huà)區(qū)相交的輕量級(jí)部件的paint()方法。因此對(duì)于所有覆蓋了paint()方法的Container子類(“輕量級(jí)”或“重量級(jí)”)需要立刻做下面的事情:


    ?? public class MyContainer extends Container {
    ??????? public void paint(Graphics g) {
    ??? // paint my contents first...
    ??? // then, make sure lightweight children paint
    ??? super.paint(g);
    ??????? }
    ??? }

    如果沒(méi)有super.paint(),那么容器(container)的輕量級(jí)子孫類就不會(huì)顯示出來(lái)(這是一個(gè)非常普遍的問(wèn)題,自從JDK1.1初次引進(jìn)“輕量級(jí)”部件之后)。

    這種情況相當(dāng)于注釋掉了默認(rèn)的Container.update()方法的執(zhí)行,從而不能 使用遞歸去調(diào)用其輕量級(jí)子孫類的update()或者paint()方法。這就意味著任何使用update()方法實(shí)現(xiàn)增量繪畫(huà)的重量級(jí)Container子類必須確保其輕量級(jí)子孫在需要時(shí),能夠被它的遞歸操作所調(diào)用從而實(shí)現(xiàn)重畫(huà)。幸運(yùn)的是,只有少數(shù)幾個(gè)重量級(jí)的容器(Container)需要增量繪圖,所以這個(gè)問(wèn)題沒(méi)有影響到大多數(shù)的程序。

    ?

    輕量級(jí)與系統(tǒng)觸發(fā)型的畫(huà)圖
    為輕量級(jí)部件實(shí)現(xiàn)窗體行為(顯示、隱藏、移動(dòng)、改變大小等)的輕量級(jí)框架的代碼全部用Java代碼寫成。經(jīng)常的,在這些功能的Java實(shí)現(xiàn)中,AWT必須明確地吩咐各個(gè)輕量級(jí)部件執(zhí)行繪畫(huà)(實(shí)質(zhì)上講這也是系統(tǒng)觸發(fā)的繪畫(huà),盡管它不是源于本地的 操作系統(tǒng))。而輕量級(jí)框架使用repaint()方法來(lái)吩咐部件執(zhí)行繪畫(huà),這是我們前面解釋過(guò)的,將導(dǎo)致一個(gè)update()的調(diào)用而不是直接地對(duì)paint()的調(diào)用。因此,對(duì)于輕量級(jí),系統(tǒng)觸發(fā)型的畫(huà)圖操作可以遵循下面的兩種途徑:

    系統(tǒng)觸發(fā)的繪畫(huà)要求產(chǎn)生于本地系統(tǒng)(例如,輕量級(jí)的重量級(jí)祖先第一次現(xiàn)身的時(shí)候),這導(dǎo)致對(duì)paint()的直接調(diào)用。
    ?

    系統(tǒng)觸發(fā)型的繪圖要求產(chǎn)生于輕量框架(例如,輕量級(jí)部件的尺寸改變了),這導(dǎo)致對(duì)update()的調(diào)用,該方法進(jìn)而默認(rèn)地調(diào)用paint()。
    簡(jiǎn)單地講,這意味著輕量級(jí)部件在update()和paint()之間沒(méi)有實(shí)質(zhì)的差別,進(jìn)一步講這又意味著“增量的繪圖技術(shù)”不能用到輕量級(jí)部件上。

    輕量級(jí)部件與透明
    因?yàn)檩p量級(jí)部件"借用"了本屬于其“重量級(jí)”祖先的屏幕,所以它們支持“透明”的特征。這樣做是因?yàn)檩p量級(jí)部件是從底往上繪畫(huà),因此如果輕量級(jí)部件遺留一些或者全部它們祖先的像素位而沒(méi)有畫(huà),底層的部件就會(huì)"直接顯示。"出來(lái)。這也是對(duì)于輕量級(jí)部件,update()方法的在默認(rèn)實(shí)現(xiàn)將不再清除背景的原因。

    LightweightDemo 例程示范了輕量級(jí)部件的透明特征。

    "靈活巧妙地"繪畫(huà)方法
    當(dāng)AWT嘗試著使呈現(xiàn)部件的處理盡可能高效率時(shí),部件自身paint()的實(shí)現(xiàn)可能對(duì)整體性能有重大的影響。影響這個(gè)處理過(guò)程的兩個(gè)關(guān)鍵領(lǐng)域是:

    使用裁剪區(qū)來(lái)縮小需要呈現(xiàn)的范圍。


    應(yīng)用內(nèi)部的版面布局信息來(lái)縮小對(duì)子部件的籠罩范圍(僅適用于輕量級(jí)).。
    如果你的部件很簡(jiǎn)單 -- 比如,如果是一個(gè)按鈕 -- 那么就不值得花費(fèi)氣力去改善它的呈現(xiàn)屬性,使它僅僅去繪畫(huà)與修剪區(qū)相交的部分;不理會(huì)Graphics的裁剪區(qū)直接繪制整個(gè)部件反而更劃算。然而,如果你創(chuàng)建的部件界面很復(fù)雜,比如文本部件,那么迫切需要你的代碼使用裁剪信息來(lái)縮小需要繪圖的范圍。

    更進(jìn)一步講,如果你寫了一個(gè)容納了很多部件的復(fù)雜的輕量級(jí)容器,其中的部件和容器的布局管理器,或者只是容器的布局管理器擁有布局的信息,那么就值得使用所知道的布局信息來(lái)更靈活地確定哪個(gè)子部件需要繪畫(huà)。Container.paint()的默認(rèn)實(shí)現(xiàn)只是簡(jiǎn)單地按順序遍歷子部件,檢查它是否可見(jiàn)、是否與重?fù)Q區(qū)域相交 -- 對(duì)于某幾個(gè)布局管理這種操作就顯得不必要的羅嗦。比如,如果容器在100*100的格子里布置部件,那么格子的信息就可以用來(lái)更快得確定這10,000個(gè)部件中哪個(gè)與裁剪框相交,哪個(gè)就確實(shí)需要繪制。


    AWT繪畫(huà)準(zhǔn)則
    AWT為繪制部件提供了一個(gè)簡(jiǎn)單的回調(diào)API。當(dāng)你使用它是,要遵循下面的原則:

    對(duì)于大多數(shù)程序,所有的客戶區(qū)繪畫(huà)代碼應(yīng)該被放置在部件的paint()方法中。
    ?

    通過(guò)調(diào)用repaint()方法,程序可以觸發(fā)一個(gè)將來(lái)執(zhí)行的paint()調(diào)用,不能直接調(diào)用paint()方法。
    ?

    對(duì)于界面復(fù)雜的部件,應(yīng)該觸發(fā)帶參數(shù)的repaint()方法,使用參數(shù)定義實(shí)際需要更新的區(qū)域;而不帶參數(shù)調(diào)用會(huì)導(dǎo)致整個(gè)部件被重畫(huà)。
    ?

    因?yàn)閷?duì)repaint()的調(diào)用會(huì)首先導(dǎo)致update()的調(diào)用,默認(rèn)地會(huì)促成paint()的調(diào)用,所以重量級(jí)部件應(yīng)該覆蓋update()方法以實(shí)現(xiàn)增量繪制,如果需要的話(輕量級(jí)部件不支持增量繪制) 。
    ?

    覆蓋了paint()方法的java.awt.Container子類應(yīng)當(dāng)在paint()方法中調(diào)用super.paint()以保證子部件能被繪制。
    ?

    界面復(fù)雜的部件應(yīng)該靈活地使用裁剪區(qū)來(lái)把繪畫(huà)范圍縮小到只包括與裁剪區(qū)相交的范圍。

    在Swing中的繪畫(huà)

    Swing起步于AWT基本繪畫(huà)模式,并且作了進(jìn)一步的擴(kuò)展以獲得最大化的性能以及改善可擴(kuò)展性能。象AWT一樣,Swing支持回調(diào)繪畫(huà)以及使用repaint()促使部件更新。另外,Swing提供了內(nèi)置的雙緩沖(double-buffering)并且作了改變以支持Swing的其它結(jié)構(gòu)(象邊框(border)和UI代理)。最后,Swing為那些想更進(jìn)一步定制繪畫(huà)機(jī)制的程序提供了RepaintManager API。

    對(duì)雙緩沖的支持
    Swing的最引人注目的特性之一就是把對(duì)雙緩沖的支持整個(gè)兒的內(nèi)置到工具包。通過(guò)設(shè)置javax.swing.JComponent的"doubleBuffered"屬性就可以使用雙緩沖:

    ???? public boolean isDoubleBuffered()
    ??? public void setDoubleBuffered(boolean o)
    當(dāng)緩沖激活的時(shí)候,Swing的雙緩沖機(jī)制為每個(gè)包容層次(通常是每個(gè)最高層的窗體)準(zhǔn)備一個(gè)單獨(dú)的屏外緩沖。并且,盡管這個(gè)屬性可以基于部件而設(shè)置,對(duì)一個(gè)特定的容器上設(shè)置這個(gè)屬性,將會(huì)影響到這個(gè)容器下面的所有輕量級(jí)部件把自己的繪畫(huà)提交給屏外緩沖,而不管它們各自的"雙緩沖"屬性值

    默認(rèn)地,所有Swing部件的該屬性值為true。不過(guò)對(duì)于JRootPane這種設(shè)置確實(shí)有些問(wèn)題,因?yàn)檫@樣就使所有位于這個(gè)上層Swing部件下面的所有部件都使用了雙緩沖。對(duì)于大多數(shù)的Swing程序,不需要作任何特別的事情就可以使用雙緩沖,除非你要決定這個(gè)屬性是開(kāi)還是關(guān)(并且為了使GUI能夠平滑呈現(xiàn),你需要打開(kāi)這個(gè)屬性)。Swing保證會(huì)有適宜的Graphics對(duì)象(或者是為雙緩沖使用的屏外映像的Graphics,或者是正規(guī)的Graphics)傳遞給部件的繪畫(huà)回調(diào)函數(shù),所以,部件需要做的所有事情僅僅就是使用這個(gè)Graphics畫(huà)圖。本文的后面,在繪制的處理過(guò)程這一章會(huì)詳細(xì)解釋這個(gè)機(jī)制。

    其他的繪畫(huà)屬性
    為了改善內(nèi)部的繪畫(huà)算法性能,Swing另外引進(jìn)了幾個(gè)JComponent的相互有關(guān)聯(lián)的屬性。引入這些屬性為的是處理下面兩個(gè)問(wèn)題,這兩個(gè)問(wèn)題有可能導(dǎo)致輕量級(jí)部件的繪畫(huà)成本過(guò)高:

    透明(Transparency): 當(dāng)一個(gè)輕量級(jí)部件的繪畫(huà)結(jié)束時(shí),如果該部件的一部分或者全部透明,那么它就可能不會(huì)把所有與其相關(guān)的像素位都涂上顏色;這就意味著不管它什么時(shí)候重畫(huà),它底層的部件必須首先重畫(huà)。這個(gè)技術(shù)需要系統(tǒng)沿著部件的包容層次去找到最底層的重量級(jí)祖先,然后從它開(kāi)始、從后向前地執(zhí)行繪畫(huà)。
    重疊的部件(Overlapping components): 當(dāng)一個(gè)輕量級(jí)部件的繪畫(huà)結(jié)束是,如果有一些其他的輕量級(jí)部件部分地疊加在它的上方;就是說(shuō),不管最初的輕量級(jí)部件什么時(shí)候畫(huà)完,只要有疊加在它上面的其它部件(裁剪區(qū)與疊加區(qū)相交),這些疊加的部件必須也要部分地重畫(huà)。這需要系統(tǒng)在每次繪畫(huà)時(shí)要遍歷大量的包容層次,以檢查與之重疊的部件。
    遮光性
    ?

    在一般情況下部件是不透明的,為了提高改善性能,Swing增加了讀寫javax.swing.JComponent的遮光(opaque)屬性的操作:

    ??? public boolean isOpaque()
    ??? public void setOpaque(boolean o)

    這些設(shè)置是:

    true:部件同意在它的矩形范圍包含的里所有像素位上繪畫(huà)。
    false:部件不保證其矩形范圍內(nèi)所有像素位上繪畫(huà)。
    遮光(opaque)屬性允許Swing的繪圖系統(tǒng)去檢測(cè)是否一個(gè)對(duì)指定部件的重畫(huà)請(qǐng)求會(huì)導(dǎo)致額外的對(duì)其底層祖先的重畫(huà)。每個(gè)標(biāo)準(zhǔn)Swing部件的默認(rèn)(遮光)opaque屬性值由當(dāng)前的視-感UI對(duì)象設(shè)定。而對(duì)于大多數(shù)部件,該值為true。

    部件實(shí)現(xiàn)中的一個(gè)最常見(jiàn)的錯(cuò)誤是它們?cè)试S遮光(opaque)屬性保持其默認(rèn)值true,卻又不完全地呈現(xiàn)它們所轄的區(qū)域,其結(jié)果就是沒(méi)有呈現(xiàn)的部分有時(shí)會(huì)造成屏幕垃圾。當(dāng)一個(gè)部件設(shè)計(jì)完畢,應(yīng)該仔細(xì)的考慮所控制的遮光(opaque)屬性,既要確保透的使用是明智的,因?yàn)樗鼤?huì)花費(fèi)更多的繪畫(huà)時(shí)間,又要確保與繪畫(huà)系統(tǒng)之間的協(xié)約履行。

    遮光(opaque)屬性的意義經(jīng)常被誤解。有時(shí)候被用來(lái)表示“使部件的背景透明”。然而這不是Swing對(duì)遮光的精確解釋。一些部件,比如按鈕,為了給部件一個(gè)非矩形的外形可能會(huì)把“遮光”設(shè)置為false,或者為了短時(shí)間的視覺(jué)效果使用一個(gè)矩形框圍住部件,例如焦點(diǎn)指示框。在這些情況下,部件不遮光,但是其背景的主要部分仍然需要填充。

    如先前的定義,遮光屬性的本質(zhì)是一個(gè)與負(fù)責(zé)重畫(huà)的系統(tǒng)之間訂立的契約。如果一個(gè)部件使用遮光屬性去定義怎樣使部件的外觀透明,那么該屬性的這種使用就應(yīng)該備有證明文件。(一些部件可能更合適于定義額外的屬性控制外觀怎樣怎樣增加透明度。例如,javax.swing.AbstractButton提供ContentAreaFilled屬性就是為了達(dá)到這個(gè)目的。)

    另一個(gè)毫無(wú)價(jià)值的問(wèn)題是遮光屬性與Swing部件的邊框(border)屬性有多少聯(lián)系。在一個(gè)部件上,由Border對(duì)象呈現(xiàn)的區(qū)域從幾何意義上講仍是部件的一部分。就是說(shuō)如果部件遮光,它就有責(zé)任去填充邊框所占用的空間。(然后只需要把邊框放到該不透明的部件之上就可以了)。

    如果你想使一個(gè)部件允許其底層部件能透過(guò)它的邊框范圍而顯示出來(lái) -- 即,通過(guò)isBorderOpaque()判斷border是否支持透明而返回值為false -- 那么部件必須定義自身的遮光屬性為false并且確保它不在邊框的范圍內(nèi)繪圖。

    "最佳的"繪畫(huà)方案
    部件重疊的問(wèn)題有些棘手。即使沒(méi)有直接的兄弟部件疊加在該部件之上,也總是可能有非直系繼承關(guān)系(比如"堂兄妹"或者"姑嬸")的部件會(huì)與它交疊。這樣的情況下,處于一個(gè)復(fù)雜層次中的每個(gè)部件的重畫(huà)工作都需要一大堆的樹(shù)遍歷來(lái)確保'正確地'繪畫(huà)。為了減少不必要的遍歷,Swing為javax.swing.JComponent增加一個(gè)只讀的isOptimizedDrawingEnabled屬性:

    ??? public boolean isOptimizedDrawingEnabled()
    這些設(shè)置是:


    true:部件指示沒(méi)有直接的子孫與其重疊。

    false: 部件不保證有沒(méi)有直接的子孫與之交疊。
    通過(guò)檢查isOptimizedDrawingEnabled屬性,Swing在重畫(huà)時(shí)可以快速減少對(duì)交疊部件的搜索。

    因?yàn)閕sOptimizedDrawingEnabled屬性是只讀的,于是部件改變默認(rèn)值的唯一方法是在其子類覆蓋(override)這個(gè)方法來(lái)返回所期望的值。除了JLayeredPane,JDesktopPane,和JViewPort外,所有標(biāo)準(zhǔn)Swing部件對(duì)這個(gè)屬性返回true。

    繪畫(huà)方法
    適應(yīng)于AWT的輕量級(jí)部件的規(guī)則同樣也適用于Swing部件 -- 舉一個(gè)例子,在部件需要呈現(xiàn)的時(shí)候就會(huì)調(diào)用paint() -- 只是Swing更進(jìn)一步地把paint()的調(diào)用分解為3個(gè)分立的方法,以下列順序依次執(zhí)行:

    ???? protected void paintComponent(Graphics g)
    ??? protected void paintBorder(Graphics g)
    ??? protected void paintChildren(Graphics g)
    Swing程序應(yīng)該覆蓋paintComponent()而不是覆蓋paint()。雖然API允許這樣做,但通常沒(méi)有理由去覆蓋paintBorder()或者paintComponents()(如果你這么做了,請(qǐng)確認(rèn)你知道你到底在做什么!)。這個(gè)分解使得編程變得更容易,程序可以只覆蓋它們需要擴(kuò)展的一部分繪畫(huà)。例如,這樣就解決先前在AWT中提到的問(wèn)題,因?yàn)檎{(diào)用super.paint()失敗而使得所有輕量級(jí)子孫都不能顯示。

    SwingPaintDemo例子程序舉例說(shuō)明了Swing的paintComponent()回調(diào)方法的簡(jiǎn)單應(yīng)用。

    繪畫(huà)與UI代理
    大多數(shù)標(biāo)準(zhǔn)Swing部件擁有它們自己的、由分離的觀-感(look-and-feel)對(duì)象(叫做"UI代理")實(shí)現(xiàn)的觀-感。這意味著標(biāo)準(zhǔn)部件把大多數(shù)或者所有的繪畫(huà)委派給UI代理,并且出現(xiàn)在下面的途徑:

    paint()觸發(fā)paintComponent()方法。
    如果ui屬性為non-null,paintComponent()觸發(fā)ui.update()。
    如果部件的遮光屬性為true,ui.udpate()方法使用背景顏色填充部件的背景并且觸發(fā)ui.paint()。
    ui.paint()呈現(xiàn)部件的內(nèi)容。
    這意味著Swing部件的擁有UI代理的子類(相對(duì)于JComponent的直系子類),應(yīng)該在它們所覆蓋的paintComponent方法中觸發(fā)super.paintComponent()。


    ??? public class MyPanel extends JPanel {
    ??????? protected void paintComponent(Graphics g) {
    ??? // Let UI delegate paint first
    ??? // (including background filling, if I'm opaque)
    ??? super.paintComponent(g);
    ??? // paint my contents next....
    ??????? }
    ??? }

    如果因?yàn)槟承┰虿考臄U(kuò)展類不允許UI代理去執(zhí)行繪畫(huà)(是如果,例如,完全更換了部件的外觀),它可以忽略對(duì)super.paintComponent()的調(diào)用,但是它必須負(fù)責(zé)填充自己的背景,如果遮光(opaque)屬性為true的話,如前面在遮光(opaque)屬性一章講述的。

    繪畫(huà)的處理過(guò)程
    Swing處理"repaint"請(qǐng)求的方式與AWT有稍微地不同,雖然對(duì)于應(yīng)用開(kāi)發(fā)人員來(lái)講其本質(zhì)是相同的 -- 同樣是觸發(fā)paint()。Swing這么做是為了支持它的RepaintManager API (后面介紹),就象改善繪畫(huà)性能一樣。在Swing里的繪畫(huà)可以走兩條路,如下所述:

    (A) 繪畫(huà)需求產(chǎn)生于第一個(gè)重量級(jí)祖先(通常是JFrame、JDialog、JWindow或者JApplet):

    事件分派線程調(diào)用其祖先的paint()
    ?

    Container.paint()的默認(rèn)實(shí)現(xiàn)會(huì)遞歸地調(diào)用任何輕量級(jí)子孫的paint()方法。
    ?

    當(dāng)?shù)竭_(dá)第一個(gè)Swing部件時(shí),JComponent.paint()的默認(rèn)執(zhí)行做下面的步驟:
    如果部件的雙緩沖屬性為true并且部件的RepaintManager上的雙緩沖已經(jīng)激活,將把Graphics對(duì)象轉(zhuǎn)換為一個(gè)合適的屏外Graphics。
    調(diào)用paintComponent()(如果使用雙緩沖就把屏外Graphics傳遞進(jìn)去)。
    調(diào)用paintChildren()(如果使用雙緩沖就把屏外Graphics傳遞進(jìn)去),該方法使用裁剪并且遮光和optimizedDrawingEnabled等屬性來(lái)嚴(yán)密地判定要遞歸地調(diào)用哪些子孫的paint()。
    如果部件的雙緩沖屬性為true并且在部件的RepaintManager上的雙緩沖已經(jīng)激活,使用最初的屏幕Graphics對(duì)象把屏外映像拷貝到部件上。


    注意:JComponent.paint()步驟#1和#5在對(duì)paint()的遞歸調(diào)用中被忽略了(由于paintChildren(),在步驟#4中介紹了),因?yàn)樗性趕wing窗體層次中的輕量級(jí)部件將共享同一個(gè)用于雙緩沖的屏外映像。

    (B) 繪畫(huà)需求從一個(gè)javax.swing.JComponent擴(kuò)展類的repaint()調(diào)用上產(chǎn)生:

    JComponent.repaint()注冊(cè)一個(gè)針對(duì)部件的RepaintManager的異步的重畫(huà)需求,該操作使用invokeLater()把一個(gè)Runnable加入事件隊(duì)列以便稍后執(zhí)行在事件分派線程上的需求。
    ?

    該Runnable在事件分派線程上執(zhí)行并且導(dǎo)致部件的RepaintManager調(diào)用該部件上paintImmediately(),該方法執(zhí)行下列步驟:


    使用裁剪框以及遮光和optimizedDrawingEnabled屬性確定“根”部件,繪畫(huà)一定從這個(gè)部件開(kāi)始(處理透明以及潛在的重疊部件)。
    如果根部件的雙緩沖屬性為true,并且根部件的RepaintManager上的雙緩沖已激活,將轉(zhuǎn)換Graphics對(duì)象到適當(dāng)?shù)钠镣釭raphics。
    調(diào)用根部件(該部件執(zhí)行上述(A)中的JComponent.paint()步驟#2-4)上的paint(),導(dǎo)致根部件之下的、與裁剪框相交的所有部件被繪制。
    如果根部件的doubleBuffered屬性為true并且根部件的RepaintManager上的雙緩沖已經(jīng)激活,使用原始的Graphics把屏外映像拷貝到部件。


    注意:如果在重畫(huà)沒(méi)有完成之前,又有發(fā)生多起對(duì)部件或者任何一個(gè)其祖先的repaint()調(diào)用,所有這些調(diào)用會(huì)被折疊到一個(gè)單一的調(diào)用 回到paintImmediately() on topmostSwing部件 on which 其repaint()被調(diào)用。例如,如果一個(gè)JTabbedPane包含了一個(gè)JTable并且在其包容層次中的現(xiàn)有的重畫(huà)需求完成之前兩次發(fā)布對(duì)repaint()的調(diào)用,其結(jié)果將變成對(duì)該JTabbedPane部件的paintImmediately()方法的單一調(diào)用,會(huì)觸發(fā)兩個(gè)部件的paint()的執(zhí)行。

    這意味著對(duì)于Swing部件來(lái)說(shuō),update()不再被調(diào)用。

    雖然repaint()方法導(dǎo)致了對(duì)paintImmediately()的調(diào)用,它不考慮"回調(diào)"繪圖,并且客戶端的繪畫(huà)代碼也不會(huì)放置到paintImmediately()方法里面。實(shí)際上,除非有特殊的原因,根本不需要超載paintImmediately()方法。

    同步繪圖
    象我們?cè)谇懊嬲鹿?jié)所講述的,paintImmediately()表現(xiàn)為一個(gè)入口,用來(lái)通知Swing部件繪制自身,確認(rèn)所有需要的繪畫(huà)都能適當(dāng)?shù)禺a(chǎn)生。這個(gè)方法也可能用來(lái)安排同步的繪圖需求,就象它的名字所暗示的,即一些部件有時(shí)候需要保證它們的外觀實(shí)時(shí)地與其內(nèi)部狀態(tài)保持一致(例如,在JScrollPane執(zhí)行滾定操作的時(shí)候確實(shí)需要這樣并且也做到了)。

    程序不應(yīng)該直接調(diào)用這個(gè)方法,除非有合理實(shí)時(shí)繪畫(huà)需要。這是因?yàn)楫惒降膔epaint()可以使多個(gè)重復(fù)的需求得到有效的精簡(jiǎn),反之直接調(diào)用paintImmediately()則做不到這點(diǎn)。另外,調(diào)用這個(gè)方法的規(guī)則是它必須由事件分派線程中的進(jìn)程調(diào)用;它也不是為能以多線程運(yùn)行你的繪畫(huà)代碼而設(shè)計(jì)的。關(guān)于Swing單線程模式的更多信息,參考一起歸檔的文章"Threads and Swing."

    RepaintManager
    Swing的RepaintManager類的目的是最大化地提高Swing包容層次上的重畫(huà)執(zhí)行效率,同時(shí)也實(shí)現(xiàn)了Swing的'重新生效'機(jī)制(作為一個(gè)題目,將在其它文章里介紹)。它通過(guò)截取所有Swing部件的重畫(huà)需求(于是它們不再需要經(jīng)由AWT處理)實(shí)現(xiàn)了重畫(huà)機(jī)制,并且在需要更新的情況下維護(hù)其自身的狀態(tài)(我們已經(jīng)知道的"dirty regions")。最后,它使用invokeLater()去處理事件分派線程中的未決需求,如同在"Repaint Processing"一節(jié)中描述的那樣(B選項(xiàng)).

    對(duì)于大多數(shù)程序來(lái)講,RepaintManager可以看做是Swing的內(nèi)部系統(tǒng)的一部分,并且甚至可以被忽略。然而,它的API為程序能更出色地控制繪畫(huà)中的幾個(gè)要素提供了選擇。

    ?

    "當(dāng)前的"RepaintManager
    RepaintManager設(shè)計(jì) is designed to be dynamically plugged, 雖然 有一個(gè)單獨(dú)的接口。下面的靜態(tài)方法允許程序得到并且設(shè)置"當(dāng)前的"RepaintManager:

    ???? public static RepaintManager currentManager(Component c)
    ??? public static RepaintManager currentManager(JComponent c)
    ??? public static void
    ???????? setCurrentManager(RepaintManager aRepaintManager)
    更換"當(dāng)前的"RepaintManager
    總的說(shuō)來(lái),程序通過(guò)下面的步驟可能會(huì)擴(kuò)展并且更換RepaintManager:

    ??? RepaintManager.setCurrentManager(new MyRepaintManager());
    你也可以參考RepaintManagerDemo ,這是個(gè)簡(jiǎn)單的舉例說(shuō)明RepaintManager加載的例子,該例子將把有關(guān)正在執(zhí)行重畫(huà)的部件的信息打印出來(lái)。

    擴(kuò)展和替換RepaintManager的一個(gè)更有趣的動(dòng)機(jī)是可以改變對(duì)重畫(huà)的處理方式。當(dāng)前,默認(rèn)的重畫(huà)實(shí)現(xiàn)所使用的來(lái)跟蹤dirty regions的內(nèi)部狀態(tài)值是包內(nèi)私有的并且因此不能被繼承類訪問(wèn)。然而,程序可以實(shí)現(xiàn)它們自己的跟蹤dirty regions的機(jī)制并且通過(guò)超載下面的方法對(duì)重畫(huà)需求的縮減:

    ???? public synchronized void
    ????? addDirtyRegion(JComponent c, int x, int y, int w, int h)
    ??? public Rectangle getDirtyRegion(JComponent aComponent)
    ??? public void markCompletelyDirty(JComponent aComponent)
    ??? public void markCompletelyClean(JComponent aComponent) {
    addDirtyRegion()方法是在調(diào)用Swing部件的repaint()的之后被調(diào)用的,因此可以用作鉤子來(lái)捕獲所有的重畫(huà)需求。如果程序超載了這個(gè)方法(并且不調(diào)用super.addDirtyRegion()),那么它改變了它的職責(zé),而使用invokeLater()把Runnable放置到EventQueue ,該隊(duì)列將在合適的部件上調(diào)用paintImmediately()(translation: not for the faint of heart).

    從全局控制雙緩沖
    RepaintManager提供了從全局中激活或者禁止雙緩沖的API:

    ???? public void setDoubleBufferingEnabled(boolean aFlag)
    ??? public boolean isDoubleBufferingEnabled()
    這個(gè)屬性在繪畫(huà)處理的時(shí)候,在JComponent的內(nèi)部檢查過(guò)以確定是否使用屏外緩沖顯示部件。這個(gè)屬性默認(rèn)為true,但是如果程序希望在全局范圍為所有Swing部件關(guān)閉雙緩沖的使用,可以按照下面的步驟做:

    ??? RepaintManager.currentManager(mycomponent).
    ????????????????? setDoubleBufferingEnabled(false);
    注意:因?yàn)镾wing的默認(rèn)實(shí)現(xiàn)要初始化一個(gè)單獨(dú)的RepaintManager實(shí)例,mycomponent參數(shù)與此不相關(guān)。


    Swing繪畫(huà)準(zhǔn)則
    Swing開(kāi)發(fā)人員在寫繪畫(huà)代碼時(shí)應(yīng)該理解下面的準(zhǔn)則:

    對(duì)于Swing部件,不管是系統(tǒng)-觸發(fā)還是程序-觸發(fā)的請(qǐng)求,總會(huì)調(diào)用paint()方法;而update()不再被Swing部件調(diào)用。
    ?

    程序可以通過(guò)repaint()觸發(fā)一個(gè)異步的paint()調(diào)用,但是不能直接調(diào)用paint()。
    ?

    對(duì)于復(fù)雜的界面,應(yīng)該調(diào)用帶參數(shù)的repaint(),這樣可以僅僅更新由該參數(shù)定義的區(qū)域;而不要調(diào)用無(wú)參數(shù)的repaint(),導(dǎo)致整個(gè)部件重畫(huà)。
    ?

    Swing中實(shí)現(xiàn)paint()的3個(gè)要素是調(diào)用3個(gè)分離的回調(diào)方法:
    paintComponent()
    paintBorder()
    paintChildren()
    Swing部件的子類,如果想執(zhí)行自己的繪畫(huà)代碼,應(yīng)該把自己的繪畫(huà)代碼放在paintComponent()方法的范圍之內(nèi)。(不要放在paint()里面)。
    ?

    Swing引進(jìn)了兩個(gè)屬性來(lái)最大化的改善繪畫(huà)的性能:
    opaque: 部件是否要重畫(huà)它所占據(jù)范圍中的所有像素位?
    optimizedDrawingEnabled: 是否有這個(gè)部件的子孫與之交疊?
    ?

    如故Swing部件的(遮光)opaque屬性設(shè)置為true,那就表示它要負(fù)責(zé)繪制它所占據(jù)的范圍內(nèi)的所有像素位(包括在paintComponent()中清除它自己的背景),否則會(huì)造成屏幕垃圾。
    把一個(gè)部件設(shè)置為遮光(opaque)同時(shí)又把它的optimizedDrawingEnabled屬性設(shè)置為false,將導(dǎo)致在每個(gè)繪畫(huà)操作中要執(zhí)行更多的處理,因此我們推薦的明智的方法是同時(shí)使用透明并且交疊部件。

    使用UI代理(包括JPanel)的Swing部件的擴(kuò)展類的典型作法是在它們自己的paintComponent()的實(shí)現(xiàn)中調(diào)用super.paintComponent()。因?yàn)閁I代理可以負(fù)責(zé)清除一個(gè)遮光部件的背景,這將照顧到#5.

    Swing通過(guò)JComponent的doubleBuffered屬性支持內(nèi)置的雙緩沖,所有的Swing部件該屬性默認(rèn)值是true,然而把Swing容器的遮光設(shè)置為true有一個(gè)整體的構(gòu)思,把該容器上的所有輕量級(jí)子孫的屬性打開(kāi),不管它們各自的設(shè)定。

    強(qiáng)烈建議為所有的Swing部件使用雙緩沖。

    界面復(fù)雜的部件應(yīng)該靈活地運(yùn)用剪切框來(lái),只對(duì)那些與剪切框相交的區(qū)域進(jìn)行繪畫(huà)操作,從而減少工作量。

    總結(jié)
    不管AWT還是Swing都提供了方便的編程手段使得部件內(nèi)容能夠正確地顯示到屏幕上。雖然對(duì)于大多數(shù)的GUI需要我們推薦使用Swing,但是理解AWT的繪畫(huà)機(jī)制也會(huì)給我們帶來(lái)幫助,因?yàn)镾wing建立在它的基礎(chǔ)上。

    關(guān)于AWT和Sing的特點(diǎn)就介紹到這里,應(yīng)用開(kāi)發(fā)人員應(yīng)該盡力按照本文中介紹的準(zhǔn)則來(lái)撰寫代碼,充分發(fā)揮這些API功能,使自己的程序獲得最佳性能。

     
    ?

    posted @ 2006-08-01 09:37 sunfruit 閱讀(453) | 評(píng)論 (1)編輯 收藏

    浙大高分子物理鄭強(qiáng)教授的激情演講摘錄

    ????浙大高分子物理鄭強(qiáng)教授的激情演講摘錄?

    ??? 作為一個(gè)學(xué)者,我不是來(lái)賣弄嘴皮子的。借助這個(gè)講壇,我認(rèn)為各行各業(yè)對(duì)知識(shí)的接受是潛移默化,循序漸近的過(guò)程。下面從自然科學(xué)的角度來(lái)談?wù)勎业囊恍┯^點(diǎn),我提出幾個(gè)重大問(wèn)題:
    ??? 第一,我國(guó)搞了幾十年的科學(xué)研究與攻關(guān),在幾十個(gè)工業(yè)門類中,到底有哪幾個(gè)是屬于中國(guó)的民族工業(yè)或者可以稱為自己的工業(yè)的?到底有哪幾項(xiàng)科研在國(guó)際上是數(shù)一數(shù)二的?中國(guó)現(xiàn)在到底需要什么?我經(jīng)常出國(guó),每出一次國(guó),靈魂就受到一次洗禮,就巴不得在回來(lái)的第二天就去中小學(xué)講。為什么?就是感到緊迫的壓力和羞愧,特別是去了日本和韓國(guó),這兩個(gè)同屬于東方國(guó)家去了之后,感觸更多。

    ??? 下面這四個(gè)方面,是近5年吹得最厲害的。先說(shuō)超導(dǎo),這也是從美國(guó)人開(kāi)始的。我是一個(gè)教授,在浙大當(dāng)老師,浙大的“求是”是個(gè)無(wú)價(jià)之寶?,F(xiàn)在中國(guó)的知識(shí)分子有個(gè)弱點(diǎn),就是不喜歡人家說(shuō)自己的缺陷,更不愿意自己說(shuō)自己的缺陷。我今天就愿意來(lái)揭揭自己的短,面對(duì)產(chǎn)業(yè)家,我更應(yīng)該說(shuō)實(shí)話。
    中國(guó)今天的科技很多都是“跟蹤”,這也難為中國(guó)的教授,因?yàn)槿兆舆^(guò)得較苦,沒(méi)有錢,加上很多領(lǐng)導(dǎo)同志本身也沒(méi)有知識(shí),為了蒙領(lǐng)導(dǎo),讓他們撥一點(diǎn)錢,總得把一些文章、報(bào)告、口號(hào)寫得越高越好。比如,現(xiàn)在教育界號(hào)稱“建世界第一流大學(xué)”,教育部跨世紀(jì)發(fā)展計(jì)劃中定的10所大學(xué),現(xiàn)在已選定了9所,第10所還未選出。在中國(guó)這個(gè)發(fā)展中國(guó)家,你能建10所世界一流大學(xué),那美國(guó)有多少所?日本有多少所?現(xiàn)在的實(shí)際狀況是:世界上前200所大學(xué),中國(guó)一所都排不進(jìn)!在亞洲能排出幾所?我到國(guó)外去看了以后,感到要將浙大建成世界一流大學(xué)就像共產(chǎn)主義理想,我們永遠(yuǎn)要努力!但是,我們不應(yīng)該去追求這樣虛幻的目標(biāo),去呼這樣的口號(hào),我們的差距還很大。
    現(xiàn)在的幾個(gè)行業(yè)也是前幾年套著中國(guó)科技產(chǎn)業(yè)目標(biāo)走得幾個(gè)方向。像納米,它只不過(guò)是一個(gè)尺度概念。各種尺度的材料都有各自的用處,比如,為什么要把泥土拿來(lái)做成磚,磚的尺度比沙泥要大得多,因?yàn)樾〉纳沉](méi)有強(qiáng)度。我們?cè)趺茨馨沿S富多彩的物質(zhì)世界只說(shuō)成是一個(gè)納米呢?所以,誰(shuí)都沒(méi)有注意是誰(shuí)提出的這個(gè)口號(hào)的,其實(shí)我們又中了美國(guó)人的圈套!這與軍備競(jìng)賽是一樣的。超導(dǎo)中國(guó)科學(xué)院在搞;基因上海在搞;納米全國(guó)在搞,連工廠技術(shù)員也在搞。
    ??? 剛才何祚庥先生講的懸浮列車,不要以為上海的高樓大廈與東京、大阪一樣,中國(guó)就現(xiàn)代化了。修一個(gè)房子、修一座橋非常容易,但你要看看國(guó)民素質(zhì)到了一個(gè)什么樣的階段。日本大樓里走出來(lái)的人都是受過(guò)高等教育的;而我們上海的大廈里走出來(lái)的人卻都是些腰纏萬(wàn)貫的文盲!怎么能說(shuō)國(guó)家已經(jīng)現(xiàn)代化了?浙江杭州搞的世貿(mào)會(huì)挺漂亮,但你可以去西溪河看看,如果西溪河能出現(xiàn)小鳥(niǎo)、天鵝,杭州就現(xiàn)代化了,這不是一個(gè)穿一件衣服的問(wèn)題。我們最需要的是什么?我們不要用這些東西來(lái)擺樣子!我們應(yīng)該關(guān)注我國(guó)的哪幾個(gè)方面?
    這是我的一些建議,提出的一些口號(hào),以前說(shuō)“無(wú)知無(wú)畏”,現(xiàn)在卻是“無(wú)知才無(wú)畏“,許多企業(yè)把浙江省技術(shù)監(jiān)督局、科委的人請(qǐng)來(lái)吃一頓飯,喝一點(diǎn)酒,他就給你簽個(gè)字,再把我們這些教授脅迫到那里去,給你蓋個(gè)章,然后就是“填補(bǔ)國(guó)內(nèi)外空白“、“國(guó)際先進(jìn)水平”,寫論文則是“國(guó)際領(lǐng)先水平的研究成果”、“首次科學(xué)發(fā)現(xiàn)“等等,這都是目前非常嚴(yán)重的問(wèn)題!作為一個(gè)大學(xué)教授,我深深地為此擔(dān)憂!這不是我們的責(zé)任,是我們的領(lǐng)導(dǎo)無(wú)知,是他們倡導(dǎo)了這個(gè)主流。
    ??? 我知道在座的處長(zhǎng)或老總?cè)兆雍茈y過(guò),因?yàn)槟銈儾粚戇@樣的報(bào)表,就拿不到錢,項(xiàng)目就得不到批準(zhǔn)。教授也同樣如此,天天寫報(bào)告,而不是在實(shí)驗(yàn)室靜下心來(lái)好好搞研究,這是很嚴(yán)重的!科學(xué)家說(shuō),納米無(wú)所不能,這一說(shuō),大家就都去搞納米了;老板說(shuō):納米商機(jī)無(wú)限,再不上就沒(méi)有機(jī)會(huì)了,因此,寧波想干,諸暨想干,天臺(tái)也想干,大家都來(lái)搞納米??茖W(xué)家知道納米不穩(wěn)定,它做成材料就聚集在一起,但產(chǎn)業(yè)家并不知道這一點(diǎn)。有人說(shuō),納米這么好,我們都變成納米人多好,但高的籃球誰(shuí)打? 籃框得降低了。納米人的作用可否用在腦血栓治療上,不用吃藥,腦袋上挖個(gè)小孔,讓納米人鉆進(jìn)去清理一下就行了。
    ??? 這些東西可能只有我在說(shuō)不好。納米在最近的一二個(gè)月里在浙江炒得很厲害,什么“納米冰箱能防霉”,我就不明白:一個(gè)是生物學(xué)與衛(wèi)生學(xué)的概念、一個(gè)是材料尺寸的納米怎么會(huì)防霉?所以,要千萬(wàn)注意,無(wú)知的人騙起人來(lái)不得了,因?yàn)樗懽哟螅裁炊几艺f(shuō),所以說(shuō):“無(wú)知才無(wú)畏”,我們懂一點(diǎn)的就不敢隨便講,這是誤導(dǎo)!現(xiàn)在,讓科學(xué)界的人感到很困惑:許多與納米研究無(wú)關(guān),不具備納米科研的單位都在上納米項(xiàng)目,開(kāi)設(shè)了許多新的戰(zhàn)場(chǎng)。作為商界的人士,這個(gè)投入是風(fēng)險(xiǎn)投入,所得到的絕對(duì)回報(bào)是非常危險(xiǎn)的。越是高科技的東西,越不要指望它的市場(chǎng)回報(bào),這個(gè)概念是我今天提出的。
    ??? 新聞界的人在干什么?新聞界的同志喜歡寫一些新東西。我知道,沒(méi)有新東西寫起來(lái)不精彩。誤導(dǎo)與新聞界有關(guān),新聞界聽(tīng)到一點(diǎn)就是一個(gè)片,如此描述宣傳以致于浙江的報(bào)紙整版整版地寫納米。我特別地告誡大家,這是把整個(gè)一個(gè)學(xué)科的概念搞得非常庸俗!
    下面我談?wù)効萍紗?wèn)題。我們整個(gè)國(guó)家民族工業(yè)的基礎(chǔ)極其脆弱,這幾年我在日本商店購(gòu)物,日本的襪子、手巾、低檔毛衣、低檔服裝全都是中國(guó)產(chǎn)的,這是否感到光榮?
    ?? 其實(shí),我們所謂的外資合營(yíng)企業(yè),所引進(jìn)的東西,真正有科技的含量極少,這就是我們的天真,就是我們領(lǐng)導(dǎo)的天真!
    比如,東京這么大的城市,全部的電視頻道就只有6個(gè),杭州有多少個(gè)?這是很清楚的。拿什么錢吃什么飯,我們現(xiàn)在是在吃國(guó)家的飯,所以,開(kāi)了這么多頻道不怕賠也不怕賺,而日本就不能這樣。
    我在日本10天,沒(méi)有看到一條有關(guān)中國(guó)的消息,這也是中國(guó)人的天真。廣島亞運(yùn)會(huì)在日本召開(kāi)時(shí),有哪一個(gè)中國(guó)人得金牌的鏡頭能在日本的電視上看得到?
    ??? 日本人喜歡下圍棋,但他不知道聶衛(wèi)平是誰(shuí)。我國(guó)現(xiàn)在是需要國(guó)際化,但國(guó)際化了以后連自己的祖宗是誰(shuí)都不知道了,連自己的民族文化是什么都不知道了,所以我要說(shuō),改革開(kāi)放20年,我們到底在經(jīng)濟(jì)上,科技上得到了什么?
    好的是有的,但作為一個(gè)科學(xué)家,我要深思:我們?cè)诟呖萍忌系玫搅耸裁矗咳毡?、韓國(guó)、美國(guó)基本都是把國(guó)內(nèi)不能生產(chǎn)的、低價(jià)的東西轉(zhuǎn)移到第叁世界國(guó)家來(lái)生產(chǎn)。你并沒(méi)有得到高科技,你以為他會(huì)給你高科技嗎?不會(huì)的!
    比如汽車,我們聯(lián)營(yíng)了這么多家,但日本的汽車技術(shù),比如豐田,都是第二代、第叁代之前的,他不會(huì)給你先進(jìn)的!為什么現(xiàn)在柯尼卡、柯達(dá)、富士在中國(guó)“大跳水”? 就是要擠跨樂(lè)凱,這個(gè)中國(guó)現(xiàn)在剩下的唯一一個(gè)國(guó)產(chǎn)膠卷!等哪一天樂(lè)凱垮掉了,國(guó)外的膠卷就會(huì)全部漲價(jià)!
    ??? 現(xiàn)在在中國(guó)賣的進(jìn)口膠卷比日本、美國(guó)的都便宜,這就是傾銷!這一點(diǎn)中國(guó)人并不知道。
    為什么我們的大學(xué)排不進(jìn)前200名?因?yàn)橐?guī)定要有800篇FCA的論文才能進(jìn)入前200名。為什么浙大好不容易搞了10年的科研卻沒(méi)有錢?教授的論文寫得少了,平均一個(gè)教授沒(méi)有一篇,像我這樣一年能寫5、6篇的很少。為什么?中國(guó)的教授一個(gè)月的工資平均只有1500元,相當(dāng)于170美元;美國(guó)的教授拿多少工資?他的一篇文章值多少錢?可見(jiàn)中國(guó)教授便宜了!美國(guó)教授成本高!
    為什么會(huì)是這樣?所以,我非常擔(dān)心這樣下去,再過(guò)5年、10年,你到底還有些什么東西?這樣惡性循環(huán)后,我們基本上沒(méi)有自己的工業(yè)了!我不贊成“造船不如買船,買船不如租船“,過(guò)若干年再看看,將會(huì)是什么樣子?
    下面談?wù)勎覀€(gè)人的觀點(diǎn):第一,我們國(guó)家的現(xiàn)實(shí)和發(fā)展就是這樣:凡是依賴不成的,我們自己都能搞得像模像樣,比如二彈一星;凡是能夠引進(jìn)的,就都搞不成。為什么?
    ??? 企業(yè)的科技人員辛辛苦苦地搞一個(gè)技術(shù)革新,只要區(qū)里的計(jì)委領(lǐng)導(dǎo)、省里的計(jì)經(jīng)委領(lǐng)導(dǎo)哪一天帶著人到美國(guó)去考察一下,買來(lái)幾個(gè)電器產(chǎn)品,跟他們簽個(gè)協(xié)議,然后再到美國(guó)去培訓(xùn)10天,引進(jìn)一條線,馬上就可以把你這個(gè)國(guó)營(yíng)企業(yè)打跨,這就是現(xiàn)實(shí)!現(xiàn)在很多合資企業(yè)就這樣,賣點(diǎn)東西,而沒(méi)有去考慮這些深層次的東西。殊不知,這就是社會(huì)的惡性循環(huán)!
    關(guān)于電信的事,我只跟電信部門這樣說(shuō):這點(diǎn)電話費(fèi)我付得起!但是,你們想過(guò)沒(méi)有,你們從自己的這個(gè)角度賺了消費(fèi)者的錢,但消費(fèi)者里面有大夫,你電信的人就不生病嗎?你若進(jìn)醫(yī)院,他給你賣高價(jià)藥行嗎?
    我開(kāi)玩笑:“你別看我是個(gè)窮教授,賺不了錢。我今天回去就去查名單,看我這個(gè)學(xué)院、我這個(gè)系的學(xué)生有多少是你們電信部門的子女,到了下個(gè)學(xué)期全部不及格!若要及格,每分交5000元錢?!暗覜Q不會(huì)這么做!若這樣做,這個(gè)世界就亂了。作為社會(huì)成員,一定要有這樣的思想:大家是互相依存的,我們這個(gè)國(guó)家也同樣。
    ??? 但是很多人只考慮自己,只要自己賺錢而不管別人怎樣,若那樣的話,明天就可能得到報(bào)應(yīng)。這是我的一個(gè)觀點(diǎn)。下面這幾個(gè)問(wèn)題是最重要的問(wèn)題:中國(guó)需要什么樣的教育?中國(guó)需要什么樣的人才?中國(guó)需要什么樣的科技?中國(guó)需要什么樣的產(chǎn)業(yè)?教育、學(xué)習(xí)是為了什么?
    最近,幼兒園、小學(xué)、中學(xué)、大學(xué)以及飯店、各個(gè)廠礦企業(yè)等單位都邀請(qǐng)我去演講,這是我應(yīng)該為社會(huì)做的,是我的本份,加上我身兼數(shù)職:院長(zhǎng)、系主任,所長(zhǎng)等,他們開(kāi)口就要找博士。其實(shí),這需要共同語(yǔ)言受教育的層次、人格的素質(zhì),這才是最重要的!
    現(xiàn)在很多人對(duì)學(xué)生的教育沒(méi)有注重這個(gè)方面。中小學(xué)在搞素質(zhì)教育,什么叫素質(zhì)?英語(yǔ)、計(jì)算機(jī)、鋼琴都會(huì)一點(diǎn)兒能算是素質(zhì)嗎?我住的那層樓的孩子都在彈鋼琴,我就聽(tīng)到二樓的一個(gè)男孩子在彈《致愛(ài)麗絲》時(shí),邊彈邊哭、邊罵他媽媽。爸爸媽媽都是音盲,卻一定要把孩子培養(yǎng)成音樂(lè)家。這么好的太陽(yáng),讓孩子坐在屋里,他能受得了嗎?這是何必呢?幼兒園3歲開(kāi)始學(xué)英語(yǔ),我這個(gè)觀點(diǎn)不知你們是否贊同,我在學(xué)校講課時(shí),學(xué)生們聽(tīng)了覺(jué)得我所說(shuō)的正符合了他們的心意。
    ??? 我認(rèn)為:語(yǔ)言、計(jì)算機(jī)就是工具。中國(guó)的外語(yǔ)教授講英語(yǔ)還不如美國(guó)賣菜的農(nóng)民!怎么看待這個(gè)問(wèn)題?日本博士、德國(guó)教授說(shuō)不出英語(yǔ)的多得是!我們?cè)趺茨苷f(shuō)一個(gè)人不會(huì)說(shuō)英語(yǔ)就是文盲呢?語(yǔ)言就是一個(gè)工具!你沒(méi)有那個(gè)環(huán)境,他怎么能講這個(gè)語(yǔ)言呢?比如,我35歲開(kāi)始學(xué)日語(yǔ),我現(xiàn)在的日語(yǔ)是頂呱呱的。但是,我在國(guó)內(nèi)進(jìn)修一年,派日本教授來(lái)教我,可我就是學(xué)不好,非常緊張。因?yàn)槟挲g較大了,學(xué)得我白天的語(yǔ)法都錯(cuò)了,晚上做夢(mèng)全講日語(yǔ),且這時(shí)講的語(yǔ)法都是對(duì)的!到了日本后,我是在實(shí)驗(yàn)室工作,而打工的人2個(gè)月學(xué)的日語(yǔ)就比我學(xué)得溜,這主要就是因?yàn)闆](méi)有環(huán)境。
    ??? 所以說(shuō),如果我是教育部長(zhǎng),我要改革二件事:第一,取消六級(jí)考試,你一個(gè)研究生連中文一級(jí)都不及格,你英文考六級(jí)干什么呢?看看研究生寫得論文,自己的民族文化都沒(méi)有學(xué)好,天天考英語(yǔ)──打勾:托福打勾,GRE打勾,英文考出很高的分,可哪個(gè)寫的英文論文在我面前過(guò)得了關(guān)呢?過(guò)不了關(guān)!這樣培養(yǎng)出來(lái)的人能干什么? 自己搞的專業(yè)一點(diǎn)都沒(méi)學(xué)好!
    我跟在座的老板們提醒一句,等下我要講一下人才使用問(wèn)題,你們現(xiàn)在的招聘動(dòng)不動(dòng)
    就要英語(yǔ)好,干什么呢?在廁所里講英語(yǔ)?需要嗎?要計(jì)算機(jī)好?說(shuō)不會(huì)計(jì)算機(jī)就是
    文盲,這又是一個(gè)誤區(qū)!我現(xiàn)在是教授,我顧不上搞計(jì)算機(jī),可是,浙大搞計(jì)算機(jī)的
    就特別敬佩我、巴結(jié)我:“鄭強(qiáng),你材料搞得這么好,我給你點(diǎn)計(jì)算機(jī),你去用用玩
    玩,今后搞材料與我們合作合作,我們也可沾點(diǎn)光?!?
    ??? 物質(zhì)世界不是算出來(lái)的,算能把肚子算飽嗎?現(xiàn)在我國(guó)搞了點(diǎn)軟件,很多精英──年輕人都跑到計(jì)算機(jī)行業(yè)去打工,自己成不了材,可惜??!不像我一直在做材料的教授,光榮得很!我們浙大就一個(gè)計(jì)算機(jī)院士潘云鶴,浙大的計(jì)算機(jī)在全國(guó)排在第幾呢?浙大最好的學(xué)生都去學(xué)計(jì)算機(jī)了,我經(jīng)常呼吁:這是在害人!
    我的同學(xué)現(xiàn)在在美國(guó)都在賣菜、賣中藥,成不了材,他們現(xiàn)在倒是非常羨慕我在國(guó)內(nèi)搞得這么好。他們的錢是稍微比我多一點(diǎn),但是我現(xiàn)在在中國(guó)過(guò)的日子比他們?cè)诿绹?guó)過(guò)得好!由此可見(jiàn),這不是錢就能解決的問(wèn)題。
    我到日本留學(xué)時(shí)受了許多苦,這次我到英國(guó)大學(xué)見(jiàn)到了十幾個(gè)中國(guó)留學(xué)生,他們都向我訴苦:每天只睡4個(gè)小時(shí)!浙大有很多老教授,夫妻兩個(gè)連走路都走不動(dòng)了,孩子卻在美國(guó)。
    我認(rèn)為中國(guó)人的民族心理這幾年扭曲到什么程度了!外國(guó)人不理解,認(rèn)為中國(guó)人有病:為什么夫妻不在一起,而是一方在國(guó)外、一方和孩子在國(guó)內(nèi),中國(guó)人這是何苦呢?!父母老了,是否需要人服侍?在國(guó)外的,是否想念父母呢?回答是肯定的,但不知是為了撐什么面子?!
    中國(guó)窮得這副樣子,我可以公開(kāi)告訴大家,我這次是跟浙大的最高人物一起去日本的──因?yàn)槲以谌毡玖袅诉@么長(zhǎng)時(shí)間的學(xué),在日本,我只能請(qǐng)他吃一碗面:一天晚上,請(qǐng)了8?jìng)€(gè)教授一個(gè)人一虢油面,就花了我1000元人民幣!所以,我在日本就呆不住,像我這樣的人,我現(xiàn)在就不愿出國(guó),去10天可以,去1個(gè)月我就受不了!
    言歸正傳,現(xiàn)在的孩子學(xué)英語(yǔ),但父母都不會(huì)講英語(yǔ),我的一個(gè)朋友的女兒在美國(guó)學(xué)
    了英語(yǔ),回來(lái)就忘記了,這就是語(yǔ)言的特點(diǎn)。語(yǔ)言沒(méi)有環(huán)境,就學(xué)不好。所以,第
    一,要取消六級(jí),讓孩子們放松;第二,大學(xué)一年級(jí)開(kāi)始的叁個(gè)月像軍訓(xùn)那樣突擊一下英語(yǔ),馬上過(guò)關(guān),然后就任其自然。

    你看我,從高中開(kāi)始學(xué)英語(yǔ),大學(xué)學(xué),碩士學(xué),博士學(xué),花了我多少精力!你說(shuō)中國(guó)人怎么做得出高科技的研究成果?我這幾天就教訓(xùn)我手下的幾位女學(xué)生,問(wèn)她們?cè)诟墒裁?,看不到人影,一天到晚考這樣、考那樣的,到美國(guó)去干什么?在國(guó)內(nèi)要干的事多著呢!你整天考英語(yǔ),美國(guó)人連報(bào)個(gè)名都要收你們的錢,日本人也是如此,中國(guó)學(xué)生到日本去要交手續(xù)費(fèi),到日本留學(xué)是為日本人打工,好不容易掙點(diǎn)錢交了學(xué)費(fèi),讀完博士在日本的公司就職,當(dāng)勞動(dòng)力,掙了一筆錢后要回國(guó)了就買了家電,把錢全給了日本人。你們都沒(méi)有注意這件事,這里面都是經(jīng)濟(jì)問(wèn)題。
    這就是素質(zhì)教育到底是什么?,F(xiàn)在有這樣一個(gè)現(xiàn)象:大學(xué)叁年級(jí)時(shí)有42名學(xué)生,畢業(yè)時(shí)只剩15人了,其他全部不能畢業(yè)。這是為什么?就是因?yàn)樗麄冊(cè)诖髮W(xué)里玩。這就是中小學(xué)教育的失敗!中小學(xué)的教育就是聽(tīng)話,老師管干部,干部管同學(xué),孩子們都學(xué)會(huì)了成年化的處世方式,這是害人??!這樣強(qiáng)迫性地做了一些好事后,沒(méi)有把做好事與做人準(zhǔn)則結(jié)合起來(lái)去培養(yǎng),而只學(xué)會(huì)了拍馬屁、討老師喜歡、說(shuō)成人話。上次電視上就曾經(jīng)播出,一個(gè)小孩得了個(gè)獎(jiǎng),主詩(shī)人問(wèn)他最愿意說(shuō)什么,他說(shuō):“我最愿意跟江爺爺說(shuō):我向你報(bào)告!““江爺爺”是誰(shuí)?還不是老師教的!
    孩子們?cè)谥行W(xué)活得很累,到了大學(xué)就沒(méi)人管了,所以就要玩、就要談戀愛(ài)。我們系有個(gè)男生,跟四川一個(gè)女孩談戀愛(ài),前幾天班主任向我匯報(bào),上個(gè)月跑回去20天看他女朋友,這還得了!這是為什么?這就是從小教育的結(jié)果!我的兒子在班上就有6個(gè)女同學(xué)有“記錄”的特權(quán),記錄哪個(gè)男同學(xué)動(dòng)了。有了6次記錄后,男同學(xué)就得寫檢查,家長(zhǎng)也要跟著寫檢查。
    我第一次寫時(shí)很難受,怎么能做這種事呢?后來(lái)就習(xí)慣了。到了星期五就問(wèn)兒子:
    “這個(gè)星期要不要寫?”反正臉皮也厚了,寫就寫吧。問(wèn)題是,實(shí)際上他只違反了一次紀(jì)律就同時(shí)被6個(gè)女孩子看見(jiàn)了,這也算6次!但是,我并不為我兒子擔(dān)心,我認(rèn)為:他受這點(diǎn)挫折也好、壓抑也好,對(duì)他一生的成長(zhǎng)有好處;而我恰恰擔(dān)心的是那6個(gè)女同學(xué),以后怎么能夠經(jīng)歷得起打擊和挫折!這樣的教育是很令人深思的。
    所以,我作為一個(gè)博士生導(dǎo)師,我從來(lái)是看人不看學(xué)歷的,學(xué)歷不等于能力。你們現(xiàn)在的招聘動(dòng)不動(dòng)就要高學(xué)歷,我就是要批判這樣做。我提出一個(gè)命名,叫“消費(fèi)學(xué)歷“──就是濫用學(xué)歷。現(xiàn)在提拔干部也同樣,不看他的身體,到了60歲,有些身體特別棒且有能力的人也要讓他退休;而有的人叁、四十歲得了肝炎,還得讓他干,這就是“一刀切”。
    招聘時(shí)也總是看學(xué)歷。學(xué)歷是指一個(gè)人讀書(shū)還可以,并不能代表他能夠當(dāng)你的經(jīng)營(yíng)人員、開(kāi)發(fā)人員。我們有很多同學(xué)成績(jī)好,卻什么都做不了。在我們大學(xué)像我這種程度的人,招博士生是從來(lái)不看成績(jī)的,成績(jī)算什么!現(xiàn)在我從事的這個(gè)領(lǐng)域在中國(guó)有叁個(gè)杰出的人才,當(dāng)初在讀研究生時(shí)都補(bǔ)考過(guò),而成績(jī)考得好的幾個(gè)人卻都跑到美國(guó)去賣中藥了,這說(shuō)明了什么問(wèn)題?作老板的可不能這樣?。?
    現(xiàn)在浙大有規(guī)定,有博士點(diǎn)的,留校就必須全部留博士生而不準(zhǔn)留碩士生,這樣,儀器就沒(méi)有人去操作。人才的梯隊(duì)一定要合理,而不要認(rèn)為教授就是萬(wàn)能的、博士就是萬(wàn)能的。中國(guó)的教育體系就是讓每一個(gè)老百姓都充滿希望和理想,教育孩子們要樹(shù)立遠(yuǎn)大的理想。
    實(shí)際上,人的能力是不一樣的,掃地能掃好,也應(yīng)該受到尊重;打掃廁所能打掃干凈,也應(yīng)該受到尊重,不能動(dòng)不動(dòng)就要高學(xué)歷。我要提醒的是:在國(guó)外可不是這樣,反之,美國(guó)、日本的博士就很難找到工作,為什么?因?yàn)槔习逍奶坼X,招博士要給他高工資,而他能做什么用呢?這是個(gè)具體問(wèn)題。我不知道現(xiàn)在的組織部長(zhǎng)、人事處長(zhǎng)在干什么,真的是在“選女婿”嗎?找這么高學(xué)歷的人干什么呢?
    現(xiàn)在,中國(guó)的大學(xué)提出要培養(yǎng)高層次的人才,我說(shuō)這話錯(cuò)了,中國(guó)現(xiàn)在教育特點(diǎn)應(yīng)該是讓全民得到教育,而不是去培養(yǎng)少數(shù)的專門人才。上次全國(guó)的化學(xué)奧林匹克競(jìng)賽在杭州舉行,是浙大主辦的,學(xué)校說(shuō)來(lái)了這么多高校的人挖人才,浙大也要派人去挖,于是派我去了。我去講了話,我毫不客氣地說(shuō):進(jìn)這扇門,我的心情是又高興又沉重。你們把孩子們搞壞了!為什么?我國(guó)搞奧林匹克競(jìng)賽──中小學(xué)叫奧賽班是舉國(guó)體制,就是為了得到世界上的一個(gè)榮譽(yù)!而在美國(guó)、日本、西歐國(guó)家就只有一個(gè)學(xué)校,叫“Play- again”就是搞著玩的。難道有一個(gè)學(xué)生得了奧林匹克的冠軍,就說(shuō)明中國(guó)的教育好嗎?
    ??? 不是,它不能代表我國(guó)的真實(shí)情況。在那些非重點(diǎn)學(xué)校里,有多少孩子在外面賭博、打游戲機(jī)!這就是我國(guó)教育的一種誤區(qū)。我指出:如果作為一個(gè)教授來(lái)做這樣的事,在座的人都感到心痛!作為父母,我們絕不能這樣寵愛(ài)自己的孩子,把這些孩子當(dāng)寶貝一樣?;瘜W(xué)的奧林匹克競(jìng)賽,清華、北大的教授來(lái)了一大堆,我們今天是在做一件害孩子的事!
    我的話講完后,主詩(shī)人要下面哪個(gè)大學(xué)的教授接著講,他們都不敢上臺(tái)講了。請(qǐng)捫心自問(wèn):我們這樣做對(duì)嗎?奧林匹克競(jìng)賽的結(jié)果在浙大的一個(gè)現(xiàn)象是:在中學(xué)學(xué)得好的、保送的,到了大學(xué)叁年級(jí)成績(jī)都降下去了,孩子這么小,怎么能分等級(jí)呢?其實(shí),他們根本就是在同一個(gè)起跑線上的,成長(zhǎng)的路程還長(zhǎng)得很,后天的努力才是最重要的。所以,我始終對(duì)孩子、對(duì)學(xué)生都是鼓勵(lì)的。我們系里有一個(gè)女同學(xué),我看到她一天到晚沒(méi)有笑臉,就是為了得到那個(gè)高分?jǐn)?shù)、為了得到高額的獎(jiǎng)學(xué)金,我感到很痛心!我說(shuō):你這是在用青春買榮譽(yù)、買光環(huán),你今后的心靈是要受到創(chuàng)傷的!我希望她不要看重明年從第1名掉到第2名,后年從第2名掉到第3名。我這個(gè)老師當(dāng)?shù)霉职?,我不是要求她往上走,而是往下走,我這是在救她!
    ??? 昨天,我的孩子參加環(huán)湖跑,我對(duì)他說(shuō):“你不要去爭(zhēng)第1名,慢慢跑。”不是說(shuō)我不要孩子上進(jìn),而是這些老師在干什么?讓5-6歲、7-8歲的孩子跑4000米,為了爭(zhēng)得那個(gè)第一,把孩子的身體都跑壞了,我之所以長(zhǎng)的矮,就是因?yàn)槲以冢禋q時(shí)早晨起床跑步,骨質(zhì)過(guò)早鈣化了。現(xiàn)在懂科學(xué)了,就知道了,小孩子不能隨便大運(yùn)動(dòng)量地運(yùn)動(dòng)。
    可是求是小學(xué)每天早上第一節(jié)課就是把全校的孩子弄到街上去跑步,剛剛吃了早飯,能量還沒(méi)有發(fā)揮,能量是要用到腦子上的,要上一天的課??稍缟系呐懿骄妥屇芰肯牧?,這不科學(xué)!還有,沿著馬路跑步,汽車尾汽對(duì)孩子的健康是很有損害的。這樣的教育到底是為了什么?
    我敢講一點(diǎn):我們浙大有很多教授就被小學(xué)老師教育得像兒子一樣,小學(xué)老師每次開(kāi)會(huì)的第一句話就是:“親愛(ài)的家長(zhǎng)同志們:孩子是你們的,也是我們的,但是歸根結(jié)底還是你們的!“每次都講這些話,然后就說(shuō):“你們不懂科學(xué)、不懂教育?!蔽倚睦锞驮谙耄汉⒆佣际悄銈兘逃怂偷轿覀兪稚蟻?lái)的,就非常擔(dān)心,孩子的心靈從小讓你們這么一整就麻煩了。
    我覺(jué)得我現(xiàn)在最對(duì)不起的就是我小學(xué)、中學(xué)、大學(xué)的同學(xué)們。我從小干部當(dāng)慣了,一直在管人,到現(xiàn)在我心里覺(jué)得最對(duì)不起的就是那時(shí)被我管過(guò)的這些同學(xué),不管他們現(xiàn)在是在開(kāi)出租車還是在干啥,都非常有成就。所以,怎樣把孩子培養(yǎng)好,從小讓他有一個(gè)健康的心理,這比成績(jī)還重要。
    何況各位家長(zhǎng),你們由于自己的學(xué)歷低些,總是希望孩子出頭,我也知道有些家長(zhǎng)在雙休日的上午、下午、晚上都要安排孩子參加各種各樣的學(xué)習(xí),把孩子完全拖垮了,其結(jié)果孩子是要厭惡的。過(guò)早彈鋼琴的人,除非他真正是個(gè)音樂(lè)家,十有八、九到了中途都會(huì)厭惡,這就是逆反心理學(xué)。所以,你們不能這么干,這么干是摧殘人才,這是我今天講的,為人才的培養(yǎng)談一些自己的看法。
    科技到底該干什么?高科技到底該干什么?如果我是科技部長(zhǎng),該玩的就玩,就像陳景潤(rùn),他就是玩。陳景潤(rùn)如果是處在今天的中國(guó),他絕對(duì)是要去討飯的,因?yàn)樗粫?huì)去搞產(chǎn)業(yè)化,他的英語(yǔ)也不好,他說(shuō)話都不流利,中文都講不好,按現(xiàn)在“標(biāo)準(zhǔn)”,他是個(gè)文盲,還談什么教授!
    ??? 日本人就是喜歡美國(guó)人,我跟日本人說(shuō):你們這個(gè)民族愛(ài)誰(shuí),誰(shuí)就要向你們?nèi)釉訌?。日本人就是喜歡黑人也不喜歡中國(guó)人?,F(xiàn)在在日本獎(jiǎng)學(xué)金最高的是美國(guó)人、歐美人;第二是韓國(guó)人、臺(tái)灣人;第叁是巴基斯坦人、馬來(lái)西亞人;第四是印度人、非洲國(guó)家的人;第五才輪到中國(guó)人。
    我就特別對(duì)我們的女教授、女同學(xué)說(shuō):在日本人面前一句日文都不要講,會(huì)也不要講;日本人一聽(tīng)說(shuō)你講英文,特別是看到中國(guó)女孩講英文,腿都要發(fā)軟,這是真的! 日本人不知道龍井茶,而只知道烏龍茶,就因?yàn)樾袢丈秊觚埐璧膹V告宣傳。日本人在開(kāi)始做烏龍茶廣告時(shí)找了6個(gè)最漂亮的中國(guó)女孩,日本人就從這個(gè)廣告得出一個(gè)結(jié)論:
    中國(guó)女性的漂亮是因?yàn)楹攘藶觚埐琛K?,日本人特別崇尚烏龍茶,而不知道龍井茶。
    日本就是崇尚歐美,誰(shuí)能講英語(yǔ),誰(shuí)就是老大。日本首相森嘉郎不會(huì)英語(yǔ),但為了表現(xiàn)自己會(huì)英語(yǔ),就叫秘書(shū)安排了一套程序,準(zhǔn)備在沖繩開(kāi)政府間合作會(huì)議時(shí),見(jiàn)到克林頓用英語(yǔ)問(wèn)候一下。但是日本人講英語(yǔ)很糟糕,森喜郎見(jiàn)到克林頓,將“How are you!”說(shuō)成了“Who are you?”,克林頓以為這是森喜郎在跟他幽默:我明明是美國(guó)總統(tǒng),他還不知道嗎?他為什么還這么問(wèn)我?我今天也跟他來(lái)個(gè)幽默:“I am husband of Hilary.”(“我是希拉里的丈夫”),森喜郎不管克林頓怎么說(shuō),就忙按照程序回答:“Too me.”、“Me too.”,克林頓想你這個(gè)玩笑開(kāi)得太大了,我老婆怎么變成你老婆了?這在日本就成了個(gè)大笑話!
    最近,我們?cè)谵k高新科技園區(qū),就國(guó)家的投資而言,我們的領(lǐng)導(dǎo)的意見(jiàn)往往是去追世界潮流:想去建世界一流的國(guó)家,達(dá)到一流的水平。我非常慚愧地向大家譴責(zé)一下自己:我們中國(guó)的教授很多拿了國(guó)家的錢就像小孩搞家家一樣,把錢用完了,就寫點(diǎn)文章,塞在抽屜里,一點(diǎn)用都沒(méi)有,就向領(lǐng)導(dǎo)報(bào)告:我做完了。這很對(duì)不起國(guó)家的錢! 說(shuō)實(shí)話,應(yīng)該弄清楚哪些是搞著玩的,哪些是對(duì)企業(yè)有幫助的,這一點(diǎn)我們沒(méi)有做好。日本、韓國(guó)的科技進(jìn)步就是在于針對(duì)性非常強(qiáng)。現(xiàn)在有一個(gè)現(xiàn)象:所有的企業(yè)家到了浙大就問(wèn)我:“鄭教授,現(xiàn)在有什么能賺錢的項(xiàng)目?給我們吧!”其實(shí),你們太不了解了,教授是完全是遠(yuǎn)離市場(chǎng)的,根本不知道市場(chǎng)是什么!他只是在搞游戲,玩家家,想一些新玩意,不要以為教授什么都有!
    ??? 當(dāng)然,這不能怪你們,因?yàn)榻裉熘袊?guó)的生產(chǎn)力的發(fā)展,還沒(méi)有到讓我們的老板們具備很高的意識(shí)。剛才何先生就講得很好,在目前的階段,中國(guó)還有假貨的話,就不能指望做假的人有什么超前的科技需求,他賺一把是一把。但是,當(dāng)中國(guó)的經(jīng)濟(jì)秩序真正完善以后,造假絕對(duì)活不下去!現(xiàn)在在日本就沒(méi)有人敢造假,只要稍微有一點(diǎn)點(diǎn)造假,馬上就完蛋。中國(guó)總有一天要進(jìn)入到有序的階段,一有序,造假的人肯定活不下去。企業(yè)能不能生存,說(shuō)到底就是看你有沒(méi)有絕招。這個(gè)絕招,第一是產(chǎn)品的特色;第二是科技的含量。上次我毫不客氣地對(duì)張德江書(shū)記說(shuō):浙江要建經(jīng)濟(jì)大省,文化強(qiáng)省,但是“大”不等于“強(qiáng)”,“民富”不等于“國(guó)強(qiáng)”。科威特有的是錢,伊拉克要打垮它就打垮了,這是很簡(jiǎn)單的事。我說(shuō):經(jīng)濟(jì)強(qiáng)省應(yīng)該有下列標(biāo)志。我問(wèn)張書(shū)記:第一,浙江省現(xiàn)在的經(jīng)濟(jì)總量中有多少具有科技的含量?第二,浙江省目前的經(jīng)濟(jì)有幾個(gè)是關(guān)系到中國(guó)國(guó)民經(jīng)濟(jì)命脈的、民生的、大的工業(yè)?第叁,浙江的經(jīng)濟(jì)真的有一天在亞洲金融風(fēng)暴來(lái)臨時(shí)能抗得住嗎?這些浙江省都有問(wèn)題。浙江的市場(chǎng)發(fā)育得很完全,但如果我是外省人,如果哪一天我自己那里方便了,我為什么還要跑到你這兒買?現(xiàn)在之所以有市場(chǎng),是因?yàn)檎憬袌?chǎng)里賣假貨的很多,要么走私、要么賣假,這幾年就是這樣發(fā)起來(lái)的。如果不是這樣,再過(guò)幾年,遼寧的人要貨在北京買就行,何必再跑到你浙江來(lái)買,如果不到你這兒買你怎么辦?
    ??? 現(xiàn)在浙江稱為塑料大省,全國(guó)叁分之一的塑料制品產(chǎn)在浙江,上次在余姚,就召開(kāi)過(guò)塑料科技大會(huì)。浙江的西服很多,像杉杉西服等,還有娃哈哈。但是,請(qǐng)各位注意:
    西服、果奶不是民生大計(jì)!千島湖的農(nóng)夫山泉是好,但水什么地方?jīng)]有?這就是問(wèn)題。另外,溫州經(jīng)驗(yàn)好不好?好!但如果我是國(guó)家主席,我可不會(huì)在全國(guó)搞溫州經(jīng)驗(yàn)。溫州經(jīng)驗(yàn)說(shuō)到底是民族經(jīng)濟(jì)全部被國(guó)外吃掉。你的資本算什么,溫州老板的那點(diǎn)錢與日本老板相比就不算錢,馬上會(huì)被吃掉,而且技術(shù)含量極低。我去了溫州好幾次,看到的都是家庭工廠,與現(xiàn)代企業(yè)能比嗎?此外,把西部的博士挖過(guò)來(lái),用高薪養(yǎng)起來(lái),這些都不能算是集約經(jīng)營(yíng)和規(guī)模經(jīng)營(yíng),這些都是危機(jī)!但是我們卻盡唱高調(diào)。那天,我最后是帶著感情與張德江談的:我是愛(ài)浙江的,作為一個(gè)教師,我教育學(xué)生習(xí)慣了,我認(rèn)為對(duì)待學(xué)生最好的方式就是從教育的角度講他,而不是去夸他“長(zhǎng)得好“、“今后要當(dāng)科學(xué)家”,這都是害人的話。所以我愿意對(duì)張書(shū)記提點(diǎn)意見(jiàn)。
    ??? 再進(jìn)一步,老板會(huì)提問(wèn):“鄭教授,我現(xiàn)在做的這些,你看看結(jié)合你的知識(shí)能否給我改進(jìn)一下?“我認(rèn)為這樣的提問(wèn)是最好的。上次我們青年教授到天臺(tái)去,天臺(tái)是個(gè)窮地方,前面11個(gè)教授都講IT產(chǎn)業(yè),講得那些企業(yè)家第二天都要來(lái)搞通訊行業(yè)了。我最后發(fā)言:前面的人講的話又把你們害苦了。你們這么窮的地方怎么搞得過(guò)寧波、杭州?你們應(yīng)該把本地的東西通過(guò)我們的先進(jìn)思想和技術(shù)改造好,做得更好一點(diǎn)。所以我希望我們的企業(yè)家在下次見(jiàn)到教授時(shí)提出這類問(wèn)題,你們就進(jìn)步了。真正的科技產(chǎn)業(yè)進(jìn)步的源泉在你們,而不在教授。當(dāng)你們有錢了、有產(chǎn)業(yè)規(guī)模了該怎么辦,就應(yīng)該學(xué)學(xué)日本。我國(guó)現(xiàn)在到底需要什么?軟件搞得這么紅火,但我們并不需要軟件。其實(shí),我們現(xiàn)在的軟件搞不過(guò)印度。美國(guó)硅谷一大半的人才是從印度去的。但印度的國(guó)防部長(zhǎng)常常驚駭這叁、四年來(lái)與中國(guó)的差距──他是從奧運(yùn)會(huì)得了一塊金牌談起的,民總產(chǎn)值才是中國(guó)的叁分之一,人口與中國(guó)差不多,而糧食產(chǎn)量卻連中國(guó)的一半都不到。中國(guó)現(xiàn)在最需要的是材料,是制造與控制。不要以為我們什么都有,我這次到韓國(guó)看了真是痛心,在韓國(guó)的街上見(jiàn)不到一輛外國(guó)的進(jìn)口車,絕對(duì)沒(méi)有!我又聽(tīng)說(shuō)現(xiàn)代企業(yè)的生產(chǎn)量比我國(guó)的桑塔納、長(zhǎng)春、武漢、富康的總和還多,且他們所有制造汽車的精密儀器全部都是國(guó)產(chǎn)的。而我們的這些部分卻全部是進(jìn)口的,沒(méi)有一樣是自己的。人家想做什么,什么都能做好,我們卻是想做什么,什么都做不成。歸根結(jié)底,不是靠我們的軟件,搞計(jì)算機(jī)的人什么都會(huì)玩,上次到天臺(tái)演示房子設(shè)計(jì)的動(dòng)態(tài),把房地產(chǎn)公司的人看傻眼了。其實(shí),這都是哄人的,房子要造起來(lái)還是要靠材料,靠造房子的人。
    ??? 現(xiàn)在我國(guó)在這兩方面是最薄弱的。高等學(xué)校投了幾十個(gè)億買研究設(shè)備,但這些設(shè)備90%都是進(jìn)口的,沒(méi)有一樣是國(guó)產(chǎn)的。買來(lái)的時(shí)候覺(jué)得很了不得,可以哄領(lǐng)導(dǎo),但是若有哪個(gè)學(xué)生把儀器弄壞了,就死了,我們國(guó)內(nèi)的企業(yè)沒(méi)有一家敢修儀器的,即使一個(gè)很簡(jiǎn)單的實(shí)驗(yàn)儀器沒(méi)有一家工廠能夠生產(chǎn),這就是我國(guó)現(xiàn)在整個(gè)民族工業(yè)的一個(gè)縮影!我們不愿意踏實(shí)地來(lái)做這些工作,而只是做了很多表面文章,既生產(chǎn)不出材料,也沒(méi)有先進(jìn)的制造工藝。我的這個(gè)觀點(diǎn)得到了大多數(shù)教授的擁護(hù)。但是,要求省里的科委主任把錢投到材料和制造工藝這兩方面,他就不干,他要做世界第一流的“納米“。說(shuō)到底,這都是些表面現(xiàn)象,我們現(xiàn)在最需要的是人們的一種堅(jiān)韌不拔的精神,我們民族已經(jīng)沒(méi)有這個(gè)精神了。我們現(xiàn)在想的只是“賣得越多越好“。
    ??? 這次校長(zhǎng)、書(shū)記在日本,見(jiàn)到東京名古屋大學(xué)的校長(zhǎng),他提了個(gè)問(wèn)題:我們都屬于東方文化,現(xiàn)在就要召集大家來(lái)討論怎樣保護(hù)東方文化,保護(hù)東方文化的特色。大家知道,生物是多樣化的,世界上若只有美國(guó)人就沒(méi)有味道。日本人說(shuō):“我們培養(yǎng)的很多人也到美國(guó)去了,當(dāng)是他們很驚訝,你們的7位中國(guó)校長(zhǎng)一致認(rèn)為這種現(xiàn)象沒(méi)有關(guān)系,這是國(guó)際化?!叭毡救诉@番話引起了我的深思:我們中國(guó)沒(méi)有一點(diǎn)本錢來(lái)談我們的人才儲(chǔ)備敢與日本比,但是,我們所表現(xiàn)出了一種莫明奇妙的胸懷。比如,日本的許多大學(xué)為什么能得到許多捐款,就是因?yàn)榫杩畹娜藢?duì)母校有感情,對(duì)社會(huì)有報(bào)答。哪一個(gè)日本大學(xué)為日本的財(cái)團(tuán)或企業(yè)輸送的高級(jí)人才越多,所得到的獎(jiǎng)學(xué)金就越多。
    現(xiàn)在,教育界有一種反思,清華大學(xué)自建校以來(lái)從來(lái)沒(méi)有像今天這樣完全實(shí)現(xiàn)了她當(dāng)初的辦學(xué)宗旨:“成為美利堅(jiān)合眾國(guó)的預(yù)備學(xué)?!?。如果我是中國(guó)的納稅人,我怎么能想得通,我國(guó)國(guó)民花那么多錢投入到這個(gè)學(xué)校,可它培養(yǎng)的人卻都跑到美國(guó)去了,為他們服務(wù)了??墒悄阌袥](méi)有看到美國(guó)政府為我國(guó)哪個(gè)大學(xué)捐過(guò)點(diǎn)錢?你們體現(xiàn)出這么一種胸懷是什么意思呢?
    你們到韓國(guó)、日本、新加坡去看看,你們就知道中國(guó)人在精神上垮到了什么地步!我恨日本人,我到日本是作為日本大使館面試的中國(guó)最杰出的博士生去的,當(dāng)時(shí)在四川只選了我一個(gè)人,我到日本拿的獎(jiǎng)學(xué)金都被告知不要告訴日本人,怕日本人嫉妒,他們就是要培養(yǎng)漢奸。但是我到日本是越培養(yǎng)越恨,神□大地震時(shí)我在日本,我是中國(guó)留學(xué)生的領(lǐng)導(dǎo),那時(shí)死了許多中國(guó)人,其中杭州人最多,就因?yàn)槿毡救讼染热毡救耍绢櫜簧暇戎袊?guó)人!在日本空港,日本國(guó)民的進(jìn)港通道有8個(gè),而僅給外國(guó)人留一個(gè),你得排隊(duì),等日本人全部走完了,他再轉(zhuǎn)換牌子,讓外國(guó)人再進(jìn)來(lái)。
    ??? 中國(guó)人為什么這些年都往外跑,最重要的是要讓國(guó)民自己愛(ài)自己國(guó)家。在廣西,美國(guó)人的骨頭埋了幾十年,還叫中國(guó)農(nóng)民去找,把美國(guó)人的骨頭找到了,放在棺材里,送回到白宮,舉行隆重的儀式、行軍禮,這怎么能讓美國(guó)人不自豪?反之,當(dāng)找美國(guó)人骨頭的中國(guó)農(nóng)民在尋找時(shí)摔了一跤,骨頭摔壞了,給200元錢就打發(fā)回家了,連“勞動(dòng)模范“都沒(méi)給人家,你怎么能讓你的國(guó)民愛(ài)這個(gè)國(guó)家,有自尊的呢?!
    如果我是杭州的市長(zhǎng),我絕對(duì)不是狹隘的民族自尊心──如果杭州有什么災(zāi)難,我就首先把杭州的老百姓安排在香格里拉,讓外國(guó)人在外面排隊(duì)?。ㄕ坡暎。┻@樣,你才會(huì)讓你的國(guó)民愛(ài)自己的國(guó)家!
    一個(gè)日本的農(nóng)民跑到峨嵋山去玩,骨頭摔斷了,你就用中國(guó)空軍的直升飛機(jī)去救他,而在日本大學(xué)一名中國(guó)留學(xué)生在宿舍里死了7天才被發(fā)現(xiàn);名古屋大學(xué)的一對(duì)中國(guó)博士夫婦和孩子誤食有毒磨菇,孩子和母親死了,父親則是重肝炎,在名古屋大學(xué)醫(yī)院的門診室等了12個(gè)小時(shí),也沒(méi)有一個(gè)日本教授來(lái)看望!而你們?yōu)槭裁催€要這么友好,以為自己很大度,實(shí)際上是被人家恥笑,笑你的無(wú)知!你們這個(gè)民族賤!我們不能這樣!
    ??? 我們的領(lǐng)導(dǎo)人跑到國(guó)外去訪問(wèn),看到有幾個(gè)人在歡迎他們,就感到挺有面子;而外國(guó)來(lái)了個(gè)什么人物,都是警車開(kāi)道,這究竟是怎么回事?這讓我們中國(guó)人感到是自豪還是悲哀?
    所有這些,對(duì)教育工作來(lái)講,都是深層次的問(wèn)題。所以我經(jīng)常講,我作為一位自然科學(xué)工作者,我教育我的學(xué)生,首先是學(xué)會(huì)做人,沒(méi)有這些,你學(xué)了高分子,外語(yǔ)都是花架子,你不是一個(gè)完整的人。怎樣建立一個(gè)科技體系?在國(guó)外,這個(gè)部分不是大學(xué)辦的,我堅(jiān)信,目前“教授+商人”的這種狀態(tài),過(guò)20年后會(huì)改變。在國(guó)外,沒(méi)有哪個(gè)教授是既當(dāng)公司經(jīng)理又當(dāng)教授的,這種現(xiàn)象極少,只有中國(guó)有!這就算是國(guó)情吧。一個(gè)人的精力是有限的,既要辦公司,又要當(dāng)教授,能當(dāng)好嗎?我不否認(rèn)有這類特殊人才,很少見(jiàn)。關(guān)鍵是把大學(xué)教授神化了,讓他們?nèi)棵嫦虍a(chǎn)業(yè)界,缺少了中間地帶,這是中國(guó)目前最大的一個(gè)缺陷。認(rèn)為今后企業(yè)改革的方向應(yīng)該是把他們直接作為企業(yè)法人結(jié)合在一起。
    日本叁菱公司的研究院,富士研究所在日本是具備最好條件的研究院,他們不發(fā)表文章,就是專門做能與產(chǎn)業(yè)結(jié)合的項(xiàng)目。這是一句口號(hào):“吃著、端著、看著”,“吃著的“――企業(yè)正在干的;“端著的”――產(chǎn)業(yè)開(kāi)發(fā)做的;“看著的”――前瞻性的東西、超前的學(xué)術(shù)研究讓大學(xué)去做,這就是一個(gè)良性循環(huán)。但是,要做好這件事,我認(rèn)為財(cái)團(tuán)和經(jīng)營(yíng)界的介入也是非常重要的。同時(shí)也要建立一種體系,讓這些信息能夠互通與共享。
    ??? 我今天講的,一個(gè)是高分子的介紹,另外是把我對(duì)科技、教育、社會(huì)等方面的一些思
    考奉獻(xiàn)給大家。主要是跟大學(xué)一起交流,有不對(duì)的地方希望在座的各位老同志、各位
    企業(yè)家、各位領(lǐng)導(dǎo)對(duì)我批評(píng)指正。?

    posted @ 2006-07-27 20:52 sunfruit 閱讀(324) | 評(píng)論 (0)編輯 收藏

    Oracle Spatial建立過(guò)程

    --sunfruit

    空間數(shù)據(jù)庫(kù)Oracle Spatial的建立過(guò)程如下:

    -- 創(chuàng)建最基本的個(gè)人興趣點(diǎn)表結(jié)構(gòu)
    drop table poi;
    create table poi (gid?INTEGER,
    ??opid?INTEGER,
    ??gname?VARCHAR2(256),
    ??gshape?MDSYS.SDO_GEOMETRY);

    -- 更新用戶空間數(shù)據(jù)對(duì)象視圖(建立索引依賴她)
    delete from USER_SDO_GEOM_METADATA where TABLE_NAME='POI' and COLUMN_NAME='GSHAPE';
    insert into USER_SDO_GEOM_METADATA values ('poi',
    ?????'gshape',
    ?????MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('lon',?-- lontitude
    ??????????-64800000,?-- min(china 26430867 73.41907434101486)
    ??????????64800000,?-- max(china 49679991 137.99997381765377)
    ??????????1),??-- scale (china abs 23249124)
    ???????MDSYS.SDO_DIM_ELEMENT('lat',??-- latitude
    ??????????-32400000,?-- min(china -1677502 -4.6597267116858045)
    ??????????32400000,?-- max(china 21571819 59.92171939467364)
    ??????????1)),??-- scale (china abs 23249321)
    ?????NULL);

    -- 插入一個(gè)個(gè)人興趣點(diǎn)的SQL語(yǔ)句,使用標(biāo)準(zhǔn)點(diǎn)地物空間數(shù)據(jù)類型
    delete from POI;
    insert into POI values (20010001,
    ???1,
    ???'我的家',
    ???MDSYS.SDO_GEOMETRY(2001,?-- SDO_GTYPE
    ?????NULL,??-- SDO_SRID
    ?????SDO_POINT_TYPE(41884696, 14377039, NULL), NULL, NULL));

    -- 插入一個(gè)個(gè)人興趣點(diǎn)的SQL語(yǔ)句,使用另一種點(diǎn)地物空間數(shù)據(jù)組織結(jié)構(gòu)
    delete from POI;
    insert into POI values (20010001,
    ???1,
    ???'我的家',
    ???MDSYS.SDO_GEOMETRY(2001,?-- SDO_GTYPE
    ?????NULL,??-- SDO_SRID
    ?????NULL,??-- SDO_POINT
    ?????MDSYS.SDO_ELEM_INFO_ARRAY (1,?-- SDO_STARTING_OFFSET
    ????????1,?-- SDO_ETYPE
    ????????1),?-- SDO_INTERPRETATION
    ?????MDSYS.SDO_ORDINATE_ARRAY (41884696,14377039)));

    -- 創(chuàng)建缺省的R-tree空間索引
    drop index POI_IDX;
    CREATE INDEX POI_IDX on poi(gshape)
    ?INDEXTYPE is MDSYS.SPATIAL_INDEX;
    --?PARAMETERS('SDO_LEVEL=10000');?-- 180*60*60*1000*2/100/100*90*60*60*1000*2/100/100 = 8398080000

    -- 索引粗濾矩形窗口選擇SQL語(yǔ)句(對(duì)于點(diǎn)地物對(duì)象,索引粗濾的結(jié)果是精確的)
    SELECT * FROM POI P
    ?WHERE sdo_filter(P.gshape,
    ??mdsys.sdo_geometry(2003,NULL,NULL,
    ????mdsys.sdo_elem_info_array(1,1003,3),
    ????mdsys.sdo_ordinate_array(41883696,14376039, 41885696,14378039)),
    ??'querytype=window') = 'TRUE';

    -- 精確匹配矩形窗口選擇SQL語(yǔ)句(計(jì)算非常耗時(shí))
    SELECT * FROM POI P
    ?WHERE sdo_relate(P.gshape,
    ??mdsys.sdo_geometry(2003,NULL,NULL,
    ????mdsys.sdo_elem_info_array(1,1003,3),
    ????mdsys.sdo_ordinate_array(41883696,14376039, 41885696,14378039)),
    ??'mask=INSIDE querytype=window') = 'TRUE';

    ?

    posted @ 2006-07-25 10:31 sunfruit 閱讀(451) | 評(píng)論 (0)編輯 收藏

    [轉(zhuǎn)發(fā)]Java虛擬機(jī)的深入研究

    Java虛擬機(jī)的深入研究

    作者:劉學(xué)超

    1??Java技術(shù)與Java虛擬機(jī)

    說(shuō)起Java,人們首先想到的是Java編程語(yǔ)言,然而事實(shí)上,Java是一種技術(shù),它由四方面組成: Java編程語(yǔ)言、Java類文件格式、Java虛擬機(jī)和Java應(yīng)用程序接口(Java API)。它們的關(guān)系如下圖所示:

    圖1??Java四個(gè)方面的關(guān)系

    運(yùn)行期環(huán)境代表著Java平臺(tái),開(kāi)發(fā)人員編寫Java代碼(.java文件),然后將之編譯成字節(jié)碼(.class文件)。最后字節(jié)碼被裝入內(nèi)存,一旦字節(jié)碼進(jìn)入虛擬機(jī),它就會(huì)被解釋器解釋執(zhí)行,或者是被即時(shí)代碼發(fā)生器有選擇的轉(zhuǎn)換成機(jī)器碼執(zhí)行。從上圖也可以看出Java平臺(tái)由Java虛擬機(jī)和Java應(yīng)用程序接口搭建,Java語(yǔ)言則是進(jìn)入這個(gè)平臺(tái)的通道,用Java語(yǔ)言編寫并編譯的程序可以運(yùn)行在這個(gè)平臺(tái)上。這個(gè)平臺(tái)的結(jié)構(gòu)如下圖所示:

    在Java平臺(tái)的結(jié)構(gòu)中, 可以看出,Java虛擬機(jī)(JVM) 處在核心的位置,是程序與底層操作系統(tǒng)和硬件無(wú)關(guān)的關(guān)鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操作系統(tǒng), 其中依賴于平臺(tái)的部分稱為適配器;JVM 通過(guò)移植接口在具體的平臺(tái)和操作系統(tǒng)上實(shí)現(xiàn);在JVM 的上方是Java的基本類庫(kù)和擴(kuò)展類庫(kù)以及它們的API, 利用Java API編寫的應(yīng)用程序(application) 和小程序(Java applet) 可以在任何Java平臺(tái)上運(yùn)行而無(wú)需考慮底層平臺(tái), 就是因?yàn)橛蠮ava虛擬機(jī)(JVM)實(shí)現(xiàn)了程序與操作系統(tǒng)的分離,從而實(shí)現(xiàn)了Java 的平臺(tái)無(wú)關(guān)性。

    那么到底什么是Java虛擬機(jī)(JVM)呢?通常我們談?wù)揓VM時(shí),我們的意思可能是:

    1. 對(duì)JVM規(guī)范的的比較抽象的說(shuō)明;
    2. 對(duì)JVM的具體實(shí)現(xiàn);
    3. 在程序運(yùn)行期間所生成的一個(gè)JVM實(shí)例。

    對(duì)JVM規(guī)范的的抽象說(shuō)明是一些概念的集合,它們已經(jīng)在書(shū)《The Java Virtual Machine Specification》(《Java虛擬機(jī)規(guī)范》)中被詳細(xì)地描述了;對(duì)JVM的具體實(shí)現(xiàn)要么是軟件,要么是軟件和硬件的組合,它已經(jīng)被許多生產(chǎn)廠商所實(shí)現(xiàn),并存在于多種平臺(tái)之上;運(yùn)行Java程序的任務(wù)由JVM的運(yùn)行期實(shí)例單個(gè)承擔(dān)。在本文中我們所討論的Java虛擬機(jī)(JVM)主要針對(duì)第三種情況而言。它可以被看成一個(gè)想象中的機(jī)器,在實(shí)際的計(jì)算機(jī)上通過(guò)軟件模擬來(lái)實(shí)現(xiàn),有自己想象中的硬件,如處理器、堆棧、寄存器等,還有自己相應(yīng)的指令系統(tǒng)。

    JVM在它的生存周期中有一個(gè)明確的任務(wù),那就是運(yùn)行Java程序,因此當(dāng)Java程序啟動(dòng)的時(shí)候,就產(chǎn)生JVM的一個(gè)實(shí)例;當(dāng)程序運(yùn)行結(jié)束的時(shí)候,該實(shí)例也跟著消失了。下面我們從JVM的體系結(jié)構(gòu)和它的運(yùn)行過(guò)程這兩個(gè)方面來(lái)對(duì)它進(jìn)行比較深入的研究。

    2??Java虛擬機(jī)的體系結(jié)構(gòu)

    剛才已經(jīng)提到,JVM可以由不同的廠商來(lái)實(shí)現(xiàn)。由于廠商的不同必然導(dǎo)致JVM在實(shí)現(xiàn)上的一些不同,然而JVM還是可以實(shí)現(xiàn)跨平臺(tái)的特性,這就要?dú)w功于設(shè)計(jì)JVM時(shí)的體系結(jié)構(gòu)了。

    我們知道,一個(gè)JVM實(shí)例的行為不光是它自己的事,還涉及到它的子系統(tǒng)、存儲(chǔ)區(qū)域、數(shù)據(jù)類型和指令這些部分,它們描述了JVM的一個(gè)抽象的內(nèi)部體系結(jié)構(gòu),其目的不光規(guī)定實(shí)現(xiàn)JVM時(shí)它內(nèi)部的體系結(jié)構(gòu),更重要的是提供了一種方式,用于嚴(yán)格定義實(shí)現(xiàn)時(shí)的外部行為。每個(gè)JVM都有兩種機(jī)制,一個(gè)是裝載具有合適名稱的類(類或是接口),叫做類裝載子系統(tǒng);另外的一個(gè)負(fù)責(zé)執(zhí)行包含在已裝載的類或接口中的指令,叫做運(yùn)行引擎。每個(gè)JVM又包括方法區(qū)、堆、Java棧、程序計(jì)數(shù)器和本地方法棧這五個(gè)部分,這幾個(gè)部分和類裝載機(jī)制與運(yùn)行引擎機(jī)制一起組成的體系結(jié)構(gòu)圖為:


    圖3??JVM的體系結(jié)構(gòu)

    JVM的每個(gè)實(shí)例都有一個(gè)它自己的方法域和一個(gè)堆,運(yùn)行于JVM內(nèi)的所有的線程都共享這些區(qū)域;當(dāng)虛擬機(jī)裝載類文件的時(shí)候,它解析其中的二進(jìn)制數(shù)據(jù)所包含的類信息,并把它們放到方法域中;當(dāng)程序運(yùn)行的時(shí)候,JVM把程序初始化的所有對(duì)象置于堆上;而每個(gè)線程創(chuàng)建的時(shí)候,都會(huì)擁有自己的程序計(jì)數(shù)器和Java棧,其中程序計(jì)數(shù)器中的值指向下一條即將被執(zhí)行的指令,線程的Java棧則存儲(chǔ)為該線程調(diào)用Java方法的狀態(tài);本地方法調(diào)用的狀態(tài)被存儲(chǔ)在本地方法棧,該方法棧依賴于具體的實(shí)現(xiàn)。

    下面分別對(duì)這幾個(gè)部分進(jìn)行說(shuō)明。

    執(zhí)行引擎處于JVM的核心位置,在Java虛擬機(jī)規(guī)范中,它的行為是由指令集所決定的。盡管對(duì)于每條指令,規(guī)范很詳細(xì)地說(shuō)明了當(dāng)JVM執(zhí)行字節(jié)碼遇到指令時(shí),它的實(shí)現(xiàn)應(yīng)該做什么,但對(duì)于怎么做卻言之甚少。Java虛擬機(jī)支持大約248個(gè)字節(jié)碼。每個(gè)字節(jié)碼執(zhí)行一種基本的CPU運(yùn)算,例如,把一個(gè)整數(shù)加到寄存器,子程序轉(zhuǎn)移等。Java指令集相當(dāng)于Java程序的匯編語(yǔ)言。

    Java指令集中的指令包含一個(gè)單字節(jié)的操作符,用于指定要執(zhí)行的操作,還有0個(gè)或多個(gè)操作數(shù),提供操作所需的參數(shù)或數(shù)據(jù)。許多指令沒(méi)有操作數(shù),僅由一個(gè)單字節(jié)的操作符構(gòu)成。

    												虛擬機(jī)的內(nèi)層循環(huán)的執(zhí)行過(guò)程如下: 
    do{ 
    取一個(gè)操作符字節(jié); 
    根據(jù)操作符的值執(zhí)行一個(gè)動(dòng)作; 
    }while(程序未結(jié)束)
    
    				
    				

    由于指令系統(tǒng)的簡(jiǎn)單性,使得虛擬機(jī)執(zhí)行的過(guò)程十分簡(jiǎn)單,從而有利于提高執(zhí)行的效率。指令中操作數(shù)的數(shù)量和大小是由操作符決定的。如果操作數(shù)比一個(gè)字節(jié)大,那么它存儲(chǔ)的順序是高位字節(jié)優(yōu)先。例如,一個(gè)16位的參數(shù)存放時(shí)占用兩個(gè)字節(jié),其值為:

    第一個(gè)字節(jié)*256+第二個(gè)字節(jié)字節(jié)碼。

    指令流一般只是字節(jié)對(duì)齊的。指令tableswitch和lookup是例外,在這兩條指令內(nèi)部要求強(qiáng)制的4字節(jié)邊界對(duì)齊。

    對(duì)于本地方法接口,實(shí)現(xiàn)JVM并不要求一定要有它的支持,甚至可以完全沒(méi)有。Sun公司實(shí)現(xiàn)Java本地接口(JNI)是出于可移植性的考慮,當(dāng)然我們也可以設(shè)計(jì)出其它的本地接口來(lái)代替Sun公司的JNI。但是這些設(shè)計(jì)與實(shí)現(xiàn)是比較復(fù)雜的事情,需要確保垃圾回收器不會(huì)將那些正在被本地方法調(diào)用的對(duì)象釋放掉。

    Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),類的實(shí)例(對(duì)象)從中分配空間,它的管理是由垃圾回收來(lái)負(fù)責(zé)的:不給程序員顯式釋放對(duì)象的能力。Java不規(guī)定具體使用的垃圾回收算法,可以根據(jù)系統(tǒng)的需求使用各種各樣的算法。

    Java方法區(qū)與傳統(tǒng)語(yǔ)言中的編譯后代碼或是Unix進(jìn)程中的正文段類似。它保存方法代碼(編譯后的java代碼)和符號(hào)表。在當(dāng)前的Java實(shí)現(xiàn)中,方法代碼不包括在垃圾回收堆中,但計(jì)劃在將來(lái)的版本中實(shí)現(xiàn)。每個(gè)類文件包含了一個(gè)Java類或一個(gè)Java界面的編譯后的代碼??梢哉f(shuō)類文件是Java語(yǔ)言的執(zhí)行代碼文件。為了保證類文件的平臺(tái)無(wú)關(guān)性,Java虛擬機(jī)規(guī)范中對(duì)類文件的格式也作了詳細(xì)的說(shuō)明。其具體細(xì)節(jié)請(qǐng)參考Sun公司的Java虛擬機(jī)規(guī)范。

    Java虛擬機(jī)的寄存器用于保存機(jī)器的運(yùn)行狀態(tài),與微處理器中的某些專用寄存器類似。Java虛擬機(jī)的寄存器有四種:

    1. pc: Java程序計(jì)數(shù)器;
    2. optop: 指向操作數(shù)棧頂端的指針;
    3. frame: 指向當(dāng)前執(zhí)行方法的執(zhí)行環(huán)境的指針;。
    4. vars: 指向當(dāng)前執(zhí)行方法的局部變量區(qū)第一個(gè)變量的指針。

    在上述體系結(jié)構(gòu)圖中,我們所說(shuō)的是第一種,即程序計(jì)數(shù)器,每個(gè)線程一旦被創(chuàng)建就擁有了自己的程序計(jì)數(shù)器。當(dāng)線程執(zhí)行Java方法的時(shí)候,它包含該線程正在被執(zhí)行的指令的地址。但是若線程執(zhí)行的是一個(gè)本地的方法,那么程序計(jì)數(shù)器的值就不會(huì)被定義。

    Java虛擬機(jī)的棧有三個(gè)區(qū)域:局部變量區(qū)、運(yùn)行環(huán)境區(qū)、操作數(shù)區(qū)。

    局部變量區(qū)

    每個(gè)Java方法使用一個(gè)固定大小的局部變量集。它們按照與vars寄存器的字偏移量來(lái)尋址。局部變量都是32位的。長(zhǎng)整數(shù)和雙精度浮點(diǎn)數(shù)占據(jù)了兩個(gè)局部變量的空間,卻按照第一個(gè)局部變量的索引來(lái)尋址。(例如,一個(gè)具有索引n的局部變量,如果是一個(gè)雙精度浮點(diǎn)數(shù),那么它實(shí)際占據(jù)了索引n和n+1所代表的存儲(chǔ)空間)虛擬機(jī)規(guī)范并不要求在局部變量中的64位的值是64位對(duì)齊的。虛擬機(jī)提供了把局部變量中的值裝載到操作數(shù)棧的指令,也提供了把操作數(shù)棧中的值寫入局部變量的指令。

    運(yùn)行環(huán)境區(qū)

    在運(yùn)行環(huán)境中包含的信息用于動(dòng)態(tài)鏈接,正常的方法返回以及異常捕捉。

    動(dòng)態(tài)鏈接

    運(yùn)行環(huán)境包括對(duì)指向當(dāng)前類和當(dāng)前方法的解釋器符號(hào)表的指針,用于支持方法代碼的動(dòng)態(tài)鏈接。方法的class文件代碼在引用要調(diào)用的方法和要訪問(wèn)的變量時(shí)使用符號(hào)。動(dòng)態(tài)鏈接把符號(hào)形式的方法調(diào)用翻譯成實(shí)際方法調(diào)用,裝載必要的類以解釋還沒(méi)有定義的符號(hào),并把變量訪問(wèn)翻譯成與這些變量運(yùn)行時(shí)的存儲(chǔ)結(jié)構(gòu)相應(yīng)的偏移地址。動(dòng)態(tài)鏈接方法和變量使得方法中使用的其它類的變化不會(huì)影響到本程序的代碼。

    正常的方法返回

    如果當(dāng)前方法正常地結(jié)束了,在執(zhí)行了一條具有正確類型的返回指令時(shí),調(diào)用的方法會(huì)得到一個(gè)返回值。執(zhí)行環(huán)境在正常返回的情況下用于恢復(fù)調(diào)用者的寄存器,并把調(diào)用者的程序計(jì)數(shù)器增加一個(gè)恰當(dāng)?shù)臄?shù)值,以跳過(guò)已執(zhí)行過(guò)的方法調(diào)用指令,然后在調(diào)用者的執(zhí)行環(huán)境中繼續(xù)執(zhí)行下去。

    異常捕捉

    異常情況在Java中被稱作Error(錯(cuò)誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:①動(dòng)態(tài)鏈接錯(cuò),如無(wú)法找到所需的class文件。②運(yùn)行時(shí)錯(cuò),如對(duì)一個(gè)空指針的引用。程序使用了throw語(yǔ)句。

    當(dāng)異常發(fā)生時(shí),Java虛擬機(jī)采取如下措施:

    • 檢查與當(dāng)前方法相聯(lián)系的catch子句表。每個(gè)catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。
    • 與異常相匹配的catch子句應(yīng)該符合下面的條件:造成異常的指令在其指令范圍之內(nèi),發(fā)生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那么系統(tǒng)轉(zhuǎn)移到指定的異常處理塊處執(zhí)行;如果沒(méi)有找到異常處理塊,重復(fù)尋找匹配的catch子句的過(guò)程,直到當(dāng)前方法的所有嵌套的catch子句都被檢查過(guò)。
    • 由于虛擬機(jī)從第一個(gè)匹配的catch子句處繼續(xù)執(zhí)行,所以catch子句表中的順序是很重要的。因?yàn)镴ava代碼是結(jié)構(gòu)化的,因此總可以把某個(gè)方法的所有的異常處理器都按序排列到一個(gè)表中,對(duì)任意可能的程序計(jì)數(shù)器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計(jì)數(shù)器值下發(fā)生的異常情況。
    • 如果找不到匹配的catch子句,那么當(dāng)前方法得到一個(gè)"未截獲異常"的結(jié)果并返回到當(dāng)前方法的調(diào)用者,好像異常剛剛在其調(diào)用者中發(fā)生一樣。如果在調(diào)用者中仍然沒(méi)有找到相應(yīng)的異常處理塊,那么這種錯(cuò)誤將被傳播下去。如果錯(cuò)誤被傳播到最頂層,那么系統(tǒng)將調(diào)用一個(gè)缺省的異常處理塊。

    操作數(shù)棧區(qū)

    機(jī)器指令只從操作數(shù)棧中取操作數(shù),對(duì)它們進(jìn)行操作,并把結(jié)果返回到棧中。選擇棧結(jié)構(gòu)的原因是:在只有少量寄存器或非通用寄存器的機(jī)器(如Intel486)上,也能夠高效地模擬虛擬機(jī)的行為。操作數(shù)棧是32位的。它用于給方法傳遞參數(shù),并從方法接收結(jié)果,也用于支持操作的參數(shù),并保存操作的結(jié)果。例如,iadd指令將兩個(gè)整數(shù)相加。相加的兩個(gè)整數(shù)應(yīng)該是操作數(shù)棧頂?shù)膬蓚€(gè)字。這兩個(gè)字是由先前的指令壓進(jìn)堆棧的。這兩個(gè)整數(shù)將從堆棧彈出、相加,并把結(jié)果壓回到操作數(shù)棧中。

    每個(gè)原始數(shù)據(jù)類型都有專門的指令對(duì)它們進(jìn)行必須的操作。每個(gè)操作數(shù)在棧中需要一個(gè)存儲(chǔ)位置,除了long和double型,它們需要兩個(gè)位置。操作數(shù)只能被適用于其類型的操作符所操作。例如,壓入兩個(gè)int類型的數(shù),如果把它們當(dāng)作是一個(gè)long類型的數(shù)則是非法的。在Sun的虛擬機(jī)實(shí)現(xiàn)中,這個(gè)限制由字節(jié)碼驗(yàn)證器強(qiáng)制實(shí)行。但是,有少數(shù)操作(操作符dupe和swap),用于對(duì)運(yùn)行時(shí)數(shù)據(jù)區(qū)進(jìn)行操作時(shí)是不考慮類型的。

    本地方法棧,當(dāng)一個(gè)線程調(diào)用本地方法時(shí),它就不再受到虛擬機(jī)關(guān)于結(jié)構(gòu)和安全限制方面的約束,它既可以訪問(wèn)虛擬機(jī)的運(yùn)行期數(shù)據(jù)區(qū),也可以使用本地處理器以及任何類型的棧。例如,本地棧是一個(gè)C語(yǔ)言的棧,那么當(dāng)C程序調(diào)用C函數(shù)時(shí),函數(shù)的參數(shù)以某種順序被壓入棧,結(jié)果則返回給調(diào)用函數(shù)。在實(shí)現(xiàn)Java虛擬機(jī)時(shí),本地方法接口使用的是C語(yǔ)言的模型棧,那么它的本地方法棧的調(diào)度與使用則完全與C語(yǔ)言的棧相同。

    3??Java虛擬機(jī)的運(yùn)行過(guò)程

    上面對(duì)虛擬機(jī)的各個(gè)部分進(jìn)行了比較詳細(xì)的說(shuō)明,下面通過(guò)一個(gè)具體的例子來(lái)分析它的運(yùn)行過(guò)程。

    虛擬機(jī)通過(guò)調(diào)用某個(gè)指定類的方法main啟動(dòng),傳遞給main一個(gè)字符串?dāng)?shù)組參數(shù),使指定的類被裝載,同時(shí)鏈接該類所使用的其它的類型,并且初始化它們。例如對(duì)于程序:

    												class HelloApp 
    {
    	public static void main(String[] args) 
    	{
    		System.out.println("Hello World!"); 
    		for (int i = 0; i < args.length; i++ )
    		{
    			System.out.println(args[i]);
    		}
    	}
    }
    
    				
    				

    編譯后在命令行模式下鍵入: java HelloApp run virtual machine

    將通過(guò)調(diào)用HelloApp的方法main來(lái)啟動(dòng)java虛擬機(jī),傳遞給main一個(gè)包含三個(gè)字符串"run"、"virtual"、"machine"的數(shù)組。現(xiàn)在我們略述虛擬機(jī)在執(zhí)行HelloApp時(shí)可能采取的步驟。

    開(kāi)始試圖執(zhí)行類HelloApp的main方法,發(fā)現(xiàn)該類并沒(méi)有被裝載,也就是說(shuō)虛擬機(jī)當(dāng)前不包含該類的二進(jìn)制代表,于是虛擬機(jī)使用ClassLoader試圖尋找這樣的二進(jìn)制代表。如果這個(gè)進(jìn)程失敗,則拋出一個(gè)異常。類被裝載后同時(shí)在main方法被調(diào)用之前,必須對(duì)類HelloApp與其它類型進(jìn)行鏈接然后初始化。鏈接包含三個(gè)階段:檢驗(yàn),準(zhǔn)備和解析。檢驗(yàn)檢查被裝載的主類的符號(hào)和語(yǔ)義,準(zhǔn)備則創(chuàng)建類或接口的靜態(tài)域以及把這些域初始化為標(biāo)準(zhǔn)的默認(rèn)值,解析負(fù)責(zé)檢查主類對(duì)其它類或接口的符號(hào)引用,在這一步它是可選的。類的初始化是對(duì)類中聲明的靜態(tài)初始化函數(shù)和靜態(tài)域的初始化構(gòu)造方法的執(zhí)行。一個(gè)類在初始化之前它的父類必須被初始化。整個(gè)過(guò)程如下:


    圖4:虛擬機(jī)的運(yùn)行過(guò)程

    4??結(jié)束語(yǔ)

    本文通過(guò)對(duì)JVM的體系結(jié)構(gòu)的深入研究以及一個(gè)Java程序執(zhí)行時(shí)虛擬機(jī)的運(yùn)行過(guò)程的詳細(xì)分析,意在剖析清楚Java虛擬機(jī)的機(jī)理。

    posted @ 2006-07-21 18:14 sunfruit 閱讀(393) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]Oracle Spatial新驅(qū)動(dòng)的查詢記錄實(shí)例

    --sunfruit
    ??? Oracle的空間數(shù)據(jù)庫(kù)的操作驅(qū)動(dòng)更新了,新的驅(qū)動(dòng)適用于Oracle8.0或以上,新驅(qū)動(dòng)在對(duì)數(shù)據(jù)庫(kù)的操作上面和原有的驅(qū)動(dòng)差別比較大,不過(guò)有一點(diǎn):使用變得簡(jiǎn)單了
    ??? 建立空間數(shù)據(jù)庫(kù)和建立空間索引的步驟就略過(guò)了,那些網(wǎng)上有很多例子,而且實(shí)現(xiàn)方式上面也沒(méi)有變化,下面列出查詢空間數(shù)據(jù)庫(kù)記錄的代碼:

    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import oracle.spatial.geometry.JGeometry;
    import java.sql.PreparedStatement;
    import oracle.sql.STRUCT;
    import java.sql.Connection;

    /**
    ?* <p>Title: </p>
    ?*
    ?* <p>Description: </p>
    ?*
    ?* <p>Copyright: Copyright (c) 2006</p>
    ?*
    ?* <p>Company: </p>
    ?*
    ?* @author?sunfruit
    ?* @version 1.0
    ?*/
    public class SdoSelect {
    ? public SdoSelect() {
    ? }
    ? public static void main(String[] args) {
    ??? String driver = "oracle.jdbc.driver.OracleDriver";
    ??? String url = "jdbc:oracle:thin:@172.16.75.200:1521:starmap";
    ??? String uid = "hmbst";
    ??? String psw = "hmbst";
    ??? Connection conn = null;
    ??? PreparedStatement ps=null;
    ??? try {
    ????? Class.forName(driver);
    ????? conn = DriverManager.getConnection(url, uid, psw);

    ????? JGeometry jGeometry=new JGeometry(41884696,14377039,42884696,14477039,0);
    ????? STRUCT obj =jGeometry.store(jGeometry,conn);
    ????? String sql = "SELECT * FROM POISDO p WHERE sdo_filter(p.gshape,?,'querytype=window')='TRUE'";
    ????? ps = conn.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    ????? ps.clearParameters();
    ????? ps.setObject(1, obj);
    ????? // 插入點(diǎn)地物記錄
    ????? ResultSet rs=ps.executeQuery();
    ????? while(rs.next())
    ????? {
    ??????? STRUCT st = (oracle.sql.STRUCT)rs.getObject("gshape");
    ??????? JGeometry j_geom = JGeometry.load(st);
    ??????? double[] dou=j_geom.getPoint();
    ??????? String buff="";
    ??????? for(int i=0;i<dou.length;i++)
    ??????? {
    ????????? buff=buff+String.valueOf((int)dou[i])+"?? ";
    ??????? }
    ??????? System.out.println(buff);
    ????? }
    ??? }
    ??? catch (Exception ex) {
    ????? ex.printStackTrace();
    ??? }
    ??? finally
    ??? {
    ????? if(conn!=null)
    ????? {
    ??????? try {
    ????????? conn.close();
    ??????? }
    ??????? catch (SQLException ex) {
    ????????? ex.printStackTrace();
    ??????? }
    ????? }
    ????? if(ps!=null)
    ????? {
    ??????? try {
    ????????? ps.close();
    ??????? }
    ??????? catch (SQLException ex) {
    ????????? ex.printStackTrace();
    ??????? }
    ????? }

    ??? }
    ? }

    }

    表POISDO的結(jié)構(gòu)如下
    create table poi (
    ? id?INTEGER,
    ??gname?VARCHAR2(256),
    ??gshape?MDSYS.SDO_GEOMETRY);

    posted @ 2006-07-20 15:28 sunfruit 閱讀(563) | 評(píng)論 (0)編輯 收藏

    [原創(chuàng)]Oracle Spatial新驅(qū)動(dòng)的添加記錄實(shí)例

    ??? --sunfruit
    ??? Oracle的空間數(shù)據(jù)庫(kù)的操作驅(qū)動(dòng)更新了,新的驅(qū)動(dòng)適用于Oracle8.0或以上,新驅(qū)動(dòng)在對(duì)數(shù)據(jù)庫(kù)的操作上面和原有的驅(qū)動(dòng)差別比較大,不過(guò)有一點(diǎn):使用變得簡(jiǎn)單了
    ??? 建立空間數(shù)據(jù)庫(kù)和建立空間索引的步驟就略過(guò)了,那些網(wǎng)上有很多例子,而且實(shí)現(xiàn)方式上面也沒(méi)有變化,下面列出添加一條空間數(shù)據(jù)庫(kù)記錄的代碼:

    import java.sql.*;
    import oracle.sql.*;
    import oracle.spatial.geometry.JGeometry;

    /**
    ?* <p>Title: </p>
    ?*
    ?* <p>Description: </p>
    ?*
    ?* <p>Copyright: Copyright (c) 2006</p>
    ?*
    ?* <p>Company: </p>
    ?*
    ?* @author not attributable
    ?* @version 1.0
    ?*/
    public class SdoAdd {
    ? public static void main(String[] args) {
    ??? String driver = "oracle.jdbc.driver.OracleDriver";
    ??? String url = "jdbc:oracle:thin:@172.16.75.200:1521:starmap";
    ??? String uid = "hmbst";
    ??? String psw = "hmbst";
    ??? Connection conn = null;
    ??? PreparedStatement ps=null;
    ??? try {
    ????? Class.forName(driver);
    ????? conn = DriverManager.getConnection(url, uid, psw);
    ?????
    ????? JGeometry jGeometry=new JGeometry(41884696,14377039,0);
    ????? STRUCT obj =jGeometry.store(jGeometry,conn);
    ????? String sql =
    ????????? "insert into POISDO values(seq_poi_id.nextval,?,?)";
    ????? ps = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
    ????? ps.clearParameters();
    ????? ps.setString(1, "我的家");
    ????? ps.setObject(2, obj);
    ????? // 插入點(diǎn)地物記錄
    ????? ps.executeUpdate();
    ????? conn.commit();
    ??? }
    ??? catch (Exception ex) {
    ????? ex.printStackTrace();
    ??? }
    ??? finally
    ??? {
    ????? if(conn!=null)
    ????? {
    ??????? try {
    ????????? conn.close();
    ??????? }
    ??????? catch (SQLException ex) {
    ????????? ex.printStackTrace();
    ??????? }
    ????? }
    ????? if(ps!=null)
    ????? {
    ??????? try {
    ????????? ps.close();
    ??????? }
    ??????? catch (SQLException ex) {
    ????????? ex.printStackTrace();
    ??????? }
    ????? }

    ??? }
    ? }
    }

    表POISDO的結(jié)構(gòu)如下
    create table poi (
    ? id?INTEGER,
    ??gname?VARCHAR2(256),
    ??gshape?MDSYS.SDO_GEOMETRY);

    posted @ 2006-07-20 15:25 sunfruit 閱讀(441) | 評(píng)論 (0)編輯 收藏

    Oracle Spatial詳解

    Step1. 創(chuàng)建一張表,其中shape用來(lái)存放空間數(shù)據(jù)
    CREATE TABLE mylake (
    ??? feature_id NUMBER PRIMARY KEY,
    ??? name VARCHAR2(32),
    ??? shape MDSYS.SDO_GEOMETRY);

    Step2. 在user_sdo_geom_metadata 表中插入新記錄,用于描述空間字段
    INSERT INTO user_sdo_geom_metadata VALUES (
    ??? 'mylake',????//---表名
    ??? 'shape',????//---字段名
    ??? MDSYS.SDO_DIM_ARRAY(???
    ??????? MDSYS.SDO_DIM_ELEMENT('X', 0, 100, 0.05),????//---X維最小,最大值和容忍度。
    ??????? MDSYS.SDO_DIM_ELEMENT('Y', 0, 100, 0.05)????//---Y維最小,最大值和容忍度
    ??? ),
    ??? NULL????//---坐標(biāo)系,缺省為笛卡爾坐標(biāo)系
    );

    Step3. 創(chuàng)建空間索引
    CREATE INDEX mylake_idx ON mylake(shape)
    ??? INDEXTYPE IS MDSYS.SPATIAL_INDEX

    Step4. 插入空間數(shù)據(jù)
    Oracle Spatial用MDSYS.SDO_GEOMETRY來(lái)存儲(chǔ)空間數(shù)據(jù),定義為:CREATE TYPE sdo_geometry AS OBJECT (
    ??? SDO_GTYPE NUMBER,
    ??? SDO_SRID NUMBER,
    ??? SDO_POINT SDO_POINT_TYPE,
    ??? SDO_ELEM_INFO MDSYS.SDO_ELEM_INFO_ARRAY,
    ??? SDO_ORDINATES MDSYS.SDO_ORDINATE_ARRAY);
    SDO_GTYPE:用四個(gè)數(shù)字定義了所有的形狀
    ??????????? 第一位:維數(shù)
    ??????????? 第二位:線性表示。用于3,4維數(shù)據(jù),二維為0
    ??????????? 最后兩位:
    ValueGeometryDescription
    00UNKNOWN_GEOMETRYSpatial ignores this value
    01POINTA single point element
    02LINE or CURVEContains one line string element that may be linear, curved or both
    03POLYGONContains one polygon element with or without other polygon elements in it
    04COLLECTIONA heterogeneous collection of elements
    05MULTIPOINTContains one or more points
    06MULTILINE or MULTICURVEContains one or more line string elements
    07MULTIPOLYGONContains multiple polygon elements that maybe disjoint

    SDO_SRID:坐標(biāo)系,NULL為笛卡爾坐標(biāo)系。
    SDO_POINT:
    Oracle Spatial也可定義單個(gè)的點(diǎn),SDO_POINT的定義:
    ??? CREATE TYPE sdo_point_type AS OBJECT (X NUMBER,Y NUMBER,Z NUMBER);
    ??? 如何是二維,Z為NULL。
    SDO_ELEM_INFO:
    每三個(gè)值描述一個(gè)元素。
    ????????????????第一個(gè)值:第一個(gè)頂點(diǎn)在SDO_ORDINATES_ARR開(kāi)始位置
    ????????????????第二個(gè)值:元素類型
    ????????????????第三個(gè)值:頂點(diǎn)連接方式:1-通過(guò)直線連接,2-通過(guò)圓弧連接

    ??? 定義為
    ??? CREATE TYPE sdo_elem_info_array AS VARRAY (1048576) of NUMBER;
    SDO_ORDINATES:幾何圖形所有頂點(diǎn)列表。定義為
    ??? CREATE TYPE sdo_ordinate_array AS VARRAY (1048576) of NUMBER;

    FONT color=#003366>// 插入包含一個(gè)島嶼的湖泊
    INSERT INTO mylake VALUES(
    ??? 10,?
    ??? 'Lake Calhoun',?
    ??? MDSYS.SDO_GEOMETRY(
    ??????? 2003,
    ??????? NULL,
    ??????? NULL,
    ??????? MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1, 19,2003,1),
    ??????? MDSYS.SDO_ORDINATE_ARRAY(0,0, 10,0, 10,10, 0,10, 0,0, 4,4, 6,4, 6,6, 4,6, 4,4)
    ??? ));

    // 插入兩艘小船
    INSERT INTO mylake VALUES(
    ??? 11,?
    ??? 'The Windswept',?
    ??? MDSYS.SDO_GEOMETRY(
    ??????? 2003,
    ??????? NULL,
    ??????? NULL,
    ??????? MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
    ??????? MDSYS.SDO_ORDINATE_ARRAY(2,2, 3,2, 3,2, 2,3, 2,2)
    ??? )
    );

    INSERT INTO mylake VALUES(
    ??? 12,?
    ??? 'Blue Crest',?
    ??? MDSYS.SDO_GEOMETRY(
    ??????? 2003,
    ??????? NULL,
    ??????? NULL,
    ??????? MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
    ??????? MDSYS.SDO_ORDINATE_ARRAY(7,7, 8,7, 8,7, 7,8, 7,7)
    ??? )
    );

    Step4. 查詢
    Oracle Spatial查詢數(shù)據(jù)包括二個(gè)處理過(guò)程:
    1.只通過(guò)索引查詢候選項(xiàng)。通過(guò)函數(shù)SDO_FILTER實(shí)現(xiàn):
    SDO_FILTER(geometry1 MDSYS.SDO_GEOMETRY,?geometry2 MDSYS.SDO_GEOMETRY, params VARCHAR2)
    geometry1:
    必須是被索引的幾何數(shù)據(jù)
    geometry2:不一定是表中的空間字段,也不要求被索引
    params:Filter類型
    ??????? querytype=WINDOW:geometry2不要求來(lái)自表
    ??????? querytype=JOIN:geometry2必須來(lái)自表

    SELECT name boat_name
    FROM mylake t
    WHERE feature_id = 12
    AND SDO_FILTER(t.shape, mdsys.sdo_geometry(2003,NULL,NULL,
    ??? mdsys.sdo_elem_info_array(1,1003,1),
    ??? mdsys.sdo_ordinate_array(2,2, 5,2, 5,5, 2,5, 2,2)),
    ??? 'querytype=WINDOW') = 'TRUE';


    2.再檢查每個(gè)候選項(xiàng)是否和條件精確匹配。通過(guò)函數(shù)SDO_RELATE實(shí)現(xiàn):
    SDO_RELATE(geometry1 MDSYS.SDO_GEOMETRY, geometry2 MDSYS.SDO_GEOMETRY, params VARCHAR2)
    params:
    masktype類型

  • DISJOINT — the boundaries and interiors do not intersect
  • TOUCH — the boundaries intersect but the interiors do not intersect
  • OVERLAPBDYDISJOINT — the interior of one object intersects the boundary and interior of the other object, but the two boundaries do not intersect. This relationship occurs, for example, when a line originates outside a polygon and ends inside that polygon.
  • OVERLAPBDYINTERSECT — the boundaries and interiors of the two objects intersect
  • EQUAL — the two objects have the same boundary and interior
  • CONTAINS — the interior and boundary of one object is completely contained in the interior of the other object
  • COVERS — the interior of one object is completely contained in the interior of the other object and their boundaries intersect
  • INSIDE — the opposite of CONTAINS. A INSIDE B implies B CONTAINS A.
  • COVEREDBY — the opposite of COVERS. A COVEREDBY B implies B COVERS A.
  • ON — the interior and boundary of one object is on the boundary of the other object (and the second object covers the first object). This relationship occurs, for example, when a line is on the boundary of a polygon.
  • ANYINTERACT — the objects are non-disjoint.

    // 選擇在定義矩形內(nèi)的所有小船
    SELECT name boat_name
    FROM mylake t
    WHERE feature_id = 12
    AND SDO_FILTER(t.shape, mdsys.sdo_geometry(2003,NULL,NULL,
    ??? mdsys.sdo_elem_info_array(1,1003,1),
    ??? mdsys.sdo_ordinate_array(2,2, 5,2, 5,5, 2,5, 2,2)),
    ??? 'querytype=WINDOW') = 'TRUE'
    AND SDO_RELATE(t.shape, mdsys.sdo_geometry(2003,NULL,NULL,
    ??? mdsys.sdo_elem_info_array(1,1003,1),
    ??? mdsys.sdo_ordinate_array(2,2, 5,2, 5,5, 2,5, 2,2)),
    ??? 'masktype=INSIDE querytype=WINDOW') = 'TRUE'

    // masktype可聯(lián)合使用
    SELECT feature_id id
    FROM mylake t
    WHERE feature_id = 12
    AND SDO_FILTER(t.shape, mdsys.sdo_geometry(2003,NULL,NULL,
    ??? mdsys.sdo_elem_info_array(1,1003,1),
    ??? mdsys.sdo_ordinate_array(2,2, 5,2, 5,5, 2,5, 2,2)),
    ??? 'querytype=WINDOW') = 'TRUE'
    AND SDO_RELATE(t.shape, mdsys.sdo_geometry(2003,NULL,NULL,
    ??? mdsys.sdo_elem_info_array(1,1003,1),
    ??? mdsys.sdo_ordinate_array(2,2, 5,2, 5,5, 2,5, 2,2)),
    ??? 'masktype=INSIDE+TOUCH querytype=WINDOW') = 'TRUE'

    Oracle Spatial 提供的其他查詢函數(shù):
    QueryDescription
    SDO_NNNearest neighbor
    SDO_SDO_WITHIN_DISTANCEAll geometries with a certain distance
    FunctionsDescription
    SDO_GEOM.SDO_MBRThe minimum bounding rectangle for a geometry
    SDO_GEOM.SDO_DISTANCEThe distance between two geometries
    SDO_GEOM.SDO_INTERSECTIONProvides the intersection point of two geometries

  • posted @ 2006-07-19 15:21 sunfruit 閱讀(1499) | 評(píng)論 (1)編輯 收藏

    主站蜘蛛池模板: 亚洲av无码乱码国产精品fc2| 国产中文字幕在线免费观看| 在线中文高清资源免费观看| 亚洲乱码在线视频| 国产精品成人免费福利| 亚洲成aⅴ人片在线影院八| 最近新韩国日本免费观看| 亚洲色欲www综合网| 在线观看免费中文视频| 亚洲精品影院久久久久久| 84pao国产成视频免费播放| 亚洲网址在线观看| 我的小后妈韩剧在线看免费高清版 | 无码国产精品一区二区免费式影视| 亚洲成无码人在线观看| 99在线精品视频观看免费| 国产成人亚洲精品| 韩国欧洲一级毛片免费| 黄色网址在线免费观看| 久久精品国产亚洲7777| 你懂得的在线观看免费视频| 亚洲av日韩av激情亚洲| 亚洲电影在线免费观看| 国产 亚洲 中文在线 字幕| 色视频色露露永久免费观看| 污污视频免费观看网站| 亚洲综合另类小说色区| 免费在线观看一级片| 亚洲视频免费观看| 成年女人午夜毛片免费看| 无码一区二区三区亚洲人妻| yy6080亚洲一级理论| 99久久精品毛片免费播放| 亚洲综合久久综合激情久久| 好先生在线观看免费播放| 久久亚洲精品成人无码| ZZIJZZIJ亚洲日本少妇JIZJIZ| a在线免费观看视频| 亚洲婷婷天堂在线综合| 日韩免费视频在线观看| 一级做a爰全过程免费视频毛片|