java swt 画按钮_java – SWT透明按钮/标签

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

在最终项目中,应用程序将显示动画对象,其中包含我计划使用图像的多个控件.

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

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

我构建了一个对象来处理图像标签.我称之为TransparentImageLabel.看起来像:

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();

}

}

我必须要亲近.定义为透明的图像区域被绘制为透明.但是我没有得到任何东西,只有白色加上而不是图像中的红色.

解决方法:

问题出在您的TransparentImageLabel#paintControl(..)方法中.将第二行最后一行更正为以下内容:

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

由于您是在画布的上下文中绘制的,因此您为位置指定的坐标应该相对于该画布.您当前正在使用相对于其父级返回的canvas的位置.

标签:java,swt

来源: https://codeday.me/bug/20190704/1371978.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值