`

(转)ImageViewer控件

SWT 
阅读更多

来源:http://www.blogjava.net/xilaile/archive/2007/04/10/109547.html

因为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(0, 0);
    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(0, 0, 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, 0, 0, 0, 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, 0, 0, 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], 0, 0);
                break;
            case SWT.DM_FILL_PREVIOUS:
                // Start from second last image.
                gc.drawImage(images[i - 2], 0, 0);
                break;
            default:
                // DM_FILL_BACKGROUND or anything else,
                // just fill with default background.
                gc.setBackground(bg);
                gc.fillRectangle(0, 0, width, height);
                break;
            }

            // Draw the current image and clean up.
            Image img = new Image(display, id);
            gc.drawImage(img, 0, 0, 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();
    }
}
 
分享到:
评论

相关推荐

    ImageViewer ActiveX控件

    ImageViewer ActiveX控件 是一个ActiveX 控件,您可以利用它在您开发的程序中集成图片浏览功能,支持大部分常见的图片格式,可用于Microsoft Visual Studio,Microsoft Office 和 Borland Delphi。 &lt;br&gt; ...

    Image Viewer CP ActiveX控件

    Image Viewer CP ActiveX控件 是一个很小的图像阅览插件,它支持常用图像文件格式,包括BMP、 GIF、JPEG、PNG、ICO和TIFF。 &lt;br&gt; Image Viewer CP ActiveX控件产品特色: 可以调整图像大小并可以导出JPEG、...

    matlab开发-IMAGEVIEWER

    在MATLAB环境中,开发图像查看器(IMAGEVIEWER)是一项常见的任务,特别是在处理大量图像数据时。本项目提供了一个GUI(图形用户界面)工具,使用户能够方便地查看和交互浏览图像文件。以下是对这个MATLAB开发的...

    Qt4 Mini ImageViewer

    【Qt4 Mini ImageViewer】是一个轻量级的图像查看器应用程序,完全利用Qt4库进行开发。Qt4是一个跨平台的C++图形用户界面应用程序框架,由Qt公司提供,广泛应用于开发桌面应用、移动应用以及嵌入式系统。它支持...

    swift-ImageViewer一个Swift编写的图片查看器

    Swift-ImageViewer是一个使用Swift编程语言开发的图片查看器应用,专为iOS和macOS平台设计。这个项目由Krisiacik开发,并在特定版本(9afa043)中提供。作为一个专业的IT专家,我将详细介绍这个项目涉及的关键知识点...

    ImageViewer

    【ImageViewer】是一款基于WPF技术的图片浏览应用,它为用户提供了独特的3D视觉体验。在这款软件中,图片的切换不仅限于传统的平移和缩放,更引入了流畅的滑动效果,使图片浏览变得生动有趣。通过3D场景的构建,...

    自己写的android图片浏览器,ImageViewer

    这通常涉及到使用`GridView`或`Gallery`等布局控件来展示图片缩略图,并在点击时切换到全屏的ImageViewer来显示选中的图片。 1. **从SD卡读取图片**:Android提供了`Environment.getExternalStorageDirectory()`...

    Image Viewer .NET:另一个用C#编写的Image Viewer。-开源

    Image Viewer .NET旨在替代Windows 7内置图片查看器,因为该程序会自动更改图片而无需询问用户。 相反,Image Viewer .NET不执行任何类型的更改。 此外,Image Viewer .NET提供了应用其他与图片相关的信息的功能,并...

    Flex 自定义组件ImageViewer

    如果你的组件有子元素,比如ImageViewer可能包含一个Image控件,那么在这里创建它们。 3. **commitProperties()**: 在属性更改后,Flex会调用此方法来更新组件的状态。如果你的组件有一些依赖于其他属性的属性,...

    基于CocoStudio 1.4 的ImageViewer源代码

    ImageViewer是一个用于展示图片的控件,常见的应用场景包括游戏中的角色选择界面、背景图片显示等。在ImageViewer的源代码中,我们可以看到如何与Cocos2dx的图形系统进行交互,使用Texture2D对象加载图片资源,并...

    ImageViewerforWindows7-64位

    《ImageViewer for Windows 7 - 64位:专业动态图片查看器详解》 在数字化时代,图片是我们记录生活、交流思想的重要载体。而在众多图片格式中,动态图片以其生动活泼的特点深受用户喜爱。本文将深入探讨“Image...

    ImageViewer_实现简单的拖放_

    然后,可以遍历这些文件,加载它们到ImageViewer或其他适当的控件,如PictureBox。 `AssemblyInfo.cs`文件通常包含项目的元数据,如版本信息、版权信息以及对其他程序集的引用。在本项目中,它可能包含了关于Image...

    ImageViewer:控制显示图像

    在iOS应用开发中,`UIImageView`是用于展示静态图像的标准控件,但有时我们需要更高级的功能,例如缩放、平移等,这时就需要一个专门的`ImageViewer`。本篇文章将详细探讨如何创建一个具备这些功能的图像浏览器,...

    sprview_cs_sprview_spr_imageviewer_

    【标题】"sprview_cs_sprview_spr_imageviewer_" 指的是一款基于C#(.NET框架)编写的SPR(Sprite)查看器源代码。SPR Viewer主要是用于查看和处理游戏或图形设计中使用的精灵图(Sprite)资源。这种工具在游戏开发...

    matlab开发-IMAGEVIEWER.zip

    这个名为"IMAGEVIEWER"的项目可能包含了一系列用于显示、操作和交互式探索图像的MATLAB代码。以下是对MATLAB图像查看器开发的详细解释和相关知识点: 1. **MATLAB图像基础**: - MATLAB提供了强大的图像处理功能,...

    image-viewer1.2.tar.gz_gtk image_show

    4. 缩放功能:Image Viewer 1.2允许用户通过鼠标滚轮或专门的缩放控件调整图片大小,以适应不同的查看需求。无论是细节查看还是整体把握,都能轻松实现。 5. 用户界面:遵循Gtk的设计原则,Image Viewer 1.2拥有...

    ImageViewer:图像查看器(WPF)

    图像浏览器 图像查看器(WPF)。 语言C#和WPF。 平台.Net 4.5 职能: 查看文件夹中的图像 带有动画的幻灯片放映 皮肤 资料夹导览 全屏观看 [项目]-MS Visual Studio 2012项目 [src]-仅资源和资源

    image-viewer1.3.tar.gz_show

    《Image Viewer 1.3:基于Gtk的图片查看器示例应用详解》 Image Viewer 1.3,这个名为“image-viewer1.3.tar.gz_show”的压缩包,揭示了一个专为展示图片而设计的Gtk样本应用程序。在本文中,我们将深入探讨这款...

    image-viewer1.1.tar.gz_show

    《Image Viewer 1.1:基于Gtk的图片查看器示例应用详解》 在软件开发领域,图形用户界面(GUI)的应用程序为用户提供直观、友好的交互方式。其中,图片查看器是常见的GUI组件,用于浏览和管理图像文件。本文将深入...

    ImageViewer:图片浏览器,支持图片手势缩放、拖拽等操作,`自定义View`的模式显示,自定义图片加载方式,更加灵活,易于扩展,同时也适用于RecyclerView、ListView的横向和纵向列表模式,最低支持版本为Android 3.0及以上..

    ImageViewer关于图片浏览器,支持图片手势缩放、拖拽等操作,自定义View的模式显示,自定义图片加载方式,可自定义索引UI、ProgressView,更加灵活,易于扩展,同时也适用于RecyclerView、ListView的横向和纵向列表...

Global site tag (gtag.js) - Google Analytics