抓取SWT组件的继承背景图像(滚动复合)

时间:2012-08-29 02:24:33

标签: java eclipse swt

我有一个有背景图片的shell。 在这个shell中,我有一个滚动的复合。这个滚动的复合继承了shell的背景图像。

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

我遵循here的代码。

  1. Rectangle rect = sc.getClientArea(); //此rect总是将宽度和高度返回为0。
  2. Image newImage = new Image(sc.getDisplay(), Math.max(1, rect.width), rect.height); //似乎没有抓住背景图片,即使我硬编码了宽度和高度。
  3. 这里的一些代码:

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

2 个答案:

答案 0 :(得分:1)

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

无论如何检查以下代码:

输出

enter image description here

代码!!

注意您必须提供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();

虽然 check this link因为这种方法不是跨平台的。

答案 1 :(得分:0)

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