Question

J'écris une application et nos concepteurs souhaitent utiliser des dégradés pour certains arrière-plans de certains de nos composites.

J'ai écrit le code suivant:

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

        }
    });

Ceci dessine le dégradé de fin sur le composite, mais nous avons des étiquettes / étiquettes, des canevas et des liens au-dessus du composite.

Dans ces zones, l’arrière-plan n’est que le gris uni que vous obtenez lorsque vous dessinez une toile vide.

J'ai essayé de forcer les étiquettes à hériter de l'arrière-plan, comme suit:

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

Mais cela me laisse avec le même gris par défaut et aucun dégradé derrière les composants au-dessus du Composite.

Avez-vous des suggestions pour que le dégradé soit l'arrière-plan de chaque élément?

Je ne serais pas opposé à dessiner le dégradé sur un gc avec une image fournie, puis à définir l’arrière-plan de cette image. Cependant, cette méthode ne fonctionne tout simplement pas, composite ou aucun de ses éléments.

De plus, il m'est impossible de définir le gradient individuellement à ma connaissance. Nous voulons que l'ensemble du composite soit un gradient uniforme.

[modifier] J'ai téléchargé un exemple jusqu'à twitpic ici .

Merci,

Brian Gianforcaro

Était-ce utile?

La solution

Utilisez composite.setBackgroundMode (SWT.INHERIT_DEFAULT) , mais ne peignez pas le composite directement - peignez une image et définissez-la comme image d'arrière-plan à l'aide de composite.setBackgroundImage (Image) . À moins que je ne manque une astuce, cela signifie que vous ne devez régénérer l'image que lorsque le composite est redimensionné.

Vous devriez pouvoir couper et coller ce code tel quel pour voir ce que je veux dire:

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

}

Autres conseils

La première chose que je voudrais essayer est de capturez une image à partir du widget et peignez la partie de l'image où le widget enfant est situé directement sur le widget enfant.

Si cela ne fonctionne pas, essayez d'utiliser le même écouteur de peinture pour les deux widgets, mais avant de définir la transformation du GC sur après avoir transformé le GC afin de traduire les coordonnées dans l'espace de coordonnées du libellé:

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

Veillez également à supprimer toutes les instances Color créées après les avoir terminées. Sinon, vous perdrez des ressources système et vous finirez par manquer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top