gr8vyguy@Blogjava

          SWT圖片顯示,支持JPEG,GIF(動畫),BMP,ICO,PNG和TIFF

          因為SWT的ImageLoader支持讀寫以上所有格式的圖片,所以實現起來比較簡單。主要解決了兩個問題。第一個問題是播放GIF動畫,通過ImageLoader讀入GIF的所有幀以及間隔時間,然后用Display.timerExec實現Timer播放。第二個問題是對圖片的Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 雖然加上了滾動條,但是不起作用,需要監聽滾動條的SWT.Selection事件。另外,加上滾動條后,pack無法得到大小,不能正確的pack。需要重載computeSize。

          /**
           * 負責顯示各種格式的圖片
           * 
           * 
          @author 喜來樂哈哈
           
          */
          public class ImageViewer extends Canvas {

              
          protected Point origin = new Point(00);
              
          protected Image image;
              
          protected ImageData[] imageDatas;
              
          protected Image[] images;
              
          protected int current;

              
          private int repeatCount;
              
          private Runnable animationTimer;
              
          private ScrollBar hBar;
              
          private ScrollBar vBar;
              
          private Color bg;
              
          private Display display;

              
          public ImageViewer(Composite parent) {
                  
          super(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL
                          
          | SWT.H_SCROLL);

                  hBar 
          = getHorizontalBar();
                  vBar 
          = getVerticalBar();
                  bg 
          = getBackground();
                  display 
          = getDisplay();
                  addListeners();
              }

              
          public void setImage(ImageData imageData) {
                  checkWidget();

                  stopAnimationTimer();
                  
          this.image = new Image(display, imageData);
                  
          this.imageDatas = null;
                  
          this.images = null;
                  redraw();
              }

              
          /**
               * 
          @param repeatCount 0 forever
               
          */
              
          public void setImages(ImageData[] imageDatas, int repeatCount) {
                  checkWidget();

                  
          this.image = null;
                  
          this.imageDatas = imageDatas;
                  
          this.repeatCount = repeatCount;
                  convertImageDatasToImages();
                  startAnimationTimer();
                  redraw();
              }

              @Override
              
          public Point computeSize(int wHint, int hHint, boolean changed) {
                  checkWidget();

                  Image image 
          = getCurrentImage();
                  
          if (image != null) {
                      Rectangle rect 
          = image.getBounds();
                      Rectangle trim 
          = computeTrim(00, rect.width, rect.height);
                      
          return new Point(trim.width, trim.height);
                  }

                  
          return new Point(wHint, hHint);
              }

              @Override
              
          public void dispose() {
                  
          if (image != null)
                      image.dispose();

                  
          if (images != null)
                      
          for (int i = 0; i < images.length; i++)
                          images[i].dispose();

                  
          super.dispose();
              }

              
          protected void paint(Event e) {
                  Image image 
          = getCurrentImage();
                  
          if (image == null)
                      
          return;

                  GC gc 
          = e.gc;
                  gc.drawImage(image, origin.x, origin.y);

                  gc.setBackground(bg);
                  Rectangle rect 
          = image.getBounds();
                  Rectangle client 
          = getClientArea();
                  
          int marginWidth = client.width - rect.width;
                  
          if (marginWidth > 0) {
                      gc.fillRectangle(rect.width, 
          0, marginWidth, client.height);
                  }
                  
          int marginHeight = client.height - rect.height;
                  
          if (marginHeight > 0) {
                      gc.fillRectangle(
          0, rect.height, client.width, marginHeight);
                  }
              }

              
          void addListeners() {
                  hBar.addListener(SWT.Selection, 
          new Listener() {
                      
          public void handleEvent(Event arg0) {
                          hscroll();
                      }
                  });
                  vBar.addListener(SWT.Selection, 
          new Listener() {
                      
          public void handleEvent(Event arg0) {
                          vscroll();
                      }
                  });
                  addListener(SWT.Resize, 
          new Listener() {
                      
          public void handleEvent(Event e) {
                          resize();
                      }
                  });
                  addListener(SWT.Paint, 
          new Listener() {
                      
          public void handleEvent(Event e) {
                          paint(e);
                      }
                  });
              }

              
          void hscroll() {
                  Image image 
          = getCurrentImage();
                  
          if (image != null) {
                      
          int hSelection = hBar.getSelection();
                      
          int destX = -hSelection - origin.x;
                      Rectangle rect 
          = image.getBounds();
                      scroll(destX, 
          000, rect.width, rect.height, false);
                      origin.x 
          = -hSelection;
                  }
              }

              
          void vscroll() {
                  Image image 
          = getCurrentImage();
                  
          if (image != null) {
                      
          int vSelection = vBar.getSelection();
                      
          int destY = -vSelection - origin.y;
                      Rectangle rect 
          = image.getBounds();
                      scroll(
          0, destY, 00, rect.width, rect.height, false);
                      origin.y 
          = -vSelection;
                  }
              }

              
          void resize() {
                  Image image 
          = getCurrentImage();
                  
          if (image == null)
                      
          return;

                  Rectangle rect 
          = image.getBounds();
                  Rectangle client 
          = getClientArea();
                  hBar.setMaximum(rect.width);
                  vBar.setMaximum(rect.height);
                  hBar.setThumb(Math.min(rect.width, client.width));
                  vBar.setThumb(Math.min(rect.height, client.height));
                  
          int hPage = rect.width - client.width;
                  
          int vPage = rect.height - client.height;
                  
          int hSelection = hBar.getSelection();
                  
          int vSelection = vBar.getSelection();
                  
          if (hSelection >= hPage) {
                      
          if (hPage <= 0)
                          hSelection 
          = 0;
                      origin.x 
          = -hSelection;
                  }
                  
          if (vSelection >= vPage) {
                      
          if (vPage <= 0)
                          vSelection 
          = 0;
                      origin.y 
          = -vSelection;
                  }
                  redraw();
              }

              
          void convertImageDatasToImages() {
                  images 
          = new Image[imageDatas.length];

                  
          // Step 1: Determine the size of the resulting images.
                  int width = imageDatas[0].width;
                  
          int height = imageDatas[0].height;

                  
          // Step 2: Construct each image.
                  int transition = SWT.DM_FILL_BACKGROUND;
                  
          for (int i = 0; i < imageDatas.length; i++) {
                      ImageData id 
          = imageDatas[i];
                      images[i] 
          = new Image(display, width, height);
                      GC gc 
          = new GC(images[i]);

                      
          // Do the transition from the previous image.
                      switch (transition) {
                      
          case SWT.DM_FILL_NONE:
                      
          case SWT.DM_UNSPECIFIED:
                          
          // Start from last image.
                          gc.drawImage(images[i - 1], 00);
                          
          break;
                      
          case SWT.DM_FILL_PREVIOUS:
                          
          // Start from second last image.
                          gc.drawImage(images[i - 2], 00);
                          
          break;
                      
          default:
                          
          // DM_FILL_BACKGROUND or anything else,
                          
          // just fill with default background.
                          gc.setBackground(bg);
                          gc.fillRectangle(
          00, width, height);
                          
          break;
                      }

                      
          // Draw the current image and clean up.
                      Image img = new Image(display, id);
                      gc.drawImage(img, 
          00, id.width, id.height, id.x, id.y, id.width,
                              id.height);
                      img.dispose();
                      gc.dispose();

                      
          // Compute the next transition.
                      
          // Special case: Can't do DM_FILL_PREVIOUS on the
                      
          // second image since there is no "second last"
                      
          // image to use.
                      transition = id.disposalMethod;
                      
          if (i == 0 && transition == SWT.DM_FILL_PREVIOUS)
                          transition 
          = SWT.DM_FILL_NONE;
                  }
              }

              Image getCurrentImage() {
                  
          if (image != null)
                      
          return image;

                  
          if (images == null)
                      
          return null;

                  
          return images[current];
              }

              
          void startAnimationTimer() {
                  
          if (images == null || images.length < 2)
                      
          return;

                  
          final int delay = imageDatas[current].delayTime * 10;
                  display.timerExec(delay, animationTimer 
          = new Runnable() {
                      
          public void run() {
                          
          if (isDisposed())
                              
          return;

                          current 
          = (current + 1% images.length;
                          redraw();

                          
          if (current + 1 == images.length && repeatCount != 0
                                  
          && --repeatCount <= 0)
                              
          return;
                          display.timerExec(delay, 
          this);
                      }
                  });
              }

              
          void stopAnimationTimer() {
                  
          if (animationTimer != null)
                      display.timerExec(
          -1, animationTimer);
              }
          }

          測試程序
          public class ImageCanvasTest {
              
          public static void main(String[] args) {
                  Display display 
          = new Display();
                  
          final Shell shell = new Shell(display);
                  ImageViewer ic 
          = new ImageViewer(shell);

                  shell.setLayout(
          new FillLayout());
                  FileDialog dialog 
          = new FileDialog(shell, SWT.OPEN);
                  dialog.setText(
          "Open an image file or cancel");
                  String string 
          = dialog.open();

                  ImageLoader loader 
          = new ImageLoader();
                  ImageData[] imageDatas 
          = loader.load(string);
                  
          if (imageDatas.length == 0)
                      
          return;
                  
          else if (imageDatas.length == 1) {
                      ic.setImage(imageDatas[
          0]);
                  } 
          else {
                      ic.setImages(imageDatas, loader.repeatCount);
                  }

                  ic.pack();
                  shell.pack();
                  shell.open();
                  
          while (!shell.isDisposed()) {
                      
          if (!display.readAndDispatch())
                          display.sleep();
                  }
                  display.dispose();
              }
          }

          在對GIF圖片的支持上,Swing要做的好很多,一句label.setIcon(new ImageIcon(name))就搞定GIF動畫了。

          轉載請保留http://www.aygfsteel.com/xilaile/archive/2007/04/10/109547.html

          posted on 2007-04-10 00:33 gr8vyguy 閱讀(9330) 評論(3)  編輯  收藏 所屬分類: Java

          評論

          # re: SWT圖片顯示,支持JPEG,GIF(動畫),BMP,ICO,PNG和TIFF 2007-04-10 03:08 BeanSoft

          友情贊助一下, 我用的是http://www.eclipse.org/articles/Article-Image-Viewer/Image_viewer.html 的一個叫 Chengdong Li (cdli@ccs.uky.edu) 的華裔寫的. 不過沒試對動畫GIF的支持如何.  回復  更多評論   

          # re: SWT圖片顯示,支持JPEG,GIF(動畫),BMP,ICO,PNG和TIFF 2007-04-28 13:06 Pande

          謝了,我看了,它的那個對GIF不支持,不過它用了ScrollableComposite倒是個好主意  回復  更多評論   

          # re: SWT圖片顯示,支持JPEG,GIF(動畫),BMP,ICO,PNG和TIFF 2010-01-14 05:49 yangerran

          這個寫的非常好,我試了,不錯  回復  更多評論   

          <2007年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          公告

        1. 轉載請注明出處.
        2. msn: gr8vyguy at live.com
        3. 常用鏈接

          留言簿(9)

          隨筆分類(68)

          隨筆檔案(80)

          文章分類(1)

          My Open Source Projects

          搜索

          積分與排名

          最新評論

          主站蜘蛛池模板: 合作市| 舟山市| 望江县| 克拉玛依市| 大兴区| 永康市| 瑞丽市| 镇安县| 龙胜| 左贡县| 应城市| 沂水县| 朝阳市| 定边县| 兴国县| 馆陶县| 浠水县| 康保县| 惠安县| 澄城县| 佳木斯市| 兰州市| 东海县| 沙坪坝区| 万全县| 富阳市| 安乡县| 灌阳县| 敦煌市| 北票市| 霍山县| 高邮市| 开原市| 健康| 绍兴市| 巴彦淖尔市| 班戈县| 赤壁市| 三河市| 曲松县| 威海市|