1. gzyueqian
      13424082685
      首頁 > 新聞中心 > > 正文

      應(yīng)用雙緩沖技術(shù)解決J2ME畫面閃爍的問題

      更新時間: 2007-01-19 09:54:56來源: 粵嵌教育瀏覽量:1134

        有些時候我們可能在J2ME中遇到畫面閃爍的問題,這時候我們可以應(yīng)用雙緩沖的技術(shù)來解決,不過由于現(xiàn)在越來越多的手機自身就支持雙緩沖了。所以這里只做個簡單的介紹。

        我寫了程序本來想在NOkia 6108上比較用和不用的區(qū)別,結(jié)果這個手機自己就支持雙緩沖,所以根本沒有比較出來。不過了解這個技術(shù)還是有必要的,所以我決定還是寫出來。雙緩沖本來是在開發(fā)PC應(yīng)用程序的時候遇到的。在MIDP開發(fā)中同樣存在,當(dāng)你在屏幕上進行原始寫畫的時候,如果很復(fù)雜的話,用戶會發(fā)現(xiàn)界面在閃爍。因此你可以這樣做,首先在另一個圖片上進行paint()得操作,當(dāng)完成了以后就把它copy到屏幕上,由于通常copy得時候速度很快就不會出現(xiàn)閃爍了。這個技術(shù)就是雙緩沖。


        Canvas類提供了isDoubleBuffered()方法來判斷設(shè)備是不是支持這個功能,如果返回true的話,那么我們就沒有必要使用雙緩沖了,如果false的話,我們可以這么做:
      public DoubleCanvas(UIController uicontroller)
          {
              super();
              this.uicontroller = uicontroller;
              width = this.getWidth();
              height = this.getHeight();
              this.setCommandListener(this);
              if(!isDoubleBuffered())
              {
                  offImage = Image.createImage(width,height);
              }
                  
                 }


          
          protected void paint(Graphics arg0)
          {
              
              arg0.drawString(isDoubleBuffered()+"",width/2,height/2,Graphics.HCENTER|Graphics.TOP);
              Graphics saved = arg0;
              if(offImage != null)
              {
                  arg0 = offImage.getGraphics();
              }
              arg0.setColor(255,128,128);
              for(int i = 2,j=2;i<width/2-6&&j<height/2-6;i=i+2,j=j+2)
              {
                  arg0.drawRect(i,j,width-2*i,height-2*j);
              }
              if(arg0 != saved)
              {
                  saved.drawImage(offImage,0,0,Graphics.LEFT|Graphics.TOP);
              }


          }


        得到offImage得Graphics實例后,進行paint()得操作。這個部分通常比較復(fù)雜,我這里的不夠復(fù)雜:)
        然后把offImage直接copy到屏幕上也就是執(zhí)行saved.drawImage(offImage,0,0,Graphics.LEFT|Graphics.TOP);


        我寫了一個應(yīng)用程序來比較使用和不使用雙緩沖的效果,但是由于我的手機支持雙緩沖所以看不出效果,如果你有興趣,那么可以把paint()部分的代碼修改的復(fù)雜一些然后再移植到不支持的手機上也許可以看出效果,下面是我程序的代碼:

      import javax.microedition.midlet.MIDlet;
      import javax.microedition.midlet.MIDletStateChangeException;



      public class DoubleBufferMIDlet extends MIDlet
      {
          private UIController uicontroller;
         
          protected void startApp() throws MIDletStateChangeException
          {
              uicontroller = new UIController(this);
              uicontroller.init();


          }


            protected void pauseApp()
          {
           


          }


         
          protected void destroyApp(boolean arg0) throws MIDletStateChangeException
          {
              }


      }


      import javax.microedition.lcdui.Command;
      import javax.microedition.lcdui.CommandListener;
      import javax.microedition.lcdui.Displayable;
      import javax.microedition.lcdui.List;



      public class MainListUI extends List implements CommandListener
      {
          private UIController uicontroller;
         
         
          public MainListUI(UIController uicontroller)
          {
              super("Test",List.IMPLICIT);
              this.uicontroller = uicontroller;
              this.append("Non-buffer",null);
              this.append("Double-buffer",null);
              this.setCommandListener(this);
          }
         
          public void commandAction(Command arg0, Displayable arg1)
          {

              if(arg0 == List.SELECT_COMMAND)
              {
                  if(this.getSelectedIndex() == 0)
                  {
                     
                      uicontroller.handleEvent(UIController.EventID.DISPLAY_NON_BUFFER);
                  }
                  else
                  {
                     
                      uicontroller.handleEvent(UIController.EventID.DISPLAY_BUFFER);
                  }
              }
             


          }


      }


      import javax.microedition.lcdui.Command;
      import javax.microedition.lcdui.CommandListener;
      import javax.microedition.lcdui.Display;
      import javax.microedition.lcdui.Displayable;



      public class UIController implements CommandListener
      {


          private Display display;
          private DoubleBufferMIDlet midlet;
          private MainListUI mainList;
          private NonDoubleCanvas noDoubleCanvas;
          private DoubleCanvas doubleCanvas;
          public static final Command backCommand = new Command("Back",Command.BACK,2);
         
          public static class EventID
          {
              public static final int DISPLAY_NON_BUFFER = 0;
              public static final int DISPLAY_BUFFER = 1;
          }
          
        
          public UIController(DoubleBufferMIDlet midlet)
          {
              this.midlet = midlet;
          }
         
          public void init()
          {
              display = Display.getDisplay(midlet);
              mainList = new MainListUI(this);
              noDoubleCanvas = new NonDoubleCanvas(this);
              doubleCanvas = new DoubleCanvas(this);
              addCommand();
              display.setCurrent(mainList);
          }
         
          public void addCommand()
          {
              noDoubleCanvas.addCommand(backCommand);
              doubleCanvas.addCommand(backCommand);
          }
         
          public Display getDisplay()
          {
              return display;
          }
         
          public void setCurrent(Displayable disp)
          {
              display.setCurrent(disp);
          }
         
          public void handleEvent(int eventID)
          {
              switch(eventID)
              {
                  case EventID.DISPLAY_BUFFER:
                  {
                      setCurrent(doubleCanvas);
                      System.out.println(EventID.DISPLAY_BUFFER);
                      break;
                  }
                  case EventID.DISPLAY_NON_BUFFER:
                  {
                      setCurrent(noDoubleCanvas);
                      System.out.println(EventID.DISPLAY_NON_BUFFER);
                      break;
                  }
              }
          }
          public void commandAction(Command arg0, Displayable arg1)
          {
             
              if(arg0 == backCommand)
              {
                  display.setCurrent(mainList);
              }


          }



      }


      import javax.microedition.lcdui.Canvas;
      import javax.microedition.lcdui.Command;
      import javax.microedition.lcdui.CommandListener;
      import javax.microedition.lcdui.Displayable;
      import javax.microedition.lcdui.Graphics;



      public class NonDoubleCanvas extends Canvas implements CommandListener
      {
          
          private UIController uicontroller;
          private int width;
          private int height;
        
          public NonDoubleCanvas(UIController uicontroller)
          {
              super();
              this.uicontroller = uicontroller;
              width = this.getWidth();
              height = this.getHeight();
              this.setCommandListener(this);
          }


        
          protected void paint(Graphics arg0)
          {
             
              arg0.setColor(100,100,100);
              arg0.drawString(isDoubleBuffered()+"",width/2,height/2,Graphics.HCENTER|Graphics.TOP);
              for(int i = 2,j=2;i<width/2-6&&j<height/2-6;i=i+2,j=j+2)
              {
                  arg0.drawRect(i,j,width-2*i,height-2*j);
              }


          }



          public void commandAction(Command arg0, Displayable arg1)
          {
              
              uicontroller.commandAction(arg0,arg1);
          }


      }


      import javax.microedition.lcdui.Canvas;
      import javax.microedition.lcdui.Command;
      import javax.microedition.lcdui.CommandListener;
      import javax.microedition.lcdui.Displayable;
      import javax.microedition.lcdui.Graphics;
      import javax.microedition.lcdui.Image;



      public class DoubleCanvas extends Canvas implements CommandListener
      {


          
          private UIController uicontroller;
          private Image offImage;
          private int width;
          private int height;
          
          public DoubleCanvas(UIController uicontroller)
          {
              super();
              this.uicontroller = uicontroller;
              width = this.getWidth();
              height = this.getHeight();
              this.setCommandListener(this);
              if(!isDoubleBuffered())
              {
                  offImage = Image.createImage(width,height);
              }
                  
             
          }


        
          protected void paint(Graphics arg0)
          {
              
              arg0.drawString(isDoubleBuffered()+"",width/2,height/2,Graphics.HCENTER|Graphics.TOP);
              Graphics saved = arg0;
              if(offImage != null)
              {
                  arg0 = offImage.getGraphics();
              }
              arg0.setColor(255,128,128);
              for(int i = 2,j=2;i<width/2-6&&j<height/2-6;i=i+2,j=j+2)
              {
                  arg0.drawRect(i,j,width-2*i,height-2*j);
              }
              if(arg0 != saved)
              {
                  saved.drawImage(offImage,0,0,Graphics.LEFT|Graphics.TOP);
              }


          }



          public void commandAction(Command arg0, Displayable arg1)
          {
               uicontroller.commandAction(arg0,arg1);
          }


      }

      免費預(yù)約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 婷婷六月综合缴 | 中文字幕制服丝袜日韩专区 | 久久精品无限国产资源好片 | 日本精品视频区 | 亚洲天天在线日亚洲洲精 | 午夜福利亚洲精品 |