8

我正在编写一个应用程序,我们的设计师希望在我们的一些复合材料中使用渐变来处理一些背景。

我写了以下代码:

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

        }
    });

这可以在复合材料上精细地绘制渐变,但我们在复合材料的顶部有标签/CLabel、画布和链接。

在这些区域中,背景只是绘制空画布时得到的纯灰色。

我试过强制标签继承背景,如下所示:

label.setBackgroundMode(SWT.INHERIT_DEFAULT) //SWT.INHERIT_FORCE Doesn't work either

但这给我留下了相同的默认灰色,并且在 Composite 顶部的组件后面没有渐变。

有什么建议让渐变成为每个元素的背景?

我不反对将渐变绘制到提供图像的 gc 上,然后将背景设置为该图像。但是,该方法根本不起作用,复合或其任何元素。

我也无法根据我的知识单独设置渐变。我们希望整个复合材料是一个均匀流动的梯度。

[编辑] 我在这里上传了一个例子到 twitpic 。

谢谢,

布赖恩·吉安福卡罗

4

2 回答 2

10

使用composite.setBackgroundMode(SWT.INHERIT_DEFAULT),但不要直接绘制复合材料 - 绘制图像并将其设置为使用composition.setBackgroundImage(Image)的背景图像。除非我错过了一个技巧,否则这意味着您只需在调整合成大小时重新生成图像。

您应该能够按原样剪切'n'粘贴此代码,以了解我的意思:

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

}
于 2008-09-26T10:51:27.320 回答
-1

我要尝试的第一件事是从小部件捕获图像并将子小部件所在的图像部分直接绘制到子小部件上。

如果这不起作用,请尝试对两个小部件使用相同的绘制侦听器,但在转换 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 实例,然后再使用它们。否则,您将泄漏系统资源并最终耗尽。

于 2008-09-25T22:44:13.557 回答