我正在编写一个应用程序,我们的设计师希望在我们的一些复合材料上使用渐变来表示某些背景。
我写了以下代码:
composite.addListener (SWT.Paint, new Listener () {
public void handleEvent (Event e) {
GC gc = e.gc;
Rectangle rect = composite.getClientArea ();
Color color1 = new Color (display, 0, 0, 0);
Color color2 = new Color (display, 255, 255, 255);
gc.setForeground(color1);
gc.setBackground(color2);
gc.fillGradientRectangle (rect.x, rect.y, rect.width, rect.height , true);
}
});
这会在复合材料上绘制渐变,但我们在复合材料上面有Label / CLabels,Canvases和Links。
在这些区域中,背景只是绘制空白画布时的纯灰色。
我试图强制标签继承背景:
label.setBackgroundMode(SWT.INHERIT_DEFAULT) //SWT.INHERIT_FORCE Doesn't work either
但是这给我留下了相同的默认灰色,并且在Composite顶部的组件后面没有渐变。
有关将渐变作为每个元素背景的建议吗?
我不反对将Gradient绘制到带有图像的gc上,然后将背景设置为该Image。然而,该方法根本没有工作,复合或其任何元素。
根据我的知识,我也不可能单独设置渐变。我们希望整个复合材料是一个均匀的流动梯度。
[edit]我上传了一个例子,直到twitpic here。
谢谢,
Brian Gianforcaro
答案 0 :(得分:10)
使用 composite.setBackgroundMode(SWT.INHERIT_DEFAULT),但不要直接绘制合成 - 使用 composite.setBackgroundImage(Image)将绘制图像并将其设置为背景图像。除非我错过了一个技巧,否则这意味着你只需要在调整复合材料时重新生成图像。
你应该能够切断这个代码,看看我的意思是什么:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
/**
* SWT composite with transparent label
*
* @author McDowell
*/
public class Sweet {
private Image imageGradient;
private Label label;
private Composite composite;
private void createComponents(Shell parent) {
composite = new Composite(parent, SWT.NONE);
composite.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event e) {
changeImage();
}
});
composite.setLayout(new FormLayout());
composite.setBackgroundMode(SWT.INHERIT_DEFAULT);
label = new Label(composite, SWT.None);
label.setText("Hello, World!");
}
private void changeImage() {
Image oldImage = imageGradient;
Display display = composite.getDisplay();
Rectangle rect = composite.getClientArea();
imageGradient = new Image(display, rect.width, rect.height);
GC gc = new GC(imageGradient);
try {
Color color1 = new Color(display, 200, 200, 255);
try {
Color color2 = new Color(display, 255, 255, 255);
try {
gc.setForeground(color1);
gc.setBackground(color2);
gc.fillGradientRectangle(rect.x, rect.y, rect.width,
rect.height, true);
} finally {
color2.dispose();
}
} finally {
color1.dispose();
}
} finally {
gc.dispose();
}
composite.setBackgroundImage(imageGradient);
if (oldImage != null) {
oldImage.dispose();
}
}
private void openShell(Display display) {
Shell shell = new Shell(display);
try {
shell.setSize(200, 100);
shell.setLayout(new FillLayout());
createComponents(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} finally {
if (!shell.isDisposed()) {
shell.dispose();
}
}
}
public void run() {
Display display = Display.getDefault();
try {
openShell(display);
} finally {
display.dispose();
}
}
public void dispose() {
if (imageGradient != null) {
imageGradient.dispose();
}
}
public static void main(String[] args) {
Sweet sweet = new Sweet();
try {
sweet.run();
} finally {
sweet.dispose();
}
}
}
答案 1 :(得分:-1)
我要尝试的第一件事是capture an image from the widget并直接将子窗口小部件所在的图像部分绘制到子窗口小部件上。
如果这不起作用,请尝试对两个窗口小部件使用相同的绘图侦听器,但在将GC的变换设置为转换GC以将坐标转换为标签的坐标空间之前:
Listener listener = new Listener () {
public void handleEvent (Event e) {
GC gc = e.gc;
Rectangle rect = composite.getClientArea ();
Point offset = ((Control)e.widget).toControl(composite.toDisplay(0, 0));
Color color1 = new Color (display, 0, 0, 0);
Color color2 = new Color (display, 255, 255, 255);
gc.setForeground(color1);
gc.setBackground(color2);
gc.fillGradientRectangle (rect.x + offset.x, rect.y + offset.y,
rect.width, rect.height , true);
}
}
composite.addListener (SWT.Paint, listener);
label.addListener(SWT.Paint, listener);
另外,在完成之后,请小心处理您创建的任何Color实例。否则,您将泄漏系统资源并最终耗尽。