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

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

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

    GUI篇: 適合于圖形用戶界面的應(yīng)用(Applet和普通應(yīng)用)

    這一部分介紹的內(nèi)容適合于圖形用戶界面的應(yīng)用(Applet和普通應(yīng)用),要用到AWT或Swing。

      3.1 用JAR壓縮類文件

      Java檔案文件(JAR文件)是根據(jù)JavaBean標(biāo)準(zhǔn)壓縮的文件,是發(fā)布JavaBean組件的主要方式和推薦方式。JAR檔案有助于減少文件體積,縮短下載時(shí)間。例如,它有助于Applet提高啟動(dòng)速度。一個(gè)JAR文件可以包含一個(gè)或者多個(gè)相關(guān)的Bean以及支持文件,比如圖形、聲音、HTML和其他資源。

      要在HTML/JSP文件中指定JAR文件,只需在Applet標(biāo)記中加入ARCHIVE = "name.jar"聲明。

      3.2 提示Applet裝入進(jìn)程

      你是否看到過(guò)使用Applet的網(wǎng)站,注意到在應(yīng)該運(yùn)行Applet的地方出現(xiàn)了一個(gè)占位符?當(dāng)Applet的下載時(shí)間較長(zhǎng)時(shí),會(huì)發(fā)生什么事情?最大的可能就是用戶掉頭離去。在這種情況下,顯示一個(gè)Applet正在下載的信息無(wú)疑有助于鼓勵(lì)用戶繼續(xù)等待。

      下面我們來(lái)看看一種具體的實(shí)現(xiàn)方法。首先創(chuàng)建一個(gè)很小的Applet,該Applet負(fù)責(zé)在后臺(tái)下載正式的Applet:

      import java.applet.Applet;

      import java.applet.AppletStub;

      import java.awt.Label;

      import java.awt.Graphics;

      import java.awt.GridLayout;

      public class PreLoader extends Applet implements Runnable, AppletStub

      {

       String largeAppletName;

       Label label;

       public void init()

       {

      // 要求裝載的正式Applet

      largeAppletName = getParameter("applet");

      // “請(qǐng)稍等”提示信息

      label = new Label("請(qǐng)稍等..." + largeAppletName);

      add(label);

       }

       public void run()

       {

      try

      {

       // 獲得待裝載Applet的類

       Class largeAppletClass = Class.forName(largeAppletName);

       // 創(chuàng)建待裝載Applet的實(shí)例

       Applet largeApplet = (Applet)largeAppletClass.newInstance();

       // 設(shè)置該Applet的Stub程序

       largeApplet.setStub(this);

       // 取消“請(qǐng)稍等”信息

       remove(label);

       // 設(shè)置布局

       setLayout(new GridLayout(1, 0));

       add(largeApplet);

       // 顯示正式的Applet

       largeApplet.init();

       largeApplet.start();

      }

      catch (Exception ex)

      {

       // 顯示錯(cuò)誤信息

       label.setText("不能裝入指定的Applet");

      }

      // 刷新屏幕

      validate();

       }

       public void appletResize(int width, int height)

       {

      // 把a(bǔ)ppletResize調(diào)用從stub程序傳遞到Applet

      resize(width, height);

       }

      }

     


      編譯后的代碼小于2K,下載速度很快。代碼中有幾個(gè)地方值得注意。首先,PreLoader實(shí)現(xiàn)了AppletStub接口。一般地,Applet從調(diào)用者判斷自己的codebase。在本例中,我們必須調(diào)用setStub()告訴Applet到哪里提取這個(gè)信息。另一個(gè)值得注意的地方是,AppletStub接口包含許多和Applet類一樣的方法,但appletResize()方法除外。這里我們把對(duì)appletResize()方法的調(diào)用傳遞給了resize()方法。

      3.3 在畫(huà)出圖形之前預(yù)先裝入它

      ImageObserver接口可用來(lái)接收?qǐng)D形裝入的提示信息。ImageObserver接口只有一個(gè)方法imageUpdate(),能夠用一次repaint()操作在屏幕上畫(huà)出圖形。下面提供了一個(gè)例子。

      public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)

      {

       if ((flags & ALLBITS) !=0 { repaint();

      }

      else if (flags & (ERROR |ABORT )) != 0)

      {

       error = true;

       // 文件沒(méi)有找到,考慮顯示一個(gè)占位符

       repaint();

      }

      return (flags & (ALLBITS | ERROR| ABORT)) == 0;

      }

     


      當(dāng)圖形信息可用時(shí),imageUpdate()方法被調(diào)用。如果需要進(jìn)一步更新,該方法返回true;如果所需信息已經(jīng)得到,該方法返回false。

      3.4 覆蓋update方法

      update()方法的默認(rèn)動(dòng)作是清除屏幕,然后調(diào)用paint()方法。如果使用默認(rèn)的update()方法,頻繁使用圖形的應(yīng)用可能出現(xiàn)顯示閃爍現(xiàn)象。要避免在paint()調(diào)用之前的屏幕清除操作,只需按照如下方式覆蓋update()方法:

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

     

      更理想的方案是:覆蓋update(),只重畫(huà)屏幕上發(fā)生變化的區(qū)域,如下所示:

    public void update(Graphics g)
      {

       g.clipRect(x, y, w, h);

       paint(g);

      }

     


      3.5 延遲重畫(huà)操作

      對(duì)于圖形用戶界面的應(yīng)用來(lái)說(shuō),性能低下的主要原因往往可以歸結(jié)為重畫(huà)屏幕的效率低下。當(dāng)用戶改變窗口大小或者滾動(dòng)一個(gè)窗口時(shí),這一點(diǎn)通??梢院苊黠@地觀察到。改變窗口大小或者滾動(dòng)屏幕之類的操作導(dǎo)致重畫(huà)屏幕事件大量地、快速地生成,甚至超過(guò)了相關(guān)代碼的執(zhí)行速度。對(duì)付這個(gè)問(wèn)題最好的辦法是忽略所有“遲到”的事件。

      建議在這里引入一個(gè)數(shù)毫秒的時(shí)差,即如果我們立即接收到了另一個(gè)重畫(huà)事件,可以停止處理當(dāng)前事件轉(zhuǎn)而處理最后一個(gè)收到的重畫(huà)事件;否則,我們繼續(xù)進(jìn)行當(dāng)前的重畫(huà)過(guò)程。

      如果事件要啟動(dòng)一項(xiàng)耗時(shí)的工作,分離出一個(gè)工作線程是一種較好的處理方式;否則,一些部件可能被“凍結(jié)”,因?yàn)槊看沃荒芴幚硪粋€(gè)事件。下面提供了一個(gè)事件處理的簡(jiǎn)單例子,但經(jīng)過(guò)擴(kuò)展后它可以用來(lái)控制工作線程。

      public static void runOnce(String id, final long milliseconds)

      {

       synchronized(e_queue)

       {

      // e_queue: 所有事件的集合

      if (!e_queue.containsKey(id))

      {

       e_queue.put(token, new LastOne());

      }

       }

       final LastOne lastOne = (LastOne) e_queue.get(token);

       final long time = System.currentTimeMillis();

       // 獲得當(dāng)前時(shí)間

       lastOne.time = time;

       (new Thread()

       {

      public void run()

      {

       if (milliseconds > 0)

       {

        try

        {

         Thread.sleep(milliseconds);

        }

        // 暫停線程

        atch (Exception ex) {}

       }

       synchronized(lastOne.running)

       {

        // 等待上一事件結(jié)束

        if (lastOne.time != time)

        // 只處理最后一個(gè)事件

         return;

       }

      }}).start();

       }

       private static Hashtable e_queue = new Hashtable();

       private static class LastOne

       {

      public long time=0;

      public Object running = new Object();

       }

     

      3.6 使用雙緩沖區(qū)

      在屏幕之外的緩沖區(qū)繪圖,完成后立即把整個(gè)圖形顯示出來(lái)。由于有兩個(gè)緩沖區(qū),所以程序可以來(lái)回切換。這樣,我們可以用一個(gè)低優(yōu)先級(jí)的線程負(fù)責(zé)畫(huà)圖,使得程序能夠利用空閑的CPU時(shí)間執(zhí)行其他任務(wù)。下面的偽代碼片斷示范了這種技術(shù)。

    Graphics myGraphics;
      Image myOffscreenImage = createImage(size().width, size().height);

      Graphics offscreenGraphics = myOffscreenImage.getGraphics();

      offscreenGraphics.drawImage(img, 50, 50, this);

      myGraphics.drawImage(myOffscreenImage, 0, 0, this);

     


      3.7 使用BufferedImage

      Java JDK 1.2使用了一個(gè)軟顯示設(shè)備,使得文本在不同的平臺(tái)上看起來(lái)相似。為實(shí)現(xiàn)這個(gè)功能,Java必須直接處理構(gòu)成文字的像素。由于這種技術(shù)要在內(nèi)存中大量地進(jìn)行位復(fù)制操作,早期的JDK在使用這種技術(shù)時(shí)性能不佳。為解決這個(gè)問(wèn)題而提出的Java標(biāo)準(zhǔn)實(shí)現(xiàn)了一種新的圖形類型,即BufferedImage。

      BufferedImage子類描述的圖形帶有一個(gè)可訪問(wèn)的圖形數(shù)據(jù)緩沖區(qū)。一個(gè)BufferedImage包含一個(gè)ColorModel和一組光柵圖形數(shù)據(jù)。這個(gè)類一般使用RGB(紅、綠、藍(lán))顏色模型,但也可以處理灰度級(jí)圖形。它的構(gòu)造函數(shù)很簡(jiǎn)單,如下所示:

      public BufferedImage (int width, int height, int imageType)

      ImageType允許我們指定要緩沖的是什么類型的圖形,比如5-位RGB、8-位RGB、灰度級(jí)等。

      3.8 使用VolatileImage

      許多硬件平臺(tái)和它們的操作系統(tǒng)都提供基本的硬件加速支持。例如,硬件加速一般提供矩形填充功能,和利用CPU完成同一任務(wù)相比,硬件加速的效率更高。由于硬件加速分離了一部分工作,允許多個(gè)工作流并發(fā)進(jìn)行,從而緩解了對(duì)CPU和系統(tǒng)總線的壓力,使得應(yīng)用能夠運(yùn)行得更快。利用VolatileImage可以創(chuàng)建硬件加速的圖形以及管理圖形的內(nèi)容。由于它直接利用低層平臺(tái)的能力,性能的改善程度主要取決于系統(tǒng)使用的圖形適配器。VolatileImage的內(nèi)容隨時(shí)可能丟失,也即它是“不穩(wěn)定的(volatile)”。因此,在使用圖形之前,最好檢查一下它的內(nèi)容是否丟失。VolatileImage有兩個(gè)能夠檢查內(nèi)容是否丟失的方法:

      public abstract int validate(GraphicsConfiguration gc);public abstract Boolean contentsLost();

      每次從VolatileImage對(duì)象復(fù)制內(nèi)容或者寫(xiě)入VolatileImage時(shí),應(yīng)該調(diào)用validate()方法。contentsLost()方法告訴我們,自從最后一次validate()調(diào)用之后,圖形的內(nèi)容是否丟失。

      雖然VolatileImage是一個(gè)抽象類,但不要從它這里派生子類。VolatileImage應(yīng)該通過(guò)Component.createVolatileImage()或者GraphicsConfiguration.createCompatibleVolatileImage()方法創(chuàng)建。

      3.9 使用Window Blitting

      進(jìn)行滾動(dòng)操作時(shí),所有可見(jiàn)的內(nèi)容一般都要重畫(huà),從而導(dǎo)致大量不必要的重畫(huà)工作。許多操作系統(tǒng)的圖形子系統(tǒng),包括WIN32 GDI、MacOS和X/Windows,都支持Window Blitting技術(shù)。Window Blitting技術(shù)直接在屏幕緩沖區(qū)中把圖形移到新的位置,只重畫(huà)新出現(xiàn)的區(qū)域。要在Swing應(yīng)用中使用Window Blitting技術(shù),設(shè)置方法如下:

      setScrollMode(int mode);

      在大多數(shù)應(yīng)用中,使用這種技術(shù)能夠提高滾動(dòng)速度。只有在一種情形下,Window Blitting會(huì)導(dǎo)致性能降低,即應(yīng)用在后臺(tái)進(jìn)行滾動(dòng)操作。如果是用戶在滾動(dòng)一個(gè)應(yīng)用,那么它總是在前臺(tái),無(wú)需擔(dān)心任何負(fù)面影響。

    http://blog.csdn.net/daoquan/archive/2005/03/04/310923.aspx



    posted on 2008-02-25 14:51 魯勝迪 閱讀(493) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2008年2月>
    272829303112
    3456789
    10111213141516
    17181920212223
    2425262728291
    2345678

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    文章分類

    新聞分類

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲国产小视频精品久久久三级| 美女被免费喷白浆视频| 日韩中文字幕免费| 亚洲一级高清在线中文字幕| 57pao一国产成永久免费| 色拍自拍亚洲综合图区| 中文字幕成人免费视频| 亚洲成人免费电影| 国产麻豆视频免费观看| 亚洲精品无码你懂的| 拔擦拔擦8x华人免费久久| 老司机精品视频免费| 亚洲AV成人精品日韩一区18p| 免费人成网站永久| 亚洲中文无韩国r级电影| 十八禁视频在线观看免费无码无遮挡骂过| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 亚洲片一区二区三区| 国产精品99爱免费视频| 亚洲国产精彩中文乱码AV| 69视频免费在线观看| 亚洲人AV在线无码影院观看| 免费人成在线观看视频播放| 插鸡网站在线播放免费观看| 亚洲欧洲日产国产综合网| 毛片网站免费在线观看| 一级做a爰片性色毛片免费网站| 中文字幕精品亚洲无线码一区| 免费国产黄网站在线观看| xxx毛茸茸的亚洲| 亚洲第一页综合图片自拍| a毛片在线免费观看| 亚洲一区二区久久| xvideos亚洲永久网址| 国产精品免费看久久久| 亚洲a级在线观看| MM131亚洲国产美女久久| 亚洲视频免费在线播放| 精品国产日韩亚洲一区91| 亚洲av无码潮喷在线观看| www.999精品视频观看免费|