4

我已经研究了几天。似乎大多数人都希望将按钮放置在透明的画布或外壳上。我需要在画布/组件上放置透明的可点击对象。在我的测试中,我发现如果我不尝试将对象放在画布上,它就永远不会显示。

在最终项目中,该应用程序将显示带有一些我计划使用图像的控件的动画对象。

在我试图解决的示例中,我采用了 Snipped195,它显示了一个转动的圆环。我试图在圆环上放置一个图像标签,这样当圆环转动时,它将通过透明的标签区域显示。我已经设置了一个红色加号并具有透明背景的 gif 文件。我还拿起了一些代码(现在不记得它来自哪里),它是paintControl 方法的一部分,用于查找透明像素并构建一个 Region 对象。区域对象显然正在做它需要做的事情来定义图像的去向。我是否需要以某种方式将该区域应用于图像而不是画布?

起初,当我尝试这样做时,确实显示了图像。但是在透明区域显示白色的地方。在实现paintControl 代码后,它至少正确处理了透明区域。现在我需要获取要显示的实际图像内容。

我构建了一个对象来处理图像标签。我称它为透明图像标签。看起来像:

public class TransparentImageLabel extends Canvas {

    private Image labelImage;

    public TransparentImageLabel(Composite parent, Image image, int style) {
        super(parent, style);
        this.labelImage = image;
        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                TransparentImageLabel.this.widgetDisposed(e);
            }
        });
        addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                TransparentImageLabel.this.paintControl(e);
            }
        });
    }

    private void widgetDisposed(DisposeEvent e) {

    }

    private void paintControl(PaintEvent event) {
        System.out.println("at paint control");
        ImageData imgData = this.labelImage.getImageData();
        Region region = new Region();
        if (imgData.alphaData != null) {
            Rectangle pixel = new Rectangle(0, 0, 1, 1);
            for (int y = 0; y < imgData.height; y++) {
                for (int x = 0; x < imgData.width; x++) {
                    if (imgData.getAlpha(x, y) == 255) {
                        pixel.x = imgData.x + x;
                        pixel.y = imgData.y + y;
                        region.add(pixel);
                    }
                }
            }
        } else {
            ImageData mask = imgData.getTransparencyMask();
            Rectangle pixel = new Rectangle(0, 0, 1, 1);
            for (int y = 0; y < mask.height; y++) {
                for (int x = 0; x < mask.width; x++) {
                    if (mask.getPixel(x, y) != 0) {
                        pixel.x = imgData.x + x;
                        pixel.y = imgData.y + y;
                        region.add(pixel);
                    }
                }
            }
        }
        this.setRegion(region);
        event.gc.drawImage(labelImage, this.getBounds().x, this.getBounds().y);
        region.dispose();
    }
}

将此添加到 Snipped195 后,代码如下所示:

public class Snippet195 {

    private Image redPlus;

    static void drawTorus(float r, float R, int nsides, int rings) {
        float ringDelta = 2.0f * (float) Math.PI / rings;
        float sideDelta = 2.0f * (float) Math.PI / nsides;
        float theta = 0.0f, cosTheta = 1.0f, sinTheta = 0.0f;
        for (int i = rings - 1; i >= 0; i--) {
            float theta1 = theta + ringDelta;
            float cosTheta1 = (float) Math.cos(theta1);
            float sinTheta1 = (float) Math.sin(theta1);
            GL11.glBegin(GL11.GL_QUAD_STRIP);
            float phi = 0.0f;
            for (int j = nsides; j >= 0; j--) {
                phi += sideDelta;
                float cosPhi = (float) Math.cos(phi);
                float sinPhi = (float) Math.sin(phi);
                float dist = R + r * cosPhi;
                GL11.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
                GL11.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
                GL11.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
                GL11.glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
            }
            GL11.glEnd();
            theta = theta1;
            cosTheta = cosTheta1;
            sinTheta = sinTheta1;
        }
    }

    private Snippet195() {
        final Display display = new Display();
        Shell shell = new Shell(display, SWT.NO_REDRAW_RESIZE);
        shell.setLayout(new FillLayout());
        Composite comp = new Composite(shell, SWT.NONE);
        comp.setLayout(new FillLayout());
        GLData data = new GLData();
        data.doubleBuffer = true;
        redPlus = new Image(shell.getDisplay(), new ImageData(
                Snippet237.class.getResourceAsStream("/red-plus.png")));
        final GLCanvas canvas = new GLCanvas(comp, SWT.NONE, data);

        canvas.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                e.gc.setAlpha(15);
                e.gc.drawImage(Snippet195.this.redPlus, 0, 0);
            }
        });

        canvas.setCurrent();
        try {
            GLContext.useContext(canvas);
        } catch (LWJGLException e) {
            e.printStackTrace();
        }

        canvas.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event event) {
                Rectangle bounds = canvas.getBounds();
                float fAspect = (float) bounds.width / (float) bounds.height;
                canvas.setCurrent();
                try {
                    GLContext.useContext(canvas);
                } catch (LWJGLException e) {
                    e.printStackTrace();
                }
                GL11.glViewport(0, 0, bounds.width, bounds.height);
                GL11.glMatrixMode(GL11.GL_PROJECTION);
                GL11.glLoadIdentity();
                GLU.gluPerspective(45.0f, fAspect, 0.5f, 400.0f);
                GL11.glMatrixMode(GL11.GL_MODELVIEW);
                GL11.glLoadIdentity();
            }
        });

        GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        GL11.glColor3f(1.0f, 0.0f, 0.0f);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
        GL11.glClearDepth(1.0);
        GL11.glLineWidth(2);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        TransparentImageLabel redPlusLabel = new TransparentImageLabel(canvas,
                redPlus, SWT.NONE);
        redPlusLabel.setSize(48, 48);
        redPlusLabel.setLocation(500, 200);
        shell.setText("SWT/LWJGL Example");
        shell.setSize(880, 720);
        shell.open();
        final Runnable run = new Runnable() {
            int rot = 0;

            public void run() {
                if (!canvas.isDisposed()) {
                    canvas.setCurrent();
                    try {
                        GLContext.useContext(canvas);
                    } catch (LWJGLException e) {
                        e.printStackTrace();
                    }
                    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT
                            | GL11.GL_DEPTH_BUFFER_BIT);
                    GL11.glClearColor(.3f, .5f, .8f, 1.0f);
                    GL11.glLoadIdentity();
                    GL11.glTranslatef(0.0f, 0.0f, -10.0f);
                    float frot = rot;
                    GL11.glRotatef(0.15f * rot, 2.0f * frot, 10.0f * frot, 1.0f);
                    GL11.glRotatef(0.3f * rot, 3.0f * frot, 1.0f * frot, 1.0f);
                    rot++;
                    GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
                    GL11.glColor3f(0.9f, 0.9f, 0.9f);
                    drawTorus(1, 1.9f + ((float) Math.sin((0.004f * frot))), 25, 75);
                    canvas.swapBuffers();
                    display.asyncExec(this);
                }
            }
        };
        canvas.addListener(SWT.Paint, new Listener() {
            public void handleEvent(Event event) {
                run.run();
            }
        });
        display.asyncExec(run);

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

    public static void main(String[] args) {
        new Snippet195();
    }
}

我必须靠近。定义为透明的图像区域被绘制为透明。但是除了图像中的红色而不是白色加号之外,我什么也没得到。

在此处输入图像描述

4

1 回答 1

2

The problem is in your TransparentImageLabel#paintControl(..) method. Correct the second last line to the following:

event.gc.drawImage(labelImage, 0, 0);

Since you are drawing within the context of the canvas so the coordinates you specify for location should be relative to that Canvas. You are currently using the location of canvas which is returned relative to it's parent.

于 2013-01-14T15:40:18.813 回答