1

我有一个带有背景图像的外壳。在这个外壳中,我有一个滚动合成。此滚动合成继承了外壳的背景图像。

我想在滚动合成的继承背景图像上执行某种 alpha 混合/渐变。

我按照这里的代码。

  1. Rectangle rect = sc.getClientArea();// 这个矩形总是返回宽度和高度为 0。
  2. Image newImage = new Image(sc.getDisplay(), Math.max(1, rect.width), rect.height);// 似乎没有抓取背景图像,即使我硬编码了宽度和高度。

这里有一些代码:

sc = new ScrolledComposite(parent, SWT.BORDER_SOLID | SWT.V_SCROLL);
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);

sc.setAlwaysShowScrollBars(true);
sc.setMinWidth(0);

GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
sc.setLayoutData(gd);
sc.setLayout(new GridLayout(1, false));

Rectangle rect = sc.getClientArea();
Image newImage = new Image(sc.getDisplay(), sc.getParent().getBackgroundImage(), SWT.IMAGE_COPY);
GC gc = new GC(newImage);

// need to do clipping on the image so that only the background underlying the scrolled composite gets the gradient

// fill background 
gc.setForeground(new Color(sc.getDisplay(), 100,200,123)); 
gc.setBackground(new Color(sc.getDisplay(), 23,23,23)); 
gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);  
gc.dispose();

sc.setBackgroundImage(newImage);
sc.setBackgroundMode(SWT.INHERIT_DEFAULT);


innerComposite = new Composite(sc, SWT.NONE);

GridLayout gl = new GridLayout();
gl.numColumns = 1;
innerComposite.setLayout(gl);
gd = new GridData(GridData.FILL_BOTH);
gd.grabExcessVerticalSpace = true;
innerComposite.setLayoutData(gd);

/**
* Creates other widgets here!
*/
sc.setContent(innerComposite);
sc.layout();
4

2 回答 2

1

我可以在这里看到的一个合乎逻辑的问题是你做所有渐变的东西太早了。即使你做了这样sc = new ScrolledComposite(parent, SWT.BORDER_SOLID | SWT.V_SCROLL);的事情,这并不意味着 shell 已创建并准备好或窗口/复合本身。一个非常方便的句柄是挂钩SWT.Resize事件。

无论如何检查以下代码:

输出

在此处输入图像描述

代码 !!

注意您必须提供image.png

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class ImageGradientTest {

    private Image imageGradient;
    private Image image;

    private void createComponents(Shell parent) 
    {
        ScrolledComposite sc = new ScrolledComposite(parent, SWT.BORDER_SOLID | SWT.V_SCROLL);
        sc.setExpandHorizontal(true);
        sc.setExpandVertical(true);

        sc.setAlwaysShowScrollBars(true);
        sc.setMinWidth(0);

        GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);
        sc.setLayoutData(gd);
        sc.setLayout(new GridLayout(1, false));


        final Composite composite = new Composite(sc, SWT.NONE);
        composite.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event e) {
                changeImage(composite);
            }
        });
        composite.setLayout(new FormLayout());
        composite.setBackgroundMode(SWT.INHERIT_DEFAULT);

        Label label = new Label(composite, SWT.None);
        label.setText("Hello, World!");

        sc.setContent(composite);
        sc.layout();

    }

    private void changeImage(Composite composite) 
    {
        Image oldImage = imageGradient;

        Display display = composite.getDisplay();
        Rectangle rect = composite.getClientArea();
        imageGradient = new Image(display, image, SWT.IMAGE_COPY);


        GC gc = new GC(imageGradient);
        Color color1 = new Color(display, 200, 200, 255);
        Color color2 = new Color(display, 255, 255, 255);

        gc.setAlpha(245);           // Two have a layer effect you should set the alpha
        gc.setForeground(color1);
        gc.setBackground(color2);
        gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);

        color2.dispose();
        color1.dispose();
        gc.dispose();


        composite.setBackgroundImage(imageGradient);

        if (oldImage != null) {
            oldImage.dispose();
        }
    }

    private void openShell() 
    {
        Display display = new Display();

        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());

        image = new Image(display, "image.png");

        shell.setBackgroundImage(image);
        shell.setBackgroundMode(SWT.INHERIT_DEFAULT);

        createComponents(shell);

        shell.open();

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

        image.dispose();
        imageGradient.dispose();        
        display.dispose();
    }

    public static void main(String[] args) {
        ImageGradientTest sweet = new ImageGradientTest();
        sweet.openShell();
    }
}

捕获客户区域图像的代码!

Display display = composite.getDisplay();
Rectangle rect = composite.getClientArea();
Image i = new Image(display, composite.getClientArea().width, composite.getClientArea().height);
GC gc = new GC(i);

composite.print(gc);            // This is important

ImageLoader loader = new ImageLoader();
loader.data = new ImageData[]{i.getImageData()};
loader.save("hello.png", SWT.IMAGE_PNG);

gc.dispose();
i.dispose();

尽管 检查此链接,因为该方法不是跨平台的。

于 2012-08-30T10:49:24.440 回答
0

您可以使用Control.getBackgroundImage()获取背景图像。只需遍历小部件层次结构,直到您使用某些逻辑找到并成像 while (myControl.getParent().getBackgroundImage == null)

于 2012-08-29T15:09:49.910 回答