WindowBuilder入门:使用swt的canvas类构造显示URL图像

时间:2022-06-22
本文章向大家介绍WindowBuilder入门:使用swt的canvas类构造显示URL图像,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/53377864

首先如创建一个基于于Canvas的ImageCanvas类,ImageCanvas.java

package net.gdface.ui;

import java.net.URL;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.wb.swt.SWTResourceManager;

public class ImageCanvas extends Canvas {
    // 显示的图像
    private Image image;
    // 图像缩放比例
    private float zoom=1f;
    /**
     * @param parent
     * @param style
     * @param image 显示的图像,为null时不显示
     */
    public ImageCanvas(Composite parent, int style, Image image) {
        super(parent, style);
        this.image = image;

        addPaintListener(new PaintListener() {
            @Override
            public void paintControl(PaintEvent e) {
                // 调用重绘方法
                paintImage(e.gc);
            }
        });
    }
    /**
     * @wbp.parser.constructor
     */
    public ImageCanvas (Composite parent, int style, URL url){      
        this(parent,style,SWTResourceManager.getImage( url));
    }


    /**
     * 重绘图像,窗口区域变化时都重新计算适合的显示位置,以保证图像居中完整显示
     * @param gc
     */
    protected void paintImage(GC gc) {
        if(null==image)return;
        zoom=fitZoom();
        Rectangle rect=getPaintRect();
        gc.drawImage(image, 0, 0, image.getBounds().width, image
                .getBounds().height, rect.x, rect.y, rect.width,
                rect.height);
    }
    /**
     * 返回适合当前窗口尺寸完整显示图像的缩放比例,图像长宽都小于显示窗口时,则返回1
     * @return 
     */
    private float fitZoom(){
        Point size = getSize();
        Rectangle imgSize= image.getBounds();
        if(imgSize.width<size.x&&imgSize.height<size.y)return 1f;
        if(imgSize.width*size.y<imgSize.height*size.x){
            return (float)size.y/imgSize.height;
        }
        return (float)size.x/imgSize.width;
    }

    /**
     * 根据图像缩放比例返回图像在gc中的显示区域(居中显示)
     * @return
     */
    private Rectangle getPaintRect(){
        Point size = getSize();
        Rectangle imgSize= image.getBounds();
        if(zoom>0){
            imgSize.width*=zoom;
            imgSize.height*=zoom;
        }
        imgSize.x=(size.x-imgSize.width)/2;
        imgSize.y=(size.y-imgSize.height)/2;
        return imgSize;
    }
    @Override
    public void dispose() {
        super.dispose();
        image.dispose();
    }
}

然后如下图用WindowBuilder创建一个TestDialog类

然后在生成的TestDialog类的createContents中将ImageCanvas对象加入对话框 TestDialog.java

package testwb;

import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.swt.SWT;
import org.eclipse.wb.swt.SWTResourceManager;

import net.gdface.ui.ImageCanvas;

import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.PaintEvent;

public class TestDialog extends Dialog {

    protected Object result;
    protected Shell shell;
    private ImageCanvas canvas;

    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public TestDialog(Shell parent, int style) {
        super(parent, style);
    }

    /**
     * Open the dialog.
     * @return the result
     */
    public Object open() {
        createContents();
        shell.open();
        shell.layout();
        Display display = getParent().getDisplay();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        return result;
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents() {
        shell = new Shell(getParent(), SWT.NONE);
        shell.setSize(450, 300);
        shell.setText(getText());
        // 将mageCanvas对象加入Dialog
        try {
            canvas = new ImageCanvas(shell, SWT.NONE,SWTResourceManager.getImage(new URL("http://d.hiphotos.baidu.com/image/pic/item/562c11dfa9ec8a13f075f10cf303918fa1ecc0eb.jpg")));
            canvas.setBounds(23, 21, 254, 241);
        } catch (MalformedURLException e1) {
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        }
        //


    }
}

然后在org.eclipse.wb.swt.SWTResourceManager.java中增加支持URL的getImage方法

    public static Image getImage(URL url) {
        Image image = m_imageMap.get(url.toString());
        if (image == null) {
            try {
                image = getImage(url.openStream());
                m_imageMap.put(url.toString(), image);
            } catch (Exception e) {
                image = getMissingImage();
                m_imageMap.put(url.toString(), image);
            }
        }
        return image;
    }

现在,在WindowBuilder的design设计视图中就能看到效果了

JUnit测试代码 TestCanvas.java

package iadbui;

import org.eclipse.swt.widgets.Shell;
import org.junit.Test;

import testwb.AnnDialog;

public class TestCanvas {

    @Test
    public void test() {
        new AnnDialog(new Shell(),0).open();
    }

}